CSAPP:Bomb Lab

1 篇文章 0 订阅

一共6个代码块。

第一个函数

0000000000400ee0 <phase_1>:
  400ee0:   48 83 ec 08             sub    $0x8,%rsp
  400ee4:   be 00 24 40 00          mov    $0x402400,%esi
  400ee9:   e8 4a 04 00 00          callq  401338 <strings_not_equal>
  400eee:   85 c0                   test   %eax,%eax
  400ef0:   74 05                   je     400ef7 <phase_1+0x17>
  400ef2:   e8 43 05 00 00          callq  40143a <explode_bomb>
  400ef7:   48 83 c4 08             add    $0x8,%rsp
  400efb:   c3                      retq   

这里,可以看到,程序从0x402400处读取一个值,并调用函数与输入比较,如果相等就跳转到return处,不等就继续执行(下一句就是explode)。

所以此处要输入的就是0x402400的内容,可以用指令x/s 0x402400获取此处的内容。我这个Lab的内容是Border relations with Canada have never been better.

第二个函数

  0000000000400efc <phase_2>:
  400efc:   55                      push   %rbp
  400efd:   53                      push   %rbx
  400efe:   48 83 ec 28             sub    $0x28,%rsp
  400f02:   48 89 e6                mov    %rsp,%rsi
  400f05:   e8 52 05 00 00          callq  40145c <read_six_numbers>    # 读取6个数值
  400f0a:   83 3c 24 01             cmpl   $0x1,(%rsp)                  # 判断rsp指向的地址内容是不是1
  400f0e:   74 20                   je     400f30 <phase_2+0x34>        # 如果是,就跳转
  400f10:   e8 25 05 00 00          callq  40143a <explode_bomb>        # 不是,就继续执行(explode)
  400f15:   eb 19                   jmp    400f30 <phase_2+0x34>
  400f17:   8b 43 fc                mov    -0x4(%rbx),%eax              # 把第一个数赋值给%eax
  400f1a:   01 c0                   add    %eax,%eax                    # 第一个数*2
  400f1c:   39 03                   cmp    %eax,(%rbx)                  # 是不是等于第二个数
  400f1e:   74 05                   je     400f25 <phase_2+0x29>        # 如果是,跳转
  400f20:   e8 15 05 00 00          callq  40143a <explode_bomb>        # 如果不是,explode
  400f25:   48 83 c3 04             add    $0x4,%rbx                    # %rbx指向下一个数
  400f29:   48 39 eb                cmp    %rbp,%rbx                    # 判断%rbx现在是不是指向最后一个数
  400f2c:   75 e9                   jne    400f17 <phase_2+0x1b>        # 如果不是最后一个数,跳转回上面继续判断
  400f2e:   eb 0c                   jmp    400f3c <phase_2+0x40>        # 如果说是,往下面跳转
  400f30:   48 8d 5c 24 04          lea    0x4(%rsp),%rbx               # %rbx是第二个数
  400f35:   48 8d 6c 24 18          lea    0x18(%rsp),%rbp              # %rbp是最后一个数
  400f3a:   eb db                   jmp    400f17 <phase_2+0x1b>        # 跳转
  400f3c:   48 83 c4 28             add    $0x28,%rsp
  400f40:   5b                      pop    %rbx
  400f41:   5d                      pop    %rbp
  400f42:   c3                      retq

每句话干了什么都在上面备注好了,可以发现就是要输入一个从1开始的等比数列,1,2,4,8,16,32。

第三个函数

