標籤:scanf style ges blog $0 call 技術 字串 plt
先貼出phase_4的代碼:
0000000000400fce <func4>: ;%rdi=num_0;%rsi=0;%rdx=0xe; 400fce: 48 83 ec 08 sub $0x8,%rsp 400fd2: 89 d0 mov %edx,%eax ;%eax=0xe; 400fd4: 29 f0 sub %esi,%eax ;%eax=0xe-0==e; 400fd6: 89 c1 mov %eax,%ecx ;%ecx=e; 400fd8: c1 e9 1f shr $0x1f,%ecx ;右移31位,注意shr是邏輯右移!!! 400fdb: 01 c8 add %ecx,%eax ;也就是如果%eax為正數則不變,為負數則+1; 400fdd: d1 f8 sar %eax ;(算術)右移1位,即%eax/2; 400fdf: 8d 0c 30 lea (%rax,%rsi,1),%ecx ;%ecx=e; 400fe2: 39 f9 cmp %edi,%ecx 400fe4: 7e 0c jle 400ff2 <func4+0x24> ;if(cx<=di)continue;else %edx=-(1+%rcx); 400fe6: 8d 51 ff lea -0x1(%rcx),%edx 400fe9: e8 e0 ff ff ff callq 400fce <func4> ;%eax=2*%eax. 400fee: 01 c0 add %eax,%eax ;注意這裡,自身調用func4後的操作,%eax乘以2了,然後ret。 400ff0: eb 15 jmp 401007 <func4+0x39> 400ff2: b8 00 00 00 00 mov $0x0, %eax ;注意這裡,%eax=0,然後ret返回。這裡才開始停止調用自身。重點中的重點!!! 400ff7: 39 f9 cmp %edi,%ecx 400ff9: 7d 0c jge 401007 <func4+0x39> 400ffb: 8d 71 01 lea 0x1(%rcx),%esi 400ffe: e8 cb ff ff ff callq 400fce <func4> ;%eax=2*%eax+1. 401003: 8d 44 00 01 lea 0x1(%rax,%rax,1),%eax;注意這裡,自身調用func4後的操作,%eax乘以2並加1,然後ret。 401007: 48 83 c4 08 add $0x8,%rsp 40100b: c3 retq 000000000040100c <phase_4>: 40100c: 48 83 ec 18 sub $0x18,%rsp 401010: 48 8d 4c 24 0c lea 0xc(%rsp),%rcx ;這裡跟之前的一樣,(%rsp+0xc)儲存第二個數字,令其為num_1; 401015: 48 8d 54 24 08 lea 0x8(%rsp),%rdx ;(%rsp+8)儲存第一數,令其為num_0. 40101a: be cf 25 40 00 mov $0x4025cf,%esi ;查看記憶體為字串"%d %d",說明還是輸入兩個數。 40101f: b8 00 00 00 00 mov $0x0,%eax 401024: e8 c7 fb ff ff callq 400bf0 <[email protected]> 401029: 83 f8 02 cmp $0x2,%eax ;sscanf正常傳回值為2,條件跳轉不執行。 40102c: 75 07 jne 401035 <phase_4+0x29> 40102e: 83 7c 24 08 0e cmpl $0xe,0x8(%rsp) ;if(num_0 <= 14) jmp;else to bomb; 401033: 76 05 jbe 40103a <phase_4+0x2e> ;所以這裡要求num_0必須小於等於14 401035: e8 00 04 00 00 callq 40143a <explode_bomb> 40103a: ba 0e 00 00 00 mov $0xe,%edx 40103f: be 00 00 00 00 mov $0x0,%esi 401044: 8b 7c 24 08 mov 0x8(%rsp),%edi ;這裡是針對num_0的運算,調用了函數func4,這裡是重點!! 401048: e8 81 ff ff ff callq 400fce <func4> 40104d: 85 c0 test %eax,%eax ;if(%eax==0)jmp;else to bomb; 40104f: 75 07 jne 401058 <phase_4+0x4c>;也就是call func4的傳回值必須為0,否則爆炸。 401051: 83 7c 24 0c 00 cmpl $0x0,0xc(%rsp) 401056: 74 05 je 40105d <phase_4+0x51> ;這裡比較num_1,要求第二個數必須等於0。 401058: e8 dd 03 00 00 callq 40143a <explode_bomb> 40105d: 48 83 c4 18 add $0x18,%rsp 401061: c3 retq
指令的講解在注釋裡了,但是想講講我的另一種分析方法:
途中通道的意思,表述可能不對,可以理解為是一個啟動並執行路程吧。
為了保證總的傳回值是0,所以只能走a,c通道(路程),由此可以計算出%ecx的值,只要在這幾次計算中有一次num_0(即輸入的第一個數)等於%ecx的值,就可以正確返回0了。
所以最終的答案為 "7 0","3 0","1 0","0 0"。
到這裡,就結束了。
CSAPP 3e: Bomb lab (phase_4)