這篇文章意爲記錄下Bomb4中比較微妙的地方。
之前經過分析,phase_4需要兩個int值,第一個值<=14,第二個爲0。
又發現<fun4>傳回的rax應爲0。
現在着重分析<fun4>如下:
0000000000400fce <func4>:
400fce: 48 83 ec 08 sub $0x8,%rsp
400fd2: 89 d0 mov %edx,%eax
400fd4: 29 f0 sub %esi,%eax
400fd6: 89 c1 mov %eax,%ecx
400fd8: c1 e9 1f shr $0x1f,%ecx
400fdb: 01 c8 add %ecx,%eax
400fdd: d1 f8 sar %eax
400fdf: 8d 0c 30 lea (%rax,%rsi,1),%ecx //temp=(esi+edx)/2
400fe2: 39 f9 cmp %edi,%ecx
400fe4: 7e 0c jle 400ff2 <func4+0x24>
400fe6: 8d 51 ff lea -0x1(%rcx),%edx //temp>a時
400fe9: e8 e0 ff ff ff callq 400fce <func4>
400fee: 01 c0 add %eax,%eax
400ff0: eb 15 jmp 401007 <func4+0x39>
400ff2: b8 00 00 00 00 mov $0x0,%eax //ret=0
400ff7: 39 f9 cmp %edi,%ecx
400ff9: 7d 0c jge 401007 <func4+0x39>
400ffb: 8d 71 01 lea 0x1(%rcx),%esi //temp<a時
400ffe: e8 cb ff ff ff callq 400fce <func4>
401003: 8d 44 00 01 lea 0x1(%rax,%rax,1),%eax //eax = 2 * rax + 1
401007: 48 83 c4 08 add $0x8,%rsp
40100b: c3 retq
還原得到函數如下:
int f(int a,int b,int c){
int ret=(c-b)/2;
int temp=(b+c)/2;
if(temp>a){
c=temp-1;
return f(a,b,c);
}
ret=0;
if(temp<a){
b=temp+1;
ret=f(a,b,c);
ret=ret*2+1;
}
return ret;
}
其中 a爲edi中的值,即爲輸入的第一個值;b爲esi的值,爲0;c爲edx的值爲調用時傳入的0xe即14。
在ide中跑了一遍,發現輸入7 ,3 ,1 ,0 四個數返回值爲0,即爲可以通過的值。而負值時,棧溢出。
這是爲什麼呢?
因爲在<fun4>中,保持ret爲零,需要temp始終>=a,即最後b、c的平均值(int)剛好落在a上。b=0,c=14時只有以上符合。
而當實際第一個輸入小於零時,會BOMB!!!
分析後發現出錯在這段代碼
40102e: 83 7c 24 08 0e cmpl $0xe,0x8(%rsp)
401033: 76 05 jbe 40103a <phase_4+0x2e>
401035: e8 00 04 00 00 callq 40143a <explode_bomb>
jbe是無符號<=,無符號情況下S1<=S2,CMP S2,S1,S1-S2,會得到CF即進位標誌爲1,而S1爲負時,CF爲0。jbe爲CF|ZF此時爲0,callq 40143a <explode_bomb>。