二进制炸弹实验 BinaryBombs( 四 )

phase_4密码如下:10 5破解过程:

  1. 设置断点,运行,反汇编
  2. 观察到
    401562: be 1f 33 40 00  mov  $0x40331f,%esi401567: b8 00 00 00 00  mov  $0x0,%eax40156c: e8 9f fb ff ff  callq 401110 <__isoc99_sscanf@plt>
   调用scanf读入,那么先打印下0x40331f是什么
二进制炸弹实验 BinaryBombs

文章插图
   答案是两个整型变量
  1. 再根据下面这段汇编语言
401576:8b 45 fc     mov  -0x4(%rbp),%eax401579:85 c0      test  %eax,%eax40157b:78 05      js   401582 <phase_4+0x30>40157d:83 f8 0e     cmp  $0xe,%eax401580:7e 05      jle  401587 <phase_4+0x35>401582:e8 b9 03 00 00  callq 401940 <explode_bomb>401587:ba 0e 00 00 00  mov  $0xe,%edx得出,输入的第一个数范围:[0, 14]

401594:  e8 7f ff ff ff callq 401518 <func4>401599: 83 f8 05      cmp  $0x5,%eax40159c:  75 06     jne  4015a4 <phase_4+0x52>可知func4的返回值必须为5

40159e: 83 7d f8 05       cmpl  $0x5,-0x8(%rbp)4015a2: 74 05         je   4015a9 <phase_4+0x57>4015a4: e8 97 03 00 00    callq 401940 <explode_bomb>可知,输入的第二个数必须为5
  1. 下面分析递归函数func4 。
    func4里每次都用到 %edi, %esi,%edx,%eax 。
    而我们输入的第一个数在一开始便是%edi 的值,%esi 一开始为0,%edx一开始为0xe,即为14 。
    不妨,将这四个寄存器,记为 a,b,c,res
看看这几段
40151c: 89 d1         mov  %edx,%ecx40151e: 29 f1         sub  %esi,%ecx401520: 89 c8         mov  %ecx,%eax401522: c1 e8 1f      shr  $0x1f,%eax// 逻辑右移31401525:01c8           add  %ecx,%eax                                                        401527: d1 f8         sar  %eax //算术右移401529: 01 f0         add  %esi,%eax写为公式:\(res = [(c - b) >> 31 + (c - b)] / 2 + b\).
化简一下,\(res = (c - b) / 2 + b\).
再看后面的分支,和分支的执行:
if(a < res) func4(a, b, res – 1, res), res *= 2, return reselse if(a > res) func(a, res + 1, c, res), res = res * 2 + 1; return reselse return 0

经验总结扩展阅读