这篇文章意为记录下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!!!
分析后发现出错在这段代码
扫描二维码关注公众号,回复:
1903514 查看本文章
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>。