OS-HW2.pdf

‫ﺳﯿﺴﺘﻢﻫﺎی ﻋﺎﻣﻞ‬
‫ﻧﯿﻢﺳﺎل دوم ‪٩٣-٩٢‬‬
‫ﻣﺪرس‪ :‬ﺣﻤﯿﺪ ﺑﯿ‬
‫داﻧﺸ ﺪهی ﻣﻬﻨﺪﺳ ﮐﺎﻣﭙﯿﻮﺗﺮ‬
‫ﺗﻤﺮﯾﻦ دوم‬
‫ﻣﻬﻠﺖ ارﺳﺎل‪ ٣١ :‬اردﯾﺒﻬﺸﺖ‬
‫ﺑﺨﺶ ‪ :١‬ﻣﺤﺎﻓﻈﺖ از ﺣﺎﻓﻈﻪ )‪ ١٠٠‬ﻧﻤﺮه(‬
‫در اﯾﻦ ﺗﻤﺮﯾﻦ ﻗﺼﺪ دارﯾﻢ ﺑﺎ ﻣ ﺎﻧﯿﺰم ﻣﺤﺎﻓﻈﺖ از ﺣﺎﻓﻈﻪ در ﺳﯿﺴﺘﻢﻋﺎﻣﻞ ﻟﯿﻨﻮﮐﺲ آﺷﻨﺎ ﺷﻮﯾﻢ‪ .‬ﺷﻤﺎ ﺑﺎﯾﺪ ﯾ ﮐﺘﺎﺑﺨﺎﻧﻪ‬
‫ﻃﺮاﺣ ﮐﻨﯿﺪ ﮐﻪ درﺧﻮاﺳﺖﻫﺎی ﻫﺮ ﺑﺮﻧﺎﻣﻪ ﺑﺮای دﺳﺘﺮﺳ ﺑﻪ ﺣﺎﻓﻈﻪ را ﺑﺮرﺳ ﮐﻨﺪ و در ﺻﻮرت ﻣﺸﺎﻫﺪه درﺧﻮاﺳﺖ‬
‫ﻧﺎﻣﻌﺘﺒﺮ از اﻧﺠﺎم آن ﺟﻠﻮﮔﯿﺮی ﮐﻨﺪ‪.‬‬
‫ﺑﺮای ﻧﻤﻮﻧﻪ ﺑﺮﻧﺎﻣﻪی زﯾﺮ را در ﻧﻈﺮ ﺑ ﯿﺮﯾﺪ‪:‬‬
‫)][‪int main(int argc, char const *argv‬‬
‫{‬
‫;)‪char *pointless=(char*)(0xfade‬‬
‫;)‪memcpy(pointless,pointless-0x10,1‬‬
‫;‪return 0‬‬
‫}‬
‫ﮐﺘﺎﺑﺨﺎﻧﻪی ﺷﻤﺎ ﺑﺎﯾﺪ ﻫﻨﮕﺎم اﻧﺠﺎم اﯾﻦ ﺑﺮﻧﺎﻣﻪ‪ ،‬ﻣﻌﺘﺒﺮ ﺑﻮدن آدرسﻫﺎی ﺣﺎﻓﻈﻪ را ﺑﺮای ﺧﻮاﻧﺪن و ﻧﻮﺷﺘﻦ ﺑﺮرﺳ ﮐﻨﺪ و‬
‫در ﺻﻮرت ﻣﻌﺘﺒﺮ ﻧﺒﻮدن ﻫﺮ ﮐﺪام ﭘﯿﻐﺎﻣ ﻣﺸﺎﺑﻪ زﯾﺮ ﻧﺸﺎن دﻫﺪ و از اﻧﺠﺎم آن ﻋﻤﻞ ﺟﻠﻮﮔﯿﺮی ﮐﻨﺪ‪:‬‬
‫‪[memcpy] address 0xface is not readable.‬‬
‫‪١.١‬‬
‫اﻃﻼﻋﺎت دﺳﺘﺮﺳ ﺑﻪ ﺣﺎﻓﻈﻪ‬
‫ﺳﯿﺴﺘﻢﻋﺎﻣﻞ ﻫﻨﮕﺎم اﺟﺮای ﻫﺮ ﺑﺮﻧﺎﻣﻪ‪ ،‬آدرسﻫﺎی ﻗﺎﺑﻞ دﺳﺘﺮس ﻫﺮ ﭘﺮدازه را ﻣﺸﺨﺺ ﻣ ﮐﻨﺪ‪ .‬ﺷﻤﺎ ﺑﺎﯾﺪ اﯾﻦ اﻃﻼﻋﺎت‬
‫را اﺳﺘﺨﺮاج ﮐﻨﯿﺪ و ﺑﺮ اﺳﺎس آنﻫﺎ دﺳﺘﺮﺳ ﻫﺎی ﻏﯿﺮﻣﺠﺎز را ﺗﺸﺨﯿﺺ دﻫﯿﺪ‪ .‬ﺑﺮای دﺳﺘﺮﺳ ﺑﻪ اﯾﻦ اﻃﻼﻋﺎت‪ ،‬ﺑﺎﯾﺪ‬
‫ﻓﺎﯾﻞ ‪ /proc/self/maps‬را از داﺧﻞ ﺑﺮﻧﺎﻣﻪ ﺑﺨﻮاﻧﯿﺪ و دﺳﺘﺮﺳ ﻫﺎی ﻣﻮﺟﻮد را اﺳﺘﺨﺮاج ﮐﻨﯿﺪ‪ .‬در زﯾﺮ ﺑﺨﺸ از‬
‫ﻣﺤﺘﻮای اﯾﻦ ﻓﺎﯾﻞ را ﻣ ﺗﻮاﻧﯿﺪ ﺑﺒﯿﻨﯿﺪ‪:‬‬
‫‪/bin/cat‬‬
‫‪/bin/cat‬‬
‫‪/bin/cat‬‬
‫]‪[heap‬‬
‫]‪[stack‬‬
‫‪00400000-0040b000 r-xp 00000000 fc:00 420281‬‬
‫‪0060a000-0060b000 r--p 0000a000 fc:00 420281‬‬
‫‪0060b000-0060c000 rw-p 0000b000 fc:00 420281‬‬
‫‪008f5000-00916000 rw-p 00000000 00:00 0‬‬
‫‪7fffb879e000-7fffb87bf000 rw-p 00000000 00:00 0‬‬
‫ﺑﺮای ﻣﻄﺎﻟﻌﻪی ﺟﺰﯾﯿﺎت ﺳﺘﻮنﻫﺎی اﯾﻦ ﻓﺎﯾﻞ ﻣ ﺗﻮاﻧﯿﺪ ﺑﺨﺶ ‪ /proc/[pid]/maps‬را در ‪ proc(5)١‬ﺑﺒﯿﻨﯿﺪ‪.‬‬
‫‪man 5 proc١‬‬
‫‪١‬‬
‫‪٢.١‬‬
‫ﻃﺮاﺣ‬
‫ﺗﻠﻪ ‪٢‬‬
‫ﺑﺮای ﮐﻨﺘﺮل دﺳﺘﺮﺳ ﻫﺎی ﮔﻔﺘﻪ ﺷﺪه‪ ،‬ﺷﻤﺎ ﺑﺎﯾﺪ در ﮐﺘﺎﺑﺨﺎﻧﻪی ﺧﻮد ﭼﻨﺪ ﺗﺎﺑﻊ را ﺑﻪ دام ﺑﯿﺎﻧﺪازﯾﺪ‪ .‬اﯾﻦ ﺗﻮاﺑﻊ در ﻟﯿﺴﺖ‬
‫زﯾﺮ آﻣﺪهاﻧﺪ‪:‬‬
‫ﺗﺎﺑﻊ‬
‫ﻋﻤﻠﯿﺎت‬
‫‪malloc‬‬
‫اﺧﺘﺼﺎص ﺣﺎﻓﻈﻪ‬
‫‪free‬‬
‫رﻫﺎ ﮐﺮدن ﺣﺎﻓﻈﻪ‬
‫‪ memcpy‬ﮐﭙﯽ ﮐﺮدن ﺣﺎﻓﻈﻪ‬
‫ﺑﺮای ﺑﻪ دام اﻧﺪاﺧﺘﻦ اﯾﻦ ﺗﻮاﺑﻊ‪ ،‬در ﻫﻨﮕﺎم اﺟﺮای ﺑﺮﻧﺎﻣﻪ‪ ،‬ﺑﺎﯾﺪ از ﻣ ﺎﻧﯿﺰم ‪ LD_PRELOAD‬اﺳﺘﻔﺎده ﮐﻨﯿﺪ‪.‬‬
‫‪٣.١‬‬
‫ﮐﻨﺘﺮل دﺳﺘﺮﺳ ﻫﺎ‬
‫ﭘﺲ از ﺑﻪ دام اﻧﺪاﺧﺘﻦ ﺗﻮاﺑﻊ ﮔﻔﺘﻪ ﺷﺪه‪ ،‬ﺑﺎﯾﺪ در ﻫﺮ ﮐﺪام از ﺗﻮاﺑﻊ ﺟﺪﯾﺪ‪ ،‬ﻣﻌﺘﺒﺮ ﺑﻮدن دﺳﺘﺮﺳ ﺑﻪ ﺣﺎﻓﻈﻪ را ﺑﺮرﺳ‬
‫ﮐﻨﯿﺪ‪ .‬ﻋﻤﻠﯿﺎت ﺟﺪﯾﺪ ﻫﺮ ﺗﺎﺑﻊ در زﯾﺮ آﻣﺪه اﺳﺖ‪:‬‬
‫ﻋﻤﻠﯿﺎت‬
‫ﺗﺎﺑﻊ‬
‫‪ malloc‬اﺧﺘﺼﺎص ﺣﺎﻓﻈﻪ و ﺛﺒﺖ ﻣﺤﺪوده اﺧﺘﺼﺎص ﯾﺎﻓﺘﻪ ﺣﺎﻓﻈﻪ‬
‫‪free‬‬
‫رﻫﺎ ﮐﺮدن ﺣﺎﻓﻈﻪ در ﺻﻮرﺗ ﮐﻪ ﻣﻌﺘﺒﺮ ﺑﺎﺷﺪ و ﻗﺒﻼ اﺧﺘﺼﺎص ﯾﺎﻓﺘﻪ ﺑﻮد‬
‫‪ memcpy‬ﮐﭙﯽ ﮐﺮدن ﺣﺎﻓﻈﻪ در ﺻﻮرﺗ ﮐﻪ اﻣ ﺎن ﺧﻮاﻧﺪن آدرس ﻣﺒﺪأ و ﻧﻮﺷﺘﻦ در آدرس ﻣﻘﺼﺪ وﺟﻮد داﺷﺖ‬
‫‪ ۴.١‬ﻧﺤﻮهی اﺟﺮا‬
‫ﺑﻌﺪ از ﻧﻮﺷﺘﻦ ﮐﺘﺎﺑﺨﺎﻧﻪی ﮔﻔﺘﻪ ﺷﺪه‪ ،‬ﺑﺎﯾﺪ ﯾ‬
‫ﺑﻪ ﺷ ﻞ زﯾﺮ اﺟﺮا ﺷﻮد‪:‬‬
‫ﻓﺎﯾﻞ ‪ .so‬ﺑﺴﺎزﯾﺪ ﮐﻪ ﺑﺎ ﻣ ﺎﻧﯿﺰم ‪ LD_PRELOAD‬ﻫﻤﺮاه ﺑﺎ ﻫﺮ ﺑﺮﻧﺎﻣﻪای‬
‫‪LD_PRELOAD=./libhooker.so ./tester‬‬
‫‪hook٢‬‬
‫‪٢‬‬
‫‪ ۵.١‬ﻧﻤﻮﻧﻪﻫﺎی اﺟﺮا‬
‫در اﯾﻦ ﺑﺨﺶ‪ ،‬ﻧﻤﻮﻧﻪﻫﺎﯾﯽ از ﺑﺮﻧﺎﻣﻪﻫﺎی ﻣﻌﯿﻮب و ﺧﺮوﺟ ﻫﺎی ﻣﻮرد اﻧﺘﻈﺎر آﻣﺪه اﺳﺖ‪.‬‬
‫‪ ١.۵.١‬ﺣﺎﻓﻈﻪی ﻧﺎﺧﻮاﻧﺎ‬
‫در ﻣﺜﺎل زﯾﺮ‪ ،‬ﺑﺮﻧﺎﻣﻪ ﻗﺼﺪ ﺧﻮاﻧﺪن ﺑﺨﺸ از ﺣﺎﻓﻈﻪ را دارد ﮐﻪ ﻏﯿﺮ ﻗﺎﺑﻞ ﺧﻮاﻧﺪن اﺳﺖ‪.‬‬
‫)][‪int main(int argc, char const *argv‬‬
‫{‬
‫;)‪memcpy((void*)(-2),(void*)(-1),1‬‬
‫;‪return 0‬‬
‫}‬
‫در ﻧﺘﯿﺠﻪی اﺟﺮای اﯾﻦ ﺑﺮﻧﺎﻣﻪ ﺑﺎ ﮐﺘﺎﺑﺨﺎﻧﻪی ﺷﻤﺎ‪ ،‬ﺑﺎﯾﺪ ﺻﺮﻓﺎً ﺧﺮوﺟ زﯾﺮ ﭼﺎپ ﺷﻮد و ﻫﯿﭻﮔﻮﻧﻪ ﭘﯿﻐﺎﻣ ﻣﺒﻨ ﺑﺮ‬
‫‪ Segmentation Fault‬ﻧﺸﺎن داده ﻧﺸﻮد‪.‬‬
‫‪[memcpy] source address 0xffffffffffffffff is not readable.‬‬
‫‪ ٢.۵.١‬ﺣﺎﻓﻈﻪی ﻓﻘﻂ ﺧﻮاﻧﺪﻧ‬
‫ﺑﺮﻧﺎﻣﻪی زﯾﺮ ﻗﺼﺪ دارد در ﯾ‬
‫ﺣﺎﻓﻈﻪی ﻓﻘﻂ ﺧﻮاﻧﺪﻧ اﻃﻼﻋﺎﺗ را ﺑﻨﻮﯾﺴﺪ‪.‬‬
‫)][‪int main(int argc, char const *argv‬‬
‫{‬
‫;"‪char useless[]="lasagna‬‬
‫;)‪memcpy((void*)&main,&useless,2‬‬
‫;‪return 0‬‬
‫}‬
‫در اﯾﻦ ﻣﻮرد‪ ،‬ﮐﺘﺎﺑﺨﺎﻧﻪی ﺷﻤﺎ ﺑﺎﯾﺪ ﺧﺮوﺟ زﯾﺮ را ﻧﻤﺎﯾﺶ دﻫﺪ و از اﺟﺮای ﻋﻤﻠﯿﺎت ﺟﻠﻮﮔﯿﺮی ﮐﻨﺪ‪.‬‬
‫‪[memcpy] destination address 0x40080c is not writeable.‬‬
‫‪٣.۵.١‬‬
‫ﻋﻤﻠﯿﺎت ﻏﯿﺮﻣﺠﺎز ﺑﺮ روی ﺣﺎﻓﻈﻪی ‪Heap‬‬
‫ﺑﺎ ﮐﻤ دو ﺗﺎﺑﻊ ‪ malloc‬و ‪ free‬ﺑﺎﯾﺪ ﻟﯿﺴﺖ ﺗﻤﺎم ﺣﺎﻓﻈﻪﻫﺎی در دﺳﺘﺮس ‪ Heap‬را ﻧﮕﻪ دارﯾﺪ‪ .‬ﺑﺎ ﮐﻤ اﯾﻦ‬
‫اﻃﻼﻋﺎت ﮐﺘﺎﺑﺨﺎﻧﻪ ﺷﻤﺎ ﺑﺎﯾﺪ دﺳﺘﺮﺳ ﻫﺎی ﻏﯿﺮ ﻣﺠﺎز ﺑﻪ اﯾﻦ ﺣﺎﻓﻈﻪ را ﺗﺸﺨﯿﺺ دﻫﺪ‪ .‬ﺑﺮﻧﺎﻣﻪی زﯾﺮ را در ﻧﻈﺮ ﺑ ﯿﺮﯾﺪ‪:‬‬
‫)][‪int main(int argc, char const *argv‬‬
‫{‬
‫;]‪int *a=new int[4‬‬
‫;‪delete[] a‬‬
‫;)‪memcpy(a+2,a,2‬‬
‫;‪return 0‬‬
‫}‬
‫‪٣‬‬
‫ﮐﺘﺎﺑﺨﺎﻧﻪی ﺷﻤﺎ ﺑﺎﯾﺪ ﭼﻨﯿﻦ ﺧﺮوﺟ در ﻧﺘﯿﺠﻪی اﺟﺮای اﯾﻦ ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﯾﺶ دﻫﺪ‪:‬‬
‫‪[memcpy] source address 0x15dc018 is not allocated.‬‬
‫ﺑﺎﯾﺪ ﺑﺮای ﺗﻤﺎم ﺣﺎﻻت ورودی ﺗﺎﺑﻊ ‪ memcpy‬اﻋﺘﺒﺎر آدرس ورودی را ﺑﺮرﺳ ﮐﻨﯿﺪ‪ .‬ﻫﻤﭽﻨﯿﻦ‪ ،‬در ﺻﻮرﺗ ﮐﻪ ﺗﻼش‬
‫ﺑﺮای رﻫﺎ ﮐﺮدن ﯾ ﺣﺎﻓﻈﻪی اﺧﺬ ﻧﺸﺪه ﺷﻮد‪ ،‬ﮐﺘﺎﺑﺨﺎﻧﻪی ﺷﻤﺎ ﺑﺎﯾﺪ ﺑﺎ ﻧﻤﺎﯾﺶ ﭘﯿﻐﺎﻣ از اﻧﺠﺎم ﻋﻤﻞ ﺟﻠﻮﮔﯿﺮی ﮐﻨﺪ‪:‬‬
‫)][‪int main(int argc, char const *argv‬‬
‫{‬
‫;‪int *i=new int‬‬
‫;‪delete i‬‬
‫;‪delete i‬‬
‫;‪delete (int *)&main‬‬
‫;‪return 0‬‬
‫}‬
‫در ﻧﺘﯿﺠﻪی اﺟﺮای اﯾﻦ ﺑﺮﻧﺎﻣﻪ‪ ،‬ﺧﺮوﺟ ﻫﺎی زﯾﺮ ﺑﺎﯾﺪ ﻧﻤﺎﯾﺶ داده ﺷﻮﻧﺪ‪:‬‬
‫)‪invalid free(0x1e48010‬‬
‫)‪invalid free(0x4007cc‬‬
‫‪۶.١‬‬
‫ﺛﺒﺖ وﻗﺎﯾﻊ‬
‫ﻋﻼوه ﺑﺮ ﺛﺒﺖ ﻣﺸ ﻼت دﺳﺘﺮﺳ ﺑﻪ ﺣﺎﻓﻈﻪ‪ ،‬ﮐﺘﺎﺑﺨﺎﻧﻪی ﺷﻤﺎ ﺑﺎﯾﺪ وﻗﺎﯾﻊ رخ داده را ﻧﯿﺰ ﺛﺒﺖ ﮐﻨﺪ‪ .‬ﺑﺎ اﻧﺠﺎم ﻫﺮ ﮐﺪام‬
‫از ﻋﻤﻞﻫﺎی اﺧﺬ و رﻫﺎ ﺳﺎزی ﺣﺎﻓﻈﻪ‪ ،‬ﮐﺘﺎﺑﺨﺎﻧﻪی ﺷﻤﺎ ﺑﺎﯾﺪ ﻣﺸﺨﺼﺎت آدرس اﺧﺬ ﺷﺪه و ﯾﺎ رﻫﺎ ﺷﺪه را ﺛﺒﺖ ﮐﻨﺪ‪.‬‬
‫ﻫﻤﭽﻨﯿﻦ‪ ،‬ﮐﭙﯽ ﮐﺮدن ﺣﺎﻓﻈﻪ ﻫﻢ ﺑﺎﯾﺪ ﺛﺒﺖ ﺷﻮد‪ .‬ﺑﺮﻧﺎﻣﻪی ﻧﻤﻮﻧﻪی زﯾﺮ را ﺑﺒﯿﻨﯿﺪ‪:‬‬
‫)][‪int main(int argc, char const *argv‬‬
‫{‬
‫;"‪string is="twisted‬‬
‫;‪return 0‬‬
‫}‬
‫اﺟﺮای اﯾﻦ ﺑﺮﻧﺎﻣﻪی ﻧﻤﻮﻧﻪ ﺑﺎﯾﺪ ﺧﺮوﺟ ای ﻣﺸﺎﺑﻪ زﯾﺮ ﻧﺸﺎن دﻫﺪ‪:‬‬
‫]‪malloc[0x206e010-0x206e030‬‬
‫)‪[memcpy] 0x400b2b to 0x206e028 (7 bytes‬‬
‫)‪free(0x206e010‬‬
‫ﻋﻼوه ﺑﺮ ﻣﻮارد ﮔﻔﺘﻪ ﺷﺪه‪ ،‬ﮐﺘﺎﺑﺨﺎﻧﻪ ی ﺷﻤﺎ ﺑﻌﺪ از ﺑﺎرﮔﺬاری‪ ،‬ﺑﺎﯾﺪ اﻃﻼﻋﺎت دو ﺣﺎﻓﻈﻪی ‪ heap‬و ‪ stack‬را ﻧﻤﺎﯾﺶ‬
‫دﻫﺪ‪.‬‬
‫‪٧.١‬‬
‫ﯾ‬
‫ﻧﻤﻮﻧﻪی ﮐﺎﻣﻞ‬
‫ﻣﻮارد ﮔﻔﺘﻪ ﺷﺪه را ﯾ ﺠﺎ در ﺑﺮﻧﺎﻣﻪی زﯾﺮ ﻣ ﺗﻮاﻧﯿﺪ ﺑﺒﯿﻨﯿﺪ‪.‬‬
‫‪۴‬‬
int main(int argc, char const *argv[])
{
string description="unlearning c++";
{
/* this will destruct */
string is="temporary";
}
/* test memory access */
long where=0xface;
int *beginning=(int *)0x0;
memcpy(beginning, (void *)where, 8);
memcpy(beginning, &where, 8);
/* test heap access */
char *info=new char[10];
delete[] info;
memcpy(&where,info,2);
delete[] info;
info=new char[15];
memcpy(&where,info,8);
/* test uninitialized access */
char *mind;
memcpy(mind,&info,13);
mind = new char[100];
description.copy(mind,10);
mind[10]='\0';
cout << mind << endl;
delete[] mind;
return 0;
}
:‫ﺧﺮوﺟ اﯾﻦ ﺑﺮﻧﺎﻣﻪ ﻣﺸﺎﺑﻪ ﺑﺎ ﺧﺮوﺟ زﯾﺮ ﺧﻮاﻫﺪ ﺑﻮد‬
02601000-02622000 rw-p 00000000 00:00 0
[heap]
7fff60181000-7fff601a2000 rw-p 00000000 00:00 0
[stack]
malloc[0x2601010-0x2601037]
[memcpy] 0x400f9b to 0x2601028 (14 bytes)
malloc[0x2601040-0x2601062]
[memcpy] 0x400faa to 0x2601058 (9 bytes)
free(0x2601040)
[memcpy] source address 0xface is not readable.
[memcpy] destination address (nil) is not writeable.
malloc[0x2601070-0x260107a]
free(0x2601070)
[memcpy] source address 0x7fff601a0e48 is not allocated.
invalid free(0x2601070)
malloc[0x2601070-0x260107f]
[memcpy] destination address 0x400b60 is not writeable.
malloc[0x2601090-0x26010f4]
[memcpy] 0x2601028 to 0x2601090 (10 bytes)
unlearning
free(0x2601090)
free(0x2601010)
۵
‫‪ ٨.١‬ﺗﺤﻮﯾﻞدادﻧ‬
‫ﻫﺎ ‪٣‬‬
‫ﺷﻤﺎ ﺑﺎﯾﺪ ﮐﺘﺎﺑﺨﺎﻧﻪی ﮔﻔﺘﻪ ﺷﺪه را ﺑﻪ ﻫﻤﺮاه ﭼﻨﺪ ﺑﺮﻧﺎﻣﻪ ﺑﺮای ﺗﺴﺖ ﺣﺎﻟﺖﻫﺎی ﻣﺨﺘﻠﻒ ﻧﻮﺷﺘﻪ ﺑﺎﺷﯿﺪ‪ .‬ﺑﺮای ﮐﺎﻣﭙﺎﯾﻞ‬
‫ﮐﺘﺎﺑﺨﺎﻧﻪ و ﺑﺮﻧﺎﻣﻪﻫﺎ ﺑﺎﯾﺪ ﯾ ‪ Makefile‬ﺑﻨﻮﯾﺴﯿﺪ ﮐﻪ اﻣ ﺎن ﮐﺎﻣﭙﺎﯾﻞ ﺑﺮﻧﺎﻣﻪﻫﺎ را ﺑﻪ ﻃﻮر ﺟﺪا داﺷﺘﻪ ﺑﺎﺷﺪ‪ .‬ﺑﺮای ﻣﺜﺎل‬
‫ﺑﺮای ﮐﺎﻣﭙﺎﯾﻞ ﮐﺘﺎﺑﺨﺎﻧﻪ‪ ،‬ﺑﺎﯾﺪ زدن ﭼﻨﯿﻦ دﺳﺘﻮری ﮐﺎﻓ ﺑﺎﺷﺪ‪:‬‬
‫‪make libhooker‬‬
‫ﻫﻤﭽﻨﯿﻦ ﺑﺎﯾﺪ اﻣ ﺎن ﮐﺎﻣﭙﺎﯾﻞ ﻫﻤﻪی ﺑﺮﻧﺎﻣﻪﻫﺎ و ﮐﺘﺎﺑﺨﺎﻧﻪ ﺑﺎ آرﮔﻮﻣﺎن ‪ all‬وﺟﻮد داﺷﺘﻪ ﺑﺎﺷﺪ‪:‬‬
‫‪make all‬‬
‫اﮔﺮﭼﻪ ﺑﺎﯾﺪ ﺑﻪ ﻧﺤﻮهی ﮐﺎﻣﭙﺎﯾﻞ ﺑﺪون اﺳﺘﻔﺎده از ‪ Makefile‬ﻫﻢ ﻣﺴﻠﻂ ﺑﺎﺷﯿﺪ‪.‬‬
‫در ﻣﻮرد ﺑﺮﻧﺎﻣﻪﻫﺎی ﺗﺴﺖ‪ ،‬ﺷﻤﺎ ﺣﺪاﻗﻞ ﺑﺎﯾﺪ ‪ ٣‬ﺑﺮﻧﺎﻣﻪ ﺑﻨﻮﯾﺴﯿﺪ‪ :‬ﯾ ﺑﺮای ﺗﺴﺖ دﺳﺘﺮﺳ ﻫﺎی ﻏﯿﺮﻣﺠﺎز ﺑﻪ ﺣﺎﻓﻈﻪ‪،‬‬
‫ﯾ ﺑﺮای ﺗﺴﺖ دﺳﺘﺮﺳ ﻫﺎی ﻏﯿﺮﻣﺠﺎز ﺑﻪ ‪ heap‬و ﯾ ﻫﻢ دﺳﺘﺮﺳ ﺑﻪ آدرسﻫﺎی ﻣﻘﺪاردﻫ ﻧﺸﺪه‪ .‬در ﻧﻬﺎﯾﺖ ﺷﻤﺎ‬
‫ﺑﺎﯾﺪ ﯾ ﻓﺎﯾﻞ ﺑﺎ ﭘﺴﻮﻧﺪ ‪ zip‬ﺑﺮای اﯾﻦ ﺗﻤﺮﯾﻦ آﻣﺎده ﮐﻨﯿﺪ ﮐﻪ ﭼﻨﯿﻦ ﻣﺤﺘﻮاﯾﯽ داﺷﺘﻪ ﺑﺎﺷﺪ‪:‬‬
‫‪.‬‬
‫‪90123210.zip‬‬
‫‪libhooker.c‬‬
‫‪code1.cpp‬‬
‫‪code2.cpp‬‬
‫‪code3.cpp‬‬
‫‪Makefile‬‬
‫ﺗﻮﺟﻪ داﺷﺘﻪ ﺑﺎﺷﯿﺪ‪ ،‬ﮐﻪ ﺑﺮای ﻫﻤﻪی ﺑﺮﻧﺎﻣﻪﻫﺎ و ﻫﻤﭽﻨﯿﻦ ﮐﺪ ﮐﺘﺎﺑﺨﺎﻧﻪ‪ ،‬ﻣﺠﺎز ﺑﻪ اﺳﺘﻔﺎده از ﻫﺮ دو زﺑﺎن ‪ C‬و‬
‫ﻫﺴﺘﯿﺪ‪ .‬ﮔﺮﭼﻪ ﺑﺮای ﻧﻮﺷﺘﻦ ﮐﺘﺎﺑﺨﺎﻧﻪ‪ ،‬اﺳﺘﻔﺎده از زﺑﺎن ‪ C‬ﺗﻮﺻﯿﻪ ﻣ ﺷﻮد‪.‬‬
‫‪٩.١‬‬
‫‪C++‬‬
‫راﻫﻨﻤﺎی اﺷ ﺎل زداﯾﯽ‬
‫در ﻃﻮل ﻧﻮﺷﺘﻦ ﮐﺘﺎﺑﺨﺎﻧﻪ‪ ،‬ﻣﻤ ﻦ اﺳﺖ ﺑﺎ ﻣﺸ ﻼﺗ ﻣﻮاﺟﻪ ﺷﻮﯾﺪ‪ .‬ﺑﺮای رﻓﻊ آنﻫﺎ ﻣﻮارد زﯾﺮ را در ﻧﻈﺮ داﺷﺘﻪ ﺑﺎﺷﯿﺪ‪:‬‬
‫• از ﺗﺴﺖ ﮐﺘﺎﺑﺨﺎﻧﻪ ﺑﺎ ﻣﺜﺎلﻫﺎی ﺑﺪﯾﻬ ﺑﭙﺮﻫﯿﺰﯾﺪ‪ .‬در اﮐﺜﺮ ﻣﻮارد ﮐﺎﻣﭙﺎﯾﻠﺮ ﺗﻮاﺑﻊ را ‪ inline‬ﻣ ﮐﻨﺪ و دﯾ ﺮ‬
‫دامﻫﺎی ﺷﻤﺎ ﺻﺪا زده ﻧﻤ ﺷﻮﻧﺪ‪ .‬ﻫﻤﭽﻨﯿﻦ ﻫﻨﮕﺎم ﮐﺎﻣﭙﺎﯾﻞ ﺑﺎ ﮐﻤ آرﮔﻮﻣﺎن ‪ -O0‬ﺗﺎ ﺣﺪ ﻣﻤ ﻦ از ﺑﻬﯿﻨﻪﺳﺎزی‬
‫ﮐﺪ ﺟﻠﻮﮔﯿﺮی ﮐﻨﯿﺪ‪.‬‬
‫• ﺗﻤﺎﻣ ﻋﻤﻠﯿﺎﺗ ﮐﻪ در داﺧﻞ دام ﺗﺎﺑﻊ ‪ malloc‬اﻧﺠﺎم ﻣ دﻫﯿﺪ‪ ،‬ﻧﺒﺎﯾﺪ از ﺣﺎﻓﻈﻪی ‪ heap‬اﺳﺘﻔﺎده ﮐﻨﻨﺪ‪ .‬در ﻏﯿﺮ‬
‫اﯾﻨﺼﻮرت‪ ،‬ﺑﻪ ﻃﻮر ﺑﺎزﮔﺸﺘ ﺑﺎ اﺧﺬ ﻫﺮ ﺣﺎﻓﻈﻪ‪ ،‬ﺑﺎﯾﺪ ﺣﺎﻓﻈﻪی ﺟﺪﯾﺪی اﺧﺬ ﺷﻮد‪.‬‬
‫• در ﺻﻮرﺗ ﮐﻪ ﺑﺮای ﻧﻮﺷﺘﻦ ﮐﺘﺎﺑﺨﺎﻧﻪ از زﺑﺎن ‪ C++‬اﺳﺘﻔﺎده ﻣ ﮐﻨﯿﺪ‪ ،‬ﻣﺘﻮﺟﻪ اﺳﺘﻔﺎدهی ﺗﻮﮐﺎر آﺑﺠ ﺖﻫﺎ از‬
‫ﺣﺎﻓﻈﻪی ‪ heap‬ﺑﺎﺷﯿﺪ‪ .‬ﻫﻤﭽﻨﯿﻦ‪ ،‬در ﺑﺮﺧ ﻣﻮارد اﺳﺘﻔﺎده از ﺑﺮﺧ از آﺑﺠ ﺖﻫﺎی ‪ C++‬ﻣﻤ ﻦ اﺳﺖ ﻣﻨﺠﺮ‬
‫ﺑﻪ دﺳﺘﺮﺳ ﻏﯿﺮﻣﺠﺎز ﺑﻪ ﺣﺎﻓﻈﻪ ﺷﻮد‪.‬‬
‫‪deliverables٣‬‬
‫‪۶‬‬
‫ﺑﺨﺶ ‪ :٢‬ﺗﮑﻤﯿﻠ )‪ ۵٠+۵‬ﻧﻤﺮهی اﻣﺘﯿﺎزی(‬
‫در اﯾﻦ ﺑﺨﺶ‪ ،‬ﭼﻨﺪ ﺳﺆال اﻣﺘﯿﺎزی آورده ﺷﺪه اﺳﺖ‪ .‬اﻧﺠﺎم اﯾﻦ ﺳﺆاﻻت ﻗﺒﻞ از ﻧﻮﺷﺘﻦ ﺗﻤﺮﯾﻦ اﺻﻠ ‪ ،‬ﺑﻪ ﺗﺴﺮﯾﻊ‬
‫ﭘﯿﺎدهﺳﺎزی ﮐﻤ ﺧﻮاﻫﺪ ﮐﺮد‪.‬‬
‫‪١.٢‬‬
‫ﻣ ﺎﻧﯿﺰم اﺧﺘﺼﺎص ﺣﺎﻓﻈﻪ )‪ ١٠‬ﻧﻤﺮه(‬
‫ﺗﺤﻘﯿﻖ ﮐﻨﯿﺪ ﮐﻪ دو ﺗﺎﺑﻊ ‪ malloc‬و ‪ free‬ﭼﻪ ﻋﻤﻠﯿﺎﺗ را ﺑﺮای اﺧﺬ و رﻫﺎ ﺳﺎزی ﺣﺎﻓﻈﻪی ‪ heap‬اﻧﺠﺎم ﻣ دﻫﻨﺪ‪.‬‬
‫ﺗﻮﺿﯿﺢ ﺧﻮد را در ﻗﺎﻟﺐ ﯾ ﻓﺎﯾﻞ ‪ pdf‬در داﺧﻞ ﻓﺎﯾﻞ ‪ zip‬ﮔﻔﺘﻪ ﺷﺪه ﻗﺮار دﻫﯿﺪ‪ .‬ﺗﻮﺟﻪ داﺷﺘﻪ ﺑﺎﺷﯿﺪ ﺑﻪ ﺗﻌﺪاد ﺧﻂ‬
‫ﺗﻮﺿﯿﺢ ﻧﻤﺮهای ﺗﻌﻠﻖ ﻧﻤ ﮔﯿﺮد‪ .‬ﺑﺎﯾﺪ ﻧﮑﺎت ﮐﻠﯿﺪی ﻧﺤﻮهی رﻓﺘﺎر اﯾﻦ دو ﺗﺎﺑﻊ ﺑﻪ ﻃﻮر ﻣﺸﺨﺺ ﻗﯿﺪ ﺷﺪه ﺑﺎﺷﺪ‪.‬‬
‫‪ ٢.٢‬ﺗﮑﻨﯿ‬
‫‪mangling‬‬
‫‪ ١٠) name‬ﻧﻤﺮه(‬
‫در زﺑﺎن ‪ C++‬ﺗﮑﻨﯿ ‪ name mangling‬ﭼﻪ زﻣﺎﻧ رخ ﻣ دﻫﺪ؟ ﭼﻪ راﻫ ﺎری ﺑﺮای ﺟﻠﻮﮔﯿﺮی از آن وﺟﻮد دارد؟‬
‫در ﭼﻪ ﻣﻮﻗﻌﯿﺖﻫﺎﯾﯽ ﻣﻤ ﻦ اﺳﺖ ﻣﻨﺠﺮ ﺑﻪ ﻣﺸ ﻞ ﺷﻮد؟ ﻋﻼوه ﺑﺮ ﺗﻮﺿﯿﺢ اﯾﻦ ﺳﺆاﻻت‪ ،‬ﺑﺎﯾﺪ ﮐﺪی ﺑﺮای ﻧﻤﺎﯾﺶ رخ‬
‫دادن اﯾﻦ ﺗﮑﻨﯿ و ﭼ ﻮﻧﮕ اﯾﺠﺎد ﻣﺸ ﻞ ﻫﻢ ﺑﻨﻮﯾﺴﯿﺪ‪ .‬ﺗﻤﺎم ﻓﺎﯾﻞﻫﺎی ﻣﺮﺑﻮط ﺑﻪ اﯾﻦ ﺳﺆال را داﺧﻞ ﯾ ﭘﻮﺷﻪ ﺑﺎ ﻧﺎم‬
‫‪ name-mangling‬داﺧﻞ ﻓﺎﯾﻞ ‪ zip‬ﮔﻔﺘﻪ ﺷﺪه ﻗﺮار دﻫﯿﺪ‪.‬‬
‫‪٣.٢‬‬
‫ﺗﺨﺼﯿﺺ دﻫﻨﺪهی ‪ ١۵) stack‬ﻧﻤﺮه(‬
‫ﯾ ﺗﺨﺼﯿﺺ دﻫﻨﺪه ﺑﺮای ﮐﻼسﻫﺎی ‪ STL‬ﻃﺮاﺣ ﮐﻨﯿﺪ ﮐﻪ ﺑﻪ ﺟﺎی ﺣﺎﻓﻈﻪی ‪ heap‬از ﺣﺎﻓﻈﻪی ‪ stack‬اﺳﺘﻔﺎده‬
‫ﮐﻨﺪ‪ .‬ﻓﺎﯾﻞﻫﺎی ﻣﺮﺑﻮط ﺑﻪ اﯾﻦ ﺳﺆال را داﺧﻞ ﯾ ﭘﻮﺷﻪ ﺑﻪ ﻧﺎم ‪ stack-allocator‬در داﺧﻞ ﻓﺎﯾﻞ ‪ zip‬ﮔﻔﺘﻪ ﺷﺪه‬
‫ﻗﺮار دﻫﯿﺪ‪ .‬ﭘﺲ از ﭘﯿﺎدهﺳﺎزی اﯾﻦ ﺗﺨﺼﯿﺺ دﻫﻨﺪه‪ ،‬ﺑﻪ ﺷ ﻞ زﯾﺮ ﺑﺎﯾﺪ ﺑﺘﻮان از آن اﺳﺘﻔﺎده ﮐﺮد‪:‬‬
‫;‪std::vector<int,stack_allocator<int> > v‬‬
‫‪ ۴.٢‬اﺷﺎرهﮔﺮ ﻫﻮﺷﻤﻨﺪ )‪ ١۵+۵‬ﻧﻤﺮه(‬
‫ﯾ ﮐﻼس ﺑﺮای ﻣﺪﯾﺮﯾﺖ اﺷﺎرهﮔﺮﻫﺎی ﻣﻮﺟﻮد ﺑﻪ ﯾ ﺷ ء ﺑﻨﻮﯾﺴﯿﺪ‪ .‬اﯾﻦ ﮐﻼس ﺑﺎﯾﺪ ﺑﺎ ﮔﺮﻓﺘﻦ ﯾ اﺷﺎرهﮔﺮ‪ ،‬ﺑﺎ ﻫﺮ‬
‫ﺑﺎر ﮐﭙﯽ ﺷﺪن‪ ،‬ﯾ ﻟﯿﺴﺖ از ﺗﻤﺎم اﺷﺎرهﮔﺮﻫﺎی ﻣﻮﺟﻮد را ﻧﮕﻪداری ﮐﻨﺪ‪ .‬ﺑﺎ ﭘﺎک ﺷﺪن آﺧﺮﯾﻦ ﺷ ء اﯾﻦ ﮐﻼس‪ ،‬ﺑﺎﯾﺪ‬
‫اﺷﺎرهﮔﺮ اﺻﻠ ﻫﻢ ﭘﺎک ﺷﻮد‪ .‬در ﺻﻮرﺗ ﮐﻪ اﯾﻦ ﮐﻼس را ‪ thread-safe‬ﻃﺮاﺣ ﮐﻨﯿﺪ‪ ۵ ،‬ﻧﻤﺮهی اﺿﺎﻓﻪ ﺧﻮاﻫﯿﺪ‬
‫ﮔﺮﻓﺖ‪ .‬ﺑﺮای اﯾﻦ ﮐﻼس ﺗﻤﺎم ﻋﻤﻠ ﺮﻫﺎی ﻻزم را ﺑﺮای ﺷﺒﺎﻫﺖ رﻓﺘﺎری ﺑﺎ ﯾ اﺷﺎرهﮔﺮ ‪ overload‬ﮐﻨﯿﺪ‪ .‬ﻧﻤﻮﻧﻪای‬
‫از ﻧﺤﻮهی اﺳﺘﻔﺎده از اﯾﻦ اﺷﺎرهﮔﺮ را در زﯾﺮ ﻣ ﺗﻮاﻧﯿﺪ ﺑﺒﯿﻨﯿﺪ‪:‬‬
‫)][‪const *argv‬‬
‫;))‪p = smart_ptr<MyObject>(new MyObject(10‬‬
‫;‪p2 = smart_ptr<MyObject> p‬‬
‫;‪endl‬‬
‫‪int main(int argc, char‬‬
‫{‬
‫>‪smart_ptr<MyObject‬‬
‫>‪smart_ptr<MyObject‬‬
‫<< ‪cout << p2->prop‬‬
‫;‪return 0‬‬
‫}‬
‫ﺑﺎ ﮐﻤ اﯾﻦ اﺷﺎرهﮔﺮ ﻫﻮﺷﻤﻨﺪ‪ ،‬اﯾﻦ ﺑﺮﻧﺎﻣﻪ ﺑﺪون ‪ leak‬و اﯾﺠﺎد اﺷﺎرهﮔﺮ ‪ dangling‬ﺗﻤﺎم ﺧﻮاﻫﺪ ﺷﺪ‪ .‬ﻓﺎﯾﻞﻫﺎی‬
‫ﻣﺮﺑﻮط ﺑﻪ اﯾﻦ ﺳﺆال را داﺧﻞ ﯾ ﭘﻮﺷﻪ ﺑﻪ ﻧﺎم ‪ smart-ptr‬در داﺧﻞ ﻓﺎﯾﻞ ‪ zip‬ﮔﻔﺘﻪ ﺷﺪه ﻗﺮار دﻫﯿﺪ‪.‬‬
‫‪٧‬‬
‫ﻧﮑﺎت ﻧﻬﺎﯾﯽ‬
‫• اﯾﻦ ﺗﻤﺮﯾﻦ را ﺑﺎﯾﺪ ﺑﺎ زﺑﺎن ‪ C‬ﯾﺎ ‪ C++‬اﻧﺠﺎم دﻫﯿﺪ و در ﺻﻮرت ﻧﯿﺎز از اﻓﺰوﻧﻪﻫﺎی ‪ GNU‬ﻫﻢ ﻣ ﺗﻮاﻧﯿﺪ اﺳﺘﻔﺎده‬
‫ﮐﻨﯿﺪ‪.‬‬
‫• ﺑﺎ ﺗﻮﺟﻪ ﺑﻪ ﻧﯿﺎز ﺑﻪ اﺳﺘﻔﺎده از ﺷﺒﻪ ﻓﺎﯾﻞﺳﯿﺴﺘﻢ ‪ proc‬اﯾﻦ ﺗﻤﺮﯾﻦ را ﺗﻨﻬﺎ ﺑﺮ روی ﺳﯿﺴﺘﻢﻋﺎﻣﻞ ﻟﯿﻨﻮﮐﺲ ﻣ ﺗﻮاﻧﯿﺪ‬
‫اﻧﺠﺎم دﻫﯿﺪ و در ﻫﻨﮕﺎم ﺗﺤﻮﯾﻞ ﺣﻀﻮری ﻫﻢ ﺑﺎﯾﺪ اﯾﻦ ﺳﯿﺴﺘﻢﻋﺎﻣﻞ را آﻣﺎده ﺑﺮای اﺟﺮای ﮐﺪ ﺧﻮد داﺷﺘﻪ ﺑﺎﺷﯿﺪ‪.‬‬
‫• از ﺑﻪ اﺷﺘﺮاک ﮔﺬاﺷﺘﻦ ﮐﺪ ﺧﻮد ﺑﺎ دﯾ ﺮان ﺑﭙﺮﻫﯿﺰﯾﺪ‪ .‬در ﺻﻮرت ﻣﺸﺎﻫﺪهی ﮐﺪﻫﺎی ﻣﺸﺎﺑﻪ‪ ،‬ﻧﻤﺮه ﻫﺮ دو ﻃﺮف‬
‫ﺑﺮاﺑﺮ ﺑﺎ ﻣﻨﻔ ﻧﻤﺮه ﮐﻞ ﺗﻤﺮﯾﻦ ﺧﻮاﻫﺪ ﺷﺪ‪.‬‬
‫• در اﯾﻦ ﺗﻤﺮﯾﻦ ﻋﻼوه ﺑﺮ ﺗﺸﺎﺑﻪ ﮐﺪ‪ ،‬ﺗﺸﺎﺑﻪ اﯾﺪهﻫﺎی اﺳﺘﻔﺎده ﺷﺪه و ﺗﺴﻠﻂ ﮐﺎﻣﻞ ﺑﺮ ﮐﺪ در ﻫﻨﮕﺎم ﺗﺤﻮﯾﻞ ﺣﻀﻮری‪،‬‬
‫ﻧﯿﺰ ﻣ ﺗﻮاﻧﺪ ﻣﻨﺠﺮ ﺑﻪ ﮔﺮﻓﺘﻦ ﻧﻤﺮهای ﻣﻌﺎدل ﻣﻨﻔ ﻧﻤﺮه ﮐﻞ ﺗﻤﺮﯾﻦ ﺷﻮد‪.‬‬
‫• ﺳﻮاﻻت ﺧﻮد را ﭘﯿﺮاﻣﻮن اﯾﻦ ﺗﻤﺮﯾﻦ از آﻗﺎی اﻟﻠﻬﻮردی و رﺷﯿﺪﯾﺎن ﺑﭙﺮﺳﯿﺪ‪.‬‬
‫‪٨‬‬