0000000000400f43 <phase_3>:
  400f43:   48 83 ec 18             sub    $0x18,%rsp
  400f47:   48 8d 4c 24 0c          lea    0xc(%rsp),%rcx
  400f4c:   48 8d 54 24 08          lea    0x8(%rsp),%rdx
  400f51:   be cf 25 40 00          mov    $0x4025cf,%esi               # 两个int值  
  400f56:   b8 00 00 00 00          mov    $0x0,%eax                    # 把%eax置零                    
  400f5b:   e8 90 fc ff ff          callq  400bf0 <__isoc99_sscanf@plt> # 调用scanf函数,读取输入
  400f60:   83 f8 01                cmp    $0x1,%eax                    # 拂去scanf返回值(返回值是输入变量的个数)
  400f63:   7f 05                   jg     400f6a <phase_3+0x27>        # 如果输入变量多于一个,跳转
  400f65:   e8 d0 04 00 00          callq  40143a <explode_bomb>
  400f6a:   83 7c 24 08 07          cmpl   $0x7,0x8(%rsp)               # 第一个数和7比较
  400f6f:   77 3c                   ja     400fad <phase_3+0x6a>        # >7就跳转
  400f71:   8b 44 24 08             mov    0x8(%rsp),%eax               # 把第一个数放到%eax里面
  400f75:   ff 24 c5 70 24 40 00    jmpq   *0x402470(,%rax,8)           # 跳转到地址 0x400f7c+%rax*8(错),应该是跳转到地址*(0x402470+%rax*8)
  400f7c:   b8 cf 00 00 00          mov    $0xcf,%eax                   # %rax = 0,%eax = 207
  400f81:   eb 3b                   jmp    400fbe <phase_3+0x7b>
  400f83:   b8 c3 02 00 00          mov    $0x2c3,%eax                  # %eax = 707
  400f88:   eb 34                   jmp    400fbe <phase_3+0x7b>
  400f8a:   b8 00 01 00 00          mov    $0x100,%eax                  # %eax = 256
  400f8f:   eb 2d                   jmp    400fbe <phase_3+0x7b>
  400f91:   b8 85 01 00 00          mov    $0x185,%eax                  # %eax = 389
  400f96:   eb 26                   jmp    400fbe <phase_3+0x7b>
  400f98:   b8 ce 00 00 00          mov    $0xce,%eax                   # %eax = 206
  400f9d:   eb 1f                   jmp    400fbe <phase_3+0x7b>
  400f9f:   b8 aa 02 00 00          mov    $0x2aa,%eax                  # %eax = 682
  400fa4:   eb 18                   jmp    400fbe <phase_3+0x7b>        # %rax = 5
  400fa6:   b8 47 01 00 00          mov    $0x147,%eax                  # %eax = 327
  400fab:   eb 11                   jmp    400fbe <phase_3+0x7b>        # 跳转
  400fad:   e8 88 04 00 00          callq  40143a <explode_bomb>
  400fb2:   b8 00 00 00 00          mov    $0x0,%eax
  400fb7:   eb 05                   jmp    400fbe <phase_3+0x7b>
  400fb9:   b8 37 01 00 00          mov    $0x137,%eax                  # %eax = 311
  400fbe:   3b 44 24 0c             cmp    0xc(%rsp),%eax               # switch跳转至此
  # 比较第二个数和%eax里面的大小
  400fc2:   74 05                   je     400fc9 <phase_3+0x86>
  400fc4:   e8 71 04 00 00          callq  40143a <explode_bomb>
  400fc9:   48 83 c4 18             add    $0x18,%rsp
  400fcd:   c3                      retq

经过gdb调试,我发现我每个注释了%eax数值的入口,对应的第一个数的值分别是0,2,3,4,5,6,7,1。但是这与%rax*8的跳转逻辑不符。

  1. 为什么第一个输入值在%rsp+8,而不是%rsp+4?

    答:因为scanf("%d %d", &a, &b)有三个参数,输入格式也是一个参数。

  2. 为什么switch跳转判断的时候,明明写的是%rax*8,每两个分支入口间隔8字节,但是下面分支的实际入口并不是这样? 为什么%rax = 1的时候会跳转到0x400fb9?

    答:因为!!!*0x402470(,%rax,8)的意思是 *(0x402470+%rax*8),而不是 *0x402470+%rax*8!!!所以这个实际上应该是指向了一个查找表!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值