二进制拆弹bomb实验第二弹

来源:互联网 发布:我行我素软件 编辑:程序博客网 时间:2024/04/28 17:26

著名的bomb拆炸弹实验第二关:

程序运行在linux环境中。程序运行中有6个关卡(6个phase),每个phase需要用户在终端上输入特定的字符或者数字才能通关,否则会引爆炸弹!那么如何才能知道输入什么内容呢?这需要你使用gdb工具反汇编出汇编代码,结合c语言文件找到每个关卡的入口函数。然后分析汇编代码,找到在每个phase程序段中,引导程序跳转到“explode_bomb”程序段的地方,并分析其成功跳转的条件,以此为突破口寻找应该在命令行输入何种字符通关。

第二弹正式开始!上代码!

08048d6a <phase_2>:   //测试得到答案:0 1 1 2 3 5

 8048d6a:  55                   push   %ebp

 8048d6b:  89e5                mov   %esp,%ebp

 8048d6d:  56                   push   %esi

 8048d6e:  53                   push   %ebx

 8048d6f:  83ec 30                 sub    $0x30,%esp

 8048d72:  8d45 e0                 lea  -0x20(%ebp),%eax//猜测-0x20(%ebp)放的是第一个参数,-0x1c(%ebp)放第二个参数,以此类推

 8048d75:  8944 24 04              mov    %eax,0x4(%esp) 

 8048d79:  8b45 08                 mov    0x8(%ebp),%eax

 8048d7c:  8904 24                 mov    %eax,(%esp)

 8048d7f:  e887 03 00 00           call   804910b<read_six_numbers>

 8048d84:  837d e0 00              cmpl  $0x0,-0x20(%ebp)  //-0x20(%ebp) 我猜想应该是第1个参数位置,ebp要不等于0,就跳到爆炸

 8048d88:  7506                    jne    8048d90<phase_2+0x26> //就爆炸

 8048d8a:  837d e4 01              cmpl   $0x1,-0x1c(%ebp) //第二个参数要等于1,就跳过bomb

 8048d8e:  7405                    je     8048d95<phase_2+0x2b>    

 8048d90:  e83c 03 00 00           call   80490d1 <explode_bomb>

 8048d95:  8d5d e8                 lea    -0x18(%ebp),%ebx //第三个参数给ebx i的初始值为3

 8048d98:  8d75 f8                 lea    -0x8(%ebp),%esi //把第六个参数给esi

 8048d9b:  8b43 fc                 mov    -0x4(%ebx),%eax //第二个参数给eax

 8048d9e:  0343 f8                 add -0x8(%ebx),%eax  //eax=eax+(ebx-0x8)  (ebx-0x8)是第一个参数a[i]=a[i-1]+a[i-2];

 8048da1:  3903                    cmp    %eax,(%ebx)   // ebx和eax一样,就跳过bomb  第三个参数和第四个参数经过运算后eax+(ebx-0x8)一样

 8048da3:  7405                    je     8048daa <phase_2+0x40>

 8048da5:  e827 03 00 00           call   80490d1<explode_bomb>

 8048daa:  83c3 04                 add    $0x4,%ebx    //ebx+4,i++

 8048dad:  39f3                    cmp    %esi,%ebx    //ebx和esi,就是和第六个参数不一样,就循环,一样就跳出循环。

 8048daf:  75ea                    jne    8048d9b<phase_2+0x31>

 8048db1:  83c4 30                 add    $0x30,%esp

 8048db4:  5b                   pop    %ebx

 8048db5:  5e                       pop    %esi

 8048db6:  5d                   pop    %ebp

 8048db7:  c3                       ret

看到这里,call   804910b <read_six_numbers>,就到0x804910b的地方去读代码,

这个函数的主要功能就是读六个数进来(读入的六个参数放的位置很重要啊!我被这六个数的位置折磨得哎)。

add -0x8(%ebx),%eax   //eax=eax+(ebx-0x8)  (ebx-0x8)是第一个参数 a[i]=a[i-1]+a[i-2]; add    $0x4,%ebx   //ebx+4,i++。从这两条语句可以推测这里有循环。然后再确定循环初始值:lea    -0x18(%ebp),%ebx //第三个参数给ebx i的初始值为3。

add -0x8(%ebx),%eax   //eax=eax+(ebx-0x8)  (ebx-0x8)是第一个参数 a[i]=a[i-1]+a[i-2];应该是循环中执行的内容,用来求输入的参数值,因为这里有很多cmp语句,应该是用来判断计算得到的值是不是和我们输入的值一样。

循环已经定了,就解决了大部分问题。cmpl   $0x0,-0x20(%ebp)  //-0x20(%ebp) 我猜想应该是第1个参数位置,ebp要不等于0,就跳到爆炸;cmpl   $0x1,-0x1c(%ebp) //第二个参数要等于1,就跳过bomb。这里确定了第一个数为0,第二个数为1.然后结合循环,求得参3=0+1=1;参4=1+1=2;参5=1+2=3;参6=2+3=5.试一试是不是对的吧。看截图(虽然之前死了好几次,但是最终还是光明的):

成功了,我的推测是对的。哈哈哈!

 

  其实刚开始的时候我进入了一个误区,把六个参数放的位置搞倒了,绕了好几圈才绕出来,好惨~~~看上图bombbomb死了好几次,呜呜。因为我以为a[i]=a[i+1]+a[i+2],

后来重新温故了书上关于函数调用时的帧栈知识,才明白后放入的参数地址越小。

其实通过后面对gdb的应用,发现gdb的功能很强大,回过头来发现其实这题也可以通过gdb来观察我放入的参数放在哪个位置,这样就可以避免我之前犯的错误了,也不用纠结辣么久。。。还有就是书本上那个P149页的帧栈表很有用啊!!!后来好多题都有用到。


1 0
原创粉丝点击