版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、Bomb-Lab實(shí)驗(yàn)報(bào)告捌泊大學(xué)HUNAN UNIVERSITY課程實(shí)驗(yàn)報(bào)告課程名稱:計(jì)算機(jī)系統(tǒng)原理實(shí)驗(yàn)實(shí)驗(yàn)名稱:Bomb Lab專業(yè)班級(jí):姓 名:學(xué) 號(hào):完成時(shí)間:完17.419一、實(shí)驗(yàn)?zāi)康氖煜R編程序,學(xué)習(xí)gdb調(diào)試工具,熟悉并掌握函數(shù)調(diào)用過程中的棧幀結(jié)構(gòu) 的變化。二、實(shí)驗(yàn)環(huán)境個(gè)人PC, Linux發(fā)行版本,終端,gdb調(diào)試工具。三、實(shí)驗(yàn)要求L本次實(shí)驗(yàn)為熟悉匯編程序及其調(diào)試方法的實(shí)驗(yàn)。2 .實(shí)驗(yàn)內(nèi)容包含2個(gè)文件bomb (可執(zhí)行文件)和bomb.c (c源文件)。3 .使用gdb工具反匯編出匯編代碼,結(jié)合c語言文件找到每個(gè)關(guān)卡的入口函 數(shù)。4 .分析匯編代碼,找到在每個(gè)phase程序段中,
2、引導(dǎo)程序跳轉(zhuǎn)到 wexplode_bomb"程序段的地方,并分析其成功跳轉(zhuǎn)的條件,以此為突破口尋 找應(yīng)該在命令行輸入何種字符通關(guān)。5 .本實(shí)驗(yàn)一共有7個(gè)關(guān)卡,包括6個(gè)普通關(guān)卡和1個(gè)隱藏關(guān)卡。要求至少通 過6個(gè)普通關(guān)卡。一、實(shí)驗(yàn)內(nèi)容及操作步驟(一)準(zhǔn)備過程1 .解壓文件夾得到"bomb" , "bomb.c” , aREADME-bomblab.txt,以 及“實(shí)驗(yàn)基本內(nèi)容與要求.txt”等文檔。查看“實(shí)驗(yàn)基本內(nèi)容與要求.txt” 了解實(shí) 驗(yàn)內(nèi)容與要求后打開bomb.c文件,編譯發(fā)現(xiàn)不能通過,代碼不完整,所以bomb.c 文件只能用來作為參考。查看bomb
3、.c文件發(fā)現(xiàn)控制密碼正確的6個(gè)函數(shù)分別為 phase_l,phase_2,phase_3,phase_4,phase_5,phase_6,因此可以對(duì) bomb 文件反匯 編得到匯編文本,結(jié)合匯編文本與bomb.c文本進(jìn)一步分析。2 .進(jìn)入U(xiǎn)buntu,將bom和bomb.c文檔復(fù)制到主文件目錄下,ctrl+alt+t打 開終端,通過“objdump -d bomb > bomb.s”命令將可執(zhí)行文件反匯編成bomb.s 文件,并且可以通過“gdbq bomb”進(jìn)行調(diào)試。3 .將bomb.c復(fù)制成文本后打開bomb.c查看匯編代碼并進(jìn)一步分析。(二)關(guān)卡分析1. phasephase匯編代
4、碼及注釋如下:08048f61 <phase_l>:push %ebpmov %esp, %ebpsub$0x18, %esp #開辟一個(gè) 24movl$0x804al5c, 0x4(%esp) #8048f61: 558048f62 : 89 e58048f64: 83 ec 18位的??臻g8048f67: c7 44 24 04 5c al 04將 0x804al5c 存到eap+4 的位置,x/s 0x804al5c 得到"We have to stand with our North Korean allies.8048f6e: 08mov0x8(%ebp), %
5、eaxmov%eax, (%esp) #%ebp+88048f6f: 8b 45 088048f72 : 89 04 24處的值存到%esp8048f75: e8 31 00 00 00call 8048fab<strings_not_equal>test %eax, %eaxje 8048f83 <phase_l+0x22>8048f7a: 85 cO8048f7c: 74 05#%eax=0則跳出函數(shù),否則跳到爆炸函數(shù),可以看出,調(diào)用<strings_not_equal>函數(shù)后如果兩個(gè)字符串相等的話最后%邑二會(huì)等于08048f7e: e8 4e 01 0
6、0 00call 80490dl <explode_bomb>8048f83:c9leave8048f84:c3ret8048f85:90nop8048f86:90nop8048f87:90nop8048f88:90nop8048f89:90nop8048f8a:90nop8048f8b:90nop8048f8c:90nop8048f8d:90nop8048f8e:90nop8048f8f:90nop思路與分析:通過call 8048fab <strings_not_equal>我們可以推斷要求輸入的 是一串字符串» movl$0x804al5c, 0x4 (
7、%esp)將地址 0x804al5c 存到%esp+4 的位置,mov 0x8(%ebp), %eax和mov%eax, (%esp)將輸入的字符串存到esp中,call 8048fab <strings_not_equal>調(diào)用字符串比較函數(shù),通過 比較上面位置參數(shù)%esp+4與%esp對(duì)應(yīng)的字符串是否相等,將返回值存到%6&乂中, test %eax, %eax, je 8048f83 <phase_l+0x22>, call 80490dl<explode_bomb>,判斷如果兩個(gè)字符串不相等則爆炸。由上面分析可知地址0x804al5c中存著正
8、確的字符串,我們只要輸入相同的字符串就可以通過關(guān)卡。進(jìn)入gdb,通過命令x/s 0x804al5c查看該字符串為: “We have to stand with our North Korean allies.(gdb) x/s 9x804al5c0x804al5c:HWe have to stand with our North Korean allies."所以 phase的通關(guān)密碼為:"We have to stand with our North Korean allies.”通過r命令運(yùn)行程序,輸入該字符串則通過第一關(guān):(gdb) rstarting progra
9、n: /hone/vamptre/bombWelcome to ny fiendish little bomb. You have 6 phases with which to blow yourself up. Have a nice day!We have to stand with our North Korean allies.Phase 1 defused- How about the next one?結(jié)論與心得:通過分析匯編代碼,通過字符串比較函數(shù)strings_not_equal可以推測 輸入的是一串字符串,通過x/s以字符串的形式查看地址0x804al5c所對(duì)應(yīng)的 值,運(yùn)行程
10、序后輸入該字符串即可通過關(guān)卡。字符串比較函數(shù)主要是通過將兩 個(gè)字符串進(jìn)行比較,將結(jié)果存到%eax中,最后判斷%=乂的值。第一關(guān)相對(duì)比較簡單,也比較好理解。2. phase_2Phase_2匯編代碼及注釋如下:08048d6a <phase_2>:8048d6a: 558048d6b: 89 e58048d6d: 568048d6e: 538048d6f: 83 ec 308048d72: 8d 45 eO8048d75: 89 44 24 04一個(gè)數(shù)字的地址放到%esp+4的位置8048d79: 8b 45 08push %ebpmov %esp, %ebppush %esipus
11、h %ebxsub $0x30, %esp1ea-0x20(%ebp), %eaxmov%eax, 0x4 (%esp)#將第mov0x8(%ebp), %eax8048d7c: 89 04 24mov8048d7f: e8 87 03 00 00call<read_six_numbers># 讀取六個(gè)數(shù)字8048d84:837deO00cmpl8048d88:7506jne# 0和-0x20 (%ebp)比較,不相等就爆炸 8048d8a:837de401cmpl8048d8e:7405je%eax, (%esp)804910b$0x0, -0x20(%ebp)8048d90 &
12、lt;phase_2+0x26>$0x1, -Oxlc(%ebp)8048d95 <phase_2+0x2b># 1和-Oxlc(%ebp)比較,相等就跳過爆炸8048d90: e8 3c 03 00 008048d95: 8d 5d e8call 80490dl <explode_bomb> lea -0x18 (%ebp), %ebx #將第三個(gè)數(shù)字的地址傳到%ebx中,即現(xiàn)在%ebx中存著第三個(gè)數(shù)字的地址8048d98: 8d 75 f8lea -0x8(%ebp), %esi #將%ebx的地址傳到%esi, %esi用于待會(huì)的判斷結(jié)束條件,ebx存的地址
13、一直循 環(huán)加4,循環(huán)直到%。6、的下一個(gè)地址是枇si就結(jié)束】8048d9b: 8b 43 fc二個(gè)數(shù)放到%eax寄存器中8048d9e: 03 43 f8第二個(gè)數(shù)和第一個(gè)數(shù)的和8048dal: 39 038048da3: 74 05#前兩個(gè)數(shù)的和與第三個(gè)數(shù)相比較mov-0x4 (%ebx), %eax#將第add-0x8 (%ebx), %eax#計(jì)算cmp%eax, (%ebx)je8048daa <phase_2+0x40>,相等則跳過炸彈8048da5:e82703 00 00call8048daa:83c304add址加4,現(xiàn)在%ebx中存著第四個(gè)數(shù)字的地址8048dad:
14、39f3cmp8048daf:75eajne80490dl <explode_bomb> $0x4, %ebx #將%ebx 的地%esi, %ebx8048d9b <phase_2+0x31># 比較現(xiàn)在%esi和%ebx里面的值是否相等,不相等則循環(huán),否則結(jié)束。其實(shí)兩個(gè)寄存器中存的都是地址,為的是保證只輸入6個(gè)數(shù),因?yàn)楫?dāng)輸入第7個(gè)數(shù)時(shí),%ebx=%esi8048dbl: 83 c4 308048db4: 5b8048db5: 5e8048db6: 5d8048db7: c3add $0x30, %esppop %ebxpop %esipop %ebp#釋放棧幀ret
15、思路與分析:通過call 804910b <read_six_numbers我們可以推斷出應(yīng)該是要輸入6 個(gè)數(shù)字。通過對(duì)匯編代碼進(jìn)行分析知道-0x20 (%ebp)存著第一個(gè)數(shù)字,-Oxlc (%ebp)存著第二個(gè)數(shù)字,依次類推。通過 cmpl $0x0, -0x20 (%ebp), jne 8048d90 <phase_2+0x26>和 cmpl$0x1, -0xlc(%ebp), je 8048d95<phase_2+0x2b>知道第一個(gè)數(shù)字必須是0,第二個(gè)數(shù)字必須是1,否則就爆炸。 命令lea -0x18 (%ebp), %ebx初始化寄存器%ebx的值,將
16、第三個(gè)數(shù)字的地址傳 到%66、中.lea-0x8(%ebp),%esi 將%ebx的地址傳到%esi, %esi用于待會(huì)的判斷結(jié)束條件,ebx存的地址一直循環(huán)加4,循環(huán)直到%ebx的下一個(gè)地址是%0$1 就結(jié)束,mov-0x4 (%ebx), %eax將第二個(gè)數(shù)放到%6"寄存器中,add-0x8(%ebx), %eax 計(jì)算第二個(gè)數(shù)和第一個(gè)數(shù)的和,cmp%eax, (%ebx) , je8048daa <phase_2+0x40>前兩個(gè)數(shù)的和與第三個(gè)數(shù)相比較,相等則跳過炸彈。 add$0x4, %ebx 將%ebx的地址加4,現(xiàn)在%ebx中存著第四個(gè)數(shù)字的地址,之后%6乂
17、 一直加4,知道循環(huán)完6個(gè)數(shù)字。通過上面的分析知道,輸入的前兩個(gè) 數(shù)字為。和1,后面的數(shù)字等于前面兩個(gè)數(shù)字的和。所以,這六個(gè)數(shù)字為 Fibonacci數(shù)列的前六項(xiàng)。為0 1 1 2 3 5。輸入這6個(gè)數(shù)字可通過phase_2.Phase 1 defused. How about the next one? 0 112 3 5That1s number 2. Keep going!結(jié)論與心得:第二關(guān)需要弄懂棧幀結(jié)構(gòu)的變化,通過add$0x4, %ebx將%66乂的地址加4,然后判斷前兩個(gè)數(shù)字的和與當(dāng)前位置的數(shù)是否相等。結(jié)合第一個(gè)和第二個(gè)數(shù)字是。和1知道結(jié)果為0 1 1 2 3 5。3. phas
18、e_3phased匯編代碼及注釋如下:08048eal <phase_3>:8048eal: 558048ea2: 89 e58048ea4: 83 ec 288048ea7: 8d 45 fO個(gè)數(shù)的位置8048eaa: 89 44 24 0c8048eae: 8d 45 f4個(gè)數(shù)的位置8048ebl: 89 44 24 088048eb5: c7 44 24 04 3e a2 04push%ebpmov%esp, %ebpsub$0x28, %esplea-0x10 (%ebp), %eax#第二mov%eax, Oxc(%esp)1 ea-Oxc (%ebp), %eax#第一
19、mov%eax, 0x8(%esp)movl $0x804a23e, 0x4(%esp) #通過查看0x804a23e的內(nèi)容,即x/s 0x804a23e,顯示為"%d %d”,提示輸入兩個(gè)整型數(shù)8048ebc: 088048ebd: 8b 45 088048ec0: 89 04 248048ec3: e8 78 f9 ff ffmov0x8 (%ebp), %eaxmov%eax, (%esp)call 8048840<_isoc99.sscanfplt>#isoc99標(biāo)準(zhǔn)輸入變量,應(yīng)該是把輸入的數(shù)字個(gè)數(shù)存在%eax里8048ec8: 83 f8 018048ecb:
20、7f 05#至少輸入2個(gè)數(shù),否則爆炸8048ecd: e8 ff 01 00 00cmp $0x1, %eaxjg8048ed2 <phase_3+0x31>call80490dl <explode_bomb>8048ed2:837df407cmpl$0x7, -Oxc (%ebp)8048ed6:776bja8048f43 <phase_3+0xa2>#第1個(gè)數(shù)大于7爆炸,所以,第一個(gè)數(shù)需要小于等于78048ed8:8b45f4mov-Oxc (%ebp), %eax將第一個(gè)數(shù)存到%&&*中8048edb:ff2485a0 al 04 08
21、 jmp*0x804ala0(, %eax, 4) #跳轉(zhuǎn)至0x804ala0+4*%eax (存放第一個(gè)數(shù))中的內(nèi)容所指的行數(shù) p/x*0x804ala0+4*%eax8048ee2: b88048ee7: eb8048ee9: b88048eee: 668048ef0: eb8048ef2: b85的時(shí)候跳到這里8048ef7: eb8048ef9: b84的時(shí)候跳到這里8048efe: 668048f00: eb8048f02: b84的時(shí)候跳到這里8048f07: eb8048f09: b82的時(shí)候跳到這里8048fOe: 668048fl0: eb8048fl2: b800 0000
22、00mov53jmp00 000000mov90xchg45jmp00 000000mov39jmp00 000000mov90xchg2bjmp00 000000movIfjmp00 000000mov90xchg11jmp14 030000mov$0x0, %eax8048f3c <phase_3+0x9b>$0x0, %eax%ax, %ax8048f37 <phase_3+0x96>$0x0, %eax #第一個(gè)數(shù)等于8048f32 <phase_3+0x91>$0x0, %eax #第一個(gè)數(shù)等于%ax, %ax8048f2d <phase_3
23、+0x8c>$0x0, %eax #第一個(gè)數(shù)等于8048f28 <phase_3+0x87>$0x0, %eax #第一個(gè)數(shù)等于%ax, %ax8048f23 <phase_3+0x82>$0x314, %eax#第一個(gè)數(shù)為。的時(shí)候跳到這里(p/x *0x804ala0)首先x=778,最后第二個(gè)數(shù)等于1478048fl7: eb 05jmp#跳轉(zhuǎn)到8048fle這一行8048fl9: b8 00 00 00 00mov1的時(shí)候跳到這里8048fle:2d5a030000sub8048f23 :05ef020000add8048f28:2d16020000sub8
24、048f2d:0516020000add8048f32 :2d16020000sub8048f37:0516020000add8048f3c:2d16020000sub8048f41:eb0ajmp#跳轉(zhuǎn)到8048f4d這一行8048f43:e889010000call8048f48 :b800000000mov8048f4d:837df405cmpl8048f51:7f05jg8048fle <phase_3 +0x7d>$0x0, %eax #第一個(gè)數(shù)等于$0x35% %eax$0x2ef, %eax$0x216, %eax$0x216, %eax$0x216, %eax$0x
25、216, %eax$0x216, %eax#x=x-858#x=x+751#x=x-534#x=x+534#x=x-534#x=x+534#x=x-5348048f4d <phase_3+0xac>80490dl <explode_bomb>$0x0, %eax$0x5, -Oxc(%ebp)8048f58 <phase_3+0xb7>#第一個(gè)數(shù)字需要小于等于5,否則爆炸8048f53: 3b 45 fOcmp -0x10(%ebp), %eax8048f56: 74 05j e 8048f5d <phase_3+0xbc>#0,147; 1-6
26、41; 2,217; 3, 一534; 4,0; 5, -5348048f58: e8 74 01 00 008048f5d: c98048f5e : 66 908048f60: c3call 80490dl <explode_bomb> leavexchg %ax, %axret思路與分析:觀察到指令movl$0x804a23e, 0x4(%esp),通過查看0x804a23e的內(nèi)容,即x/s 0x804a23e,顯示為"d %d”,提示輸入兩個(gè)整型數(shù)。call 8048840<_isoc99_sscanfplt>,調(diào)用isoc99標(biāo)準(zhǔn)輸入變量,是把輸入的數(shù)
27、字個(gè)數(shù)存 在皺乂 里返回。通過 cmp $0x1, %eax 和 jg 8048ed2 <phase_3+0x31>知 道至少輸入2個(gè)數(shù),否則爆炸。通過cmpl$0x7, -Oxc (%ebp)和ja 8048f43<phase_3+0xa2>知道第一個(gè)數(shù)字小于等于 7,由 cmpl $0x5,-Oxc (%ebp)和 jg 8048f58 <phase_3+0xb7>知道輸入的數(shù)字要小于等于5,所以輸入的數(shù)字范圍為 0-5o jmp*0x804ala0(, %eax, 4)為 switch 分支結(jié)構(gòu),eax 存著輸入的數(shù)字的值,當(dāng)輸入的數(shù)組是。的時(shí)候,查看
28、*0x804ala0的值,得到$1 = 0x8048f 12, 即跳轉(zhuǎn)到0x8048fl2處。當(dāng)輸入的數(shù)字為1-5時(shí)依次類推。得到的地址分別為:(gdb) p/x *0x8O4alaO $1 = 0x8048fl2(gdb) p/x *ex804ala4 $2 = 0x8O48fl9(gdb) p/x *0x804ala8$3 = Qx8048f09(gdb) p/x *0x804alac $4 = 6x8O48f02(gdb) p/x *0x804alb0$5 = 0x8O48ef9(gdb) p/x *Gx804alb4S6 = 0x8048ef2cmp -OxlO(%ebp),%eax
29、和 je 8048f5d <phase_3+0xbc>即為判斷經(jīng) 過一系列運(yùn)算后求的值是否與正確的值相等。通過分析匯編代碼,我們可以知 道當(dāng)輸入不同的x值,等到的y值如下:當(dāng) x=0 時(shí),y=788-858+751-534+534-534+534-534=147當(dāng) x=l 時(shí),y=-858+751-534+534-534+534-534=-641當(dāng) x=2 時(shí),y=751-534+534-534+534-534=217當(dāng) x=3 時(shí),x=-534+534-534+534-534=-534當(dāng) x=4 時(shí),x=534-534+534-534=0當(dāng) x=5 時(shí),x=-534+534-53
30、4=-534所以可以輸入六組數(shù)據(jù):0 147; 1 -641; 2 217; 3 -534; 4 0; 5 -534。 隨便輸入一組都能通過炸彈。That's number 2. Keep going! 0 147 Halfway there!結(jié)論與心得:第三關(guān)主要用到了 switch分支結(jié)構(gòu),根據(jù)輸如的不同數(shù)字跳轉(zhuǎn)到不同位置 進(jìn)行不同的運(yùn)算,最后得到結(jié)果。首先分析輸入數(shù)字的范圍,然后通過判斷跳轉(zhuǎn)的位置來準(zhǔn)確計(jì)算。4. phase_4Phase_4匯編代碼及注釋如下:08048e2e <phase_4>:8048e2e: 558048e2f: 89 e58048e31: 8
31、3 ec 288048e34: 8d 45 fO個(gè)數(shù)字8048e37: 89 44 24 Oc8048e3b: 8d 45 f4個(gè)數(shù)字8048e3e: 89 44 24 088048e42: c7 44 24 04 3e a2 04輸入 x/s 0x804a23e 顯示為 "d %d"8048e49: 088048e4a: 8b 45 088048e4d: 89 04 248048e50: e8 eb f9 ff ffpush%ebpmov%esp, %ebpsub$0x28, %esp#開辟棧空間lea-0x10 (%ebp), %eax#第二mov%eax, Oxc(%
32、esp)lea-Oxc (%ebp), %eax#第一mov%eax, 0x8(%esp)movl$0x804a23e, 0x4(%esp) #,提示輸入兩個(gè)整型數(shù)字mov0x8 (%ebp), %eaxmov%eax, (%esp)call8048840<_isoc99_sscanfplt>#標(biāo)準(zhǔn)輸入變量,將輸入的數(shù)字個(gè)數(shù)存在%6=中8048e55 :83f802cmp$0x2, %eax8048e58:750cjne8048e66 <phase_4+0x38>#要求輸入2個(gè)數(shù)字,即輸入的數(shù)字個(gè)數(shù)不等于2則爆炸8048e5a:8b45f4mov-Oxc (%ebp),
33、%eax#將第一個(gè)數(shù)放到%eax中8048e5d:85cOtest%eax, %eax8048e5f: 78 05js 8048e66 <phase_4+0x38>#判斷第一個(gè)數(shù),如果是負(fù)數(shù)就爆炸,所以需要%。>=08048e61: 83 f8 0ecmp $0xe, %eax8048e64: 7e 05jle 8048e6b <phase_4+0x3d>#比較第一個(gè)數(shù)和14(0xe)的大小,如果%eax<=14,則繼續(xù)執(zhí)行,否則爆炸8048e66: e8660200008048e6b: c7442408Oe 0000Oxe 存到esp+88048e72:
34、008048e73: c744240400 00000x0 存到esp+48048e7a:008048e7b:8b458048e7e:890424數(shù)存到%esp8048e81:dafunc4函數(shù)(遞歸函數(shù))8048e86: 83 f801y存放在%eax寄存器中8048e89: 75 06#y要等于1,否則爆炸8048e8b: 83 7d fO 018048e8f: 74 0c#第二個(gè)數(shù)要等于1,否則爆炸8048e91:8db4 26 00 00 00008048e98:e834 02 00 008048e9d:c98048e9e:6690call80490dl <explode_bom
35、b>movl$0xe, 0x8 (%esp) #將movl$0x0,0x4(%esp) #將mov-Oxc (%ebp), %eaxmov%eax, (%esp) #將第一個(gè)call8048b60 <func4> #調(diào)用cmp $0x1, %eax #函數(shù)的返回值jne8048e91 <phase_4+0x63>cmpl$0x1, -0x10(%ebp)je8048e9d <phase_4+0x6f>lea0x0 (%esi, %eiz, 1), %esicall80490dl <explode_bomb>leavexchg%ax, %ax
36、8048ea0: c3retcall 8048b60 <func4>知道要調(diào)用 func4 函數(shù)。func4匯編代碼及注釋如下:08048b60 <func4>:8048b60:8048b61:8048b63:8048b66:8048b69:8048b6c:#%edx->x8048b6f:5589 e583 ec 1889 5d f889 75 fc8b 55 088b 45 0c#%eax->y=0x0=08048b72: 8b 5d 10push%ebpmov%esp, %ebpsub$0x18, %esp#建立一個(gè)棧幀mov%ebx, -0x8(%eb
37、p)mov%esi, -0x4(%ebp)mov0x8 (%ebp), %edxmovOxc (%ebp), %eaxmov0x10 (%ebp), %ebx#%ebx->z=0xe=14func4 (x, y, z)%ebx, %ecx #計(jì)算臨時(shí)變量%eax, %ecx #t=z-y%ecx, %esi #t=z-y$0xlf, %esi #t= (z-y)»31,(%esi, %ecx, 1), %ecxsar %ecxadd %eax, %ecx(14»31+14)/2+0=78048b75: 89 d9movt的過程,#t=z8048b77:29clsub8
38、048b79:89cemov8048b7b:cleeIfshr邏輯右移31位8048b7e:8d0cOelea#t=(z-y)>31+(z-y)8048b81: dl f9#t= (z-y) »31+ (z-y) »18048b83: 01 cl#t= (z-y) »31+ (z-y) / 2+y=8048b85: 39 dlcmp%edx, %ecx #將 7 和 x (第一個(gè)數(shù))比較,即7-x8048b87: 7e 17jle 8048ba0 <func4+0x40>#當(dāng)7<=乂就跳轉(zhuǎn)到8048ba0否則繼續(xù)執(zhí)行下一條指令8048b89
39、: 83 e9 01if(7>x)8048b8c: 89 4c 24 08t-l 移到 0x8 (%esp), z=t-l8048b90:894424048048b94:8914248048b97:e8c4ffffff8048b9c:01cO結(jié)果存放到%eax中8048b9e:eb20結(jié)束8048ba0:b800000000跳轉(zhuǎn)到這里,此時(shí)令y=08048ba5:39dl8048ba7:7d17sub$0x1, %ecx #t=t-lmov%ecx, 0x8 (%esp) #將mov%eax, 0x4(%esp) ttymov%edx, (%esp)#xcall8048b60 <f
40、unc4> #遞歸add%eax, %eax#y=2*y,將jmp8048bc0 <func4+0x60> #mov$0x0, %eax #if(x>=7)時(shí)就cmp%edx, %ecxjge8048bc0 <func4+0x60> #如果t>=x(在這種情況下只能x=t),則跳轉(zhuǎn)到8048bc0,否則繼續(xù)執(zhí)行8048ba9:89 5c 24 088048bad:83cl018048bb0:894c24048048bb4:8914248048bb7:a48048bbc:8d440001#y=Z*y+l,將結(jié)果存到%eax中8048bc0:8b 5d f
41、8mov%ebx, 0x8(%esp)#zadd$0x1, %ecx #y=t+lmov%ecx, 0x4(%esp)y=t+lmov%edx, (%esp) #xcall8048b60 <func4>#遞歸lea0x1 (%eax, %eax, 1),%eaxmov-0x8 (%ebp), %ebx8048bc3: 8b 75 fc8048bc6: 89 ec8048bc8: 5d8048bc9: c3mov -0x4(%ebp), %esimov %ebp, %esppop %ebpret思路與分析:首先分析 phase_4 匯編代碼。movl $0x804a23e, 0x4
42、(%esp)輸入 x/s 0x804a23e顯示為"%d %d",提示輸入兩個(gè)整型數(shù)字。call 8048840 <_isoc99_sscanfplt>, cmp $0x2, %eax, jne 8048e66 <phase_4+0x38> 任然要求輸入 2 個(gè)數(shù)字。通過 mov -0xc(%ebp), %eax, test %eax, %eax, js 8048e66 <phase_4+0x38>知道第一個(gè)數(shù)為非負(fù)數(shù)。由 cmp $0xe, %eax 和jle 8048e6b <phase_4+0x3d>又可以知道第一個(gè)數(shù)字
43、要小于等于14。之 后分析func4函數(shù),分別用esp, 0x4 (%esp), %0x8(%esp)傳遞三個(gè)參數(shù),設(shè)為 x, y, z。參數(shù)y存儲(chǔ)在寄存器%eax中并作為最終的返回值,最終結(jié)果為1,也 就是n的值;參數(shù)x和z存儲(chǔ)于寄存器%edx和%ebx中,并通堆棧指針來保存或 改變(配合其他指令)。在func4中進(jìn)一步縮小了第一個(gè)數(shù)字的范圍。現(xiàn)在需 要第一個(gè)數(shù)字的范圍為7-14。通過分析func4匯編代碼,可以得到如下的c代 碼:# #include<stdio. h># int x, y, z, ret;# int func4 () # int t= (z-y) »
44、31+ (z-y) /2+y;# if(t>x)# z=t-l;# func4 ();# y=z*y;# )# else# y=0;# if (t=x)# return y;# y=t+l;# func4 ();# y=2*y+l;# # )# int main () # for(x=0;x<=0xe;x+)# y=0;# z=0xe;# ret=func4 ();# if(ret=l)# printf (*m=%d, n=%dn*, x, ret)# # return 0;# )第二個(gè)數(shù)必須為1。經(jīng)過分析可以有三組數(shù)。分別是:8 1; 9 1; 11 lo任意 輸入一組數(shù)就能通過
45、關(guān)卡。Halfway there! 8 1So you got that one. Try this one.結(jié)論與心得:這一關(guān)中在函數(shù)里調(diào)用了另外一個(gè)函數(shù)func4,func4函數(shù)中運(yùn)用到了線性遞歸。 通過分析匯編代碼可以寫出相應(yīng)的c代碼,通過分析第一個(gè)數(shù)范圍在7-14,第 二個(gè)數(shù)必須為1,結(jié)合c代碼可以得出結(jié)果。5. phase_5phased匯編代碼及注釋如下:08048db8 <phase.5>:8048db8: 558048db9: 89 e58048dbb: 568048dbc: 538048dbd: 83 ec 208048dc0: 8d 45 fO8048dc3:
46、89 44 24 0c個(gè)數(shù)8048dc7: 8d 45 f48048dca:89 44 24 08個(gè)數(shù)8048dce:c7 44 24 04 3e a2 04輸入 x/s 0x804a23e 顯示為 "%d %d"push%ebpmov%esp, %ebppush%esipush%ebxsub$0x20, %esp#開辟??臻glea-0x10(%ebp), %eaxmov%eax, Oxc (%esp)#第二1ea-Oxc(%ebp), %eaxmov%eax, 0x8 (%esp)#第一movl$0x804a23e, 0x4(%esp) #,提示輸入兩個(gè)整型數(shù)字8048d
47、d5: 088048dd6: 8b 45 088048dd9: 89 04 248048ddc: e8 5f fa ff ffmov0x8 (%ebp), %eaxmov%eax, (%esp)call 8048840<_isoc99_sscanfplt>#將輸入的數(shù)字個(gè)數(shù)返回到%eax中8048del: 83 f8 01cmp $0x1, %eax8048de4: 7f 05jg 8048deb <phase_5+0x33>#若輸入的數(shù)字個(gè)數(shù)大于1則跳轉(zhuǎn),否則爆炸,所以至少輸入兩個(gè)數(shù)字8048de6:e8e60200 008048deb:8b45f48048dee:8
48、3eOOfcall 80490dl <explode_bomb> mov -Oxc(%ebp), %eax and $0xf, %eax #第一個(gè)數(shù)“與" Oxf,這個(gè)操作可以只保留第一個(gè)數(shù)的二進(jìn)制后四位(0 “與”任何數(shù)都 為0)8048dfl :8945f4mov%eax, -Oxc (%ebp) #經(jīng)過上面的操作后再把第一個(gè)數(shù)放回原來的位置(只保留二進(jìn)制表示的后四位)8048df4:83f8Ofcmp$0xf, %eax8048df7:7429je8048e22 <phase_5+0x6a>#比較,如果第一個(gè)數(shù)和Oxf (1111)相等則爆炸,說明第一個(gè)
49、數(shù)的二進(jìn)制后四位不能為“1111”,否則爆炸8048df9: b9 00 00 00 00用來累加%6",初始化為08048dfe: ba 00 00 00 00循環(huán)次數(shù),初始化為08048e03: bb c0 al 04 08mov $0x0, %ecx #%ecx=0mov $0x0, %edx #%edx=0mov $0x804alc0, %ebx # p*0x804alc0=10 ,這個(gè)地址為數(shù)組的首地址,求的值為第一個(gè)元素的值,求數(shù)組元素:p *0x804alc016= 10, 2, 14, 7, 8, 12,15, 11, 0, 4, 1, 13, 3, 9,6, 580
50、48e08: 83 c2 01add從這里開始8048e0b: 8b 04 83mov#%eax= (%ebx+4*%eax) = (0x804alc0+4*%eax);中的某個(gè)值8048e0e: 01 cladd#%ecx=%ecx+%eax$0x1, %edx #%edx=l> 循環(huán)(%ebx, %eax, 4), %eax%eax用來保存求出的數(shù)組%eax, %ecx8048el0: 83 f8 Ofcmp$0xf, %eax8048el3: 75 f3jne 8048e08 <phase_5+0x50>#如果此時(shí)%03、(此時(shí)的數(shù)組元素值)不等于15,則繼續(xù)循環(huán),否則
51、執(zhí)行下一語句8048el5: 89 45 f4mov %eax, -0xc (%ebp) #將現(xiàn)在的元素值放回第一個(gè)數(shù)的位置? ? ?8048el8: 83 fa Ofcmp $0xf, %edx8048elb: 75 05jne 8048e22 <phase_5+0x6a>#如果%edx不等于15,則爆炸,所以,要循環(huán)15次8048eld: 39 4d f0累加的結(jié)果8048e20: 74 05#判斷第二個(gè)數(shù)的值8048e22: e8 aa 02 00 008048e27: 83 c4 208048e2a: 5b8048e2b: 5e8048e2c: 5d8048e2d: c3c
52、mp%ecx, -0x10(%ebp)#je8048e27<phase_5+0x6f>call80490dl<explode_bomb>add$0x20, %esp #釋放棧的操作pop%ebxpop%esipop%ebpret思路與分析:movl $0x804a23e, 0x4(%esp)仍然提示輸入兩個(gè)整型數(shù)字,and$0xf, %eax第一個(gè)數(shù)“與" Oxf,這個(gè)操作可以只保留第一個(gè)數(shù)的二進(jìn)制后四 位(0 “與”任何數(shù)都為0)。mov %eax, -0xc(%ebp)經(jīng)過上面的操作后再把 第一個(gè)數(shù)放回原來的位置(只保留二進(jìn)制表示的后四位)。cmp $0x
53、f, %eax 和je 8048e22 <phase_5+0x6a>比較,如果第一個(gè)數(shù)和Oxf (1111)相等則 爆炸,說明第一個(gè)數(shù)的二進(jìn)制后四位不能為“1111” ,否則爆炸。mov $0x804alc0,%ebx這個(gè)地址為數(shù)組的首地址,求的值為第一個(gè)元素的值。求數(shù)組 元素:p *0x804alc016=10, 2, 14, 7, 8, 12, 15, 11, 0, 4, 1, 13, 3, 9, 6, 5Cgdb) p *Ox8O4alc001657 = 10, 2, 14, 7, 8, 12, 15, 11, 0, 4, 1, 13, 3, 9, 6, 5)通過分析匯編代碼
54、可以推出如下C代碼:# p *0x804alc0®16=10, 2, 14, 7, 8, 12, 15, 11, 0, 4, 1, 13, 3, 9, 6, 5)# sum=0;# for(i=l;n!=15;i+)n=an;# sum+=n;# # if(i=15)# return sum;n最后需要等于15,采用逆推的方法可以知道從開始到最后n的值分別為(因?yàn)殚_始循環(huán)之前取了一個(gè)n,所以總的有16個(gè)n):5,12, 3, 7,11,13, 9, 4, 8, 0,10,1, 2,14, 6,15、也就是說需要一開始傳進(jìn)去的值為5,循環(huán)15次后得到的元素值才為15。只要 用戶輸入的第一位數(shù)的二進(jìn)制的后四位是0101 (5),則可以通過,所以第一個(gè) 數(shù)有無窮多個(gè)。第二個(gè)數(shù)累加的結(jié)果為1
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 幼兒園幼兒臨時(shí)接送合同范本
- 知識(shí)管理信息化管理實(shí)施辦法
- 臨時(shí)非營利組織救護(hù)
- 電商服務(wù)員工工資管理
- 養(yǎng)豬場建筑垃圾處理協(xié)議
- 船舶修造配電系統(tǒng)改造協(xié)議
- 美發(fā)學(xué)校食堂炊事員工作合同
- 別墅區(qū)房產(chǎn)交易合同模板
- 建筑節(jié)能掛靠施工協(xié)議
- 醫(yī)院手術(shù)室電力使用與安全
- 數(shù)據(jù)結(jié)構(gòu)課件隊(duì)列
- 彈力重力和摩擦力
- 配料罐(攪拌罐)說明書
- 【超星爾雅學(xué)習(xí)通】《中國近現(xiàn)代史綱要(首都師范大學(xué))》章節(jié)測試題及答案(一)
- 國有企業(yè)副經(jīng)理競聘面試問題及參考答案
- 2023-2024學(xué)年新疆維吾爾自治區(qū)烏魯木齊市小學(xué)數(shù)學(xué)五年級(jí)上冊期末評(píng)估提分題
- 樂山市市中區(qū)2022-2023學(xué)年度上期期末學(xué)情調(diào)查測試六年級(jí)語文答案
- GB/T 325.1-2008包裝容器鋼桶第1部分:通用技術(shù)要求
- GB/T 31326-2014植物飲料
- 氣候的成因、特點(diǎn)、判斷
- 橋(門)式起重機(jī)安裝(拆卸)、操作安全技術(shù)交底(機(jī)械設(shè)備安全交底)
評(píng)論
0/150
提交評(píng)論