二进制bomb实验第三弹

第三弹啦!继续上代码!

08048ea1<phase_3>:

 8048ea1:  55                       push   %ebp

 8048ea2:  89e5                    mov    %esp,%ebp

 8048ea4:  83ec 28                 sub    $0x28,%esp          //开辟了10个地址

 8048ea7:  8d45 f0                 lea   -0x10(%ebp),%eax     

8048eaa:  89 44 24 0c              mov   %eax,0xc(%esp)

 8048eae:  8d45 f4                 lea    -0xc(%ebp),%eax       //将第一个参数给eax

 8048eb1:  8944 24 08              mov    %eax,0x8(%esp)

 8048eb5:  c744 24 04 3e a2 04     movl $0x804a23e,0x4(%esp)  //$0x804a23e应该很重要

 8048ebc:  08

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

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

 8048ec3:  e878 f9 ff ff           call   8048840<__isoc99_sscanf@plt>

 8048ec8:  83f8 01                 cmp    $0x1,%eax         //eax大于1就不bomb

 8048ecb:  7f05                    jg     8048ed2<phase_3+0x31>

 8048ecd:  e8ff 01 00 00           call   80490d1<explode_bomb>

 8048ed2:  837d f4 07              cmpl   $0x7,-0xc(%ebp)      //-0xc(%ebp)大于7就bomb  -0xc(%ebp)是第一个参数

 8048ed6:  776b                    ja     8048f43<phase_3+0xa2>

 8048ed8:  8b45 f4                 mov   -0xc(%ebp),%eax  //eax变成了我输入的第一个数

 8048edb:  ff24 85 a0 a1 04 08     jmp   *0x804a1a0(,%eax,4)      //以0x804a1a0(,%eax,4)作为读地址,相当于switch语句,eax值改变,就jump到不同位置

 //这里比如输入0,就jump到 8048f12,得到147;如果输入1,就jump到8048f19,得到-641;我测试了两个都可以通过。

 8048ee2:  b800 00 00 00           mov    $0x0,%eax

 8048ee7:  eb53                    jmp    8048f3c<phase_3+0x9b>

 8048ee9:  b800 00 00 00           mov    $0x0,%eax

 8048eee:  6690                    xchg   %ax,%ax    //xchg是交换,不过好像在这里没什么用啊

 8048ef0:  eb45                    jmp    8048f37<phase_3+0x96>

 8048ef2:  b800 00 00 00           mov    $0x0,%eax

 8048ef7:  eb39                    jmp    8048f32 <phase_3+0x91>

 8048ef9:  b800 00 00 00           mov    $0x0,%eax

 8048efe:  6690                    xchg   %ax,%ax

 8048f00:  eb2b                    jmp    8048f2d<phase_3+0x8c>

 8048f02:  b800 00 00 00           mov    $0x0,%eax

 8048f07:  eb1f                    jmp    8048f28<phase_3+0x87>

 8048f09:  b800 00 00 00           mov    $0x0,%eax

 8048f0e:  6690                    xchg   %ax,%ax

 8048f10:  eb11                    jmp    8048f23<phase_3+0x82>

 8048f12:  b814 03 00 00           mov    $0x314,%eax//当输入为0时 就会跳转到这里。往下执行

 8048f17:  eb05                    jmp    8048f1e<phase_3+0x7d>

 8048f19:  b800 00 00 00           mov    $0x0,%eax

 8048f1e:  2d5a 03 00 00           sub    $0x35a,%eax

 8048f23:  05ef 02 00 00           add    $0x2ef,%eax

 8048f28:  2d16 02 00 00           sub    $0x216,%eax

 8048f2d:  0516 02 00 00           add    $0x216,%eax

 8048f32:  2d16 02 00 00           sub    $0x216,%eax

 8048f37:  0516 02 00 00           add    $0x216,%eax

 8048f3c:  2d16 02 00 00           sub    $0x216,%eax

 8048f41:  eb0a                    jmp    8048f4d <phase_3+0xac>

 8048f43:  e889 01 00 00           call   80490d1<explode_bomb>

 8048f48:  b800 00 00 00           mov    $0x0,%eax

 8048f4d:  837d f4 05              cmpl  $0x5,-0xc(%ebp)

 8048f51:  7f05                    jg8048f58<phase_3+0xb7> //-0xc(%ebp)比5大,就bomb

 8048f53:  3b45 f0                 cmp   -0x10(%ebp),%eax

 8048f56:  74 05                    je    8048f5d <phase_3+0xbc>  //%eax和-0x10(%ebp)一样,就不会bomb

 8048f58:  e874 01 00 00           call   80490d1<explode_bomb>

 8048f5d:  c9                       leave 

 8048f5e:  6690                    xchg   %ax,%ax

 8048f60:  c3                       ret

分析分析吧:

粗粗看一下代码,应该会留意到这里有几个点:

 

movl   $0x804a23e,0x4(%esp) //$0x804a23e应该很重要,有了第一关的经验,我就用gdb查看了0x804a23e的内容,发现是 %d %d,结合call   8048840 <__isoc99_sscanf@plt>指令,就可以大概确定这是要输入两个整形的节奏。下一条指令cmp    $0x1,%eax //eax大于1就不bomb,更加确定了这一点。

 

cmpl   $0x7,-0xc(%ebp) //-0xc(%ebp)大于7就bomb  -0xc(%ebp)是第一个参数。cmpl   $0x5,-0xc(%ebp) jg8048f58<phase_3+0xb7> //-0xc(%ebp)比5大,就bomb。这两条指令都是确定第一个参数的范围的。

 

最关键的代码来了:

mov    -0xc(%ebp),%eax  //eax变成了我输入的第一个数

jmp    *0x804a1a0(,%eax,4)//以*0x804a1a0(,%eax,4)作为读地址,相当于switch语句,eax值改变,就jump到不同位置。到这里我就可以确定这个phase3想干嘛了,大概就是像c程序中的Switch一样,输入不同的参数,匹配到不同的代码段执行相应内容。(一开始我找不到代码上0x804a1a的地址,后来发现前面有个*,原来是读内容啊,所以我就又用gdb x/xw 0x804a1a命令尝试了一下,发现内容0x8048f12,所以是从0x8048f12开始读,看下图:)


 

je    8048f5d <phase_3+0xbc>//%eax和-0x10(%ebp)一样,就不会bomb,所以我们输入的第二个参数要等于计算出的那个值。

还是试一下吧,比如我输入的第一个参数为1,这样就会跳到0x8048f12+0*4=0x8048f12;然后顺序执行下面的语句,是一系列的加减运算,用机器自带的程序员计算器就ok了,0x314-0x35a+0x2ef-0x216+0x216-0x216+0x216-0x216=147,看截图:


   哈哈,又成功过了一关。


这说明我对代码的理解是正确的,那么我就再来试一下当第一个参数为1的时候,经过我的计算应该是-641,来看一下:


恩!又对了,说明不止一个答案,我就不一一试了。还有好多弹等着我拆呢!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值