CSAPP_实验二 拆炸弹 汇编知识应用

CSAPP——实验二 拆炸弹

Phase1

disas phase_1, 反汇编 phase_1 函数

在 phase_1函数入口处 设置断点 break phase_1

run 开始运行,输入字符串 “hello” 

stepi ,逐条执行命令。寄存器 %rdi、%rsi、%rdx,%rcx、%r8、%r9用作传递函数参数,分别对应第1个参数、第2个参数直到第6个参数。

我们的输入作为调用函数时用到的参数保存在了寄存器%rdi中。对应的地址为 0x603780,用 x/s 0x603780 查看对应的值,确实如此。

stepi 继续执行下一条指令,即运行到 mov   $0x402400,%esi,此时用 x/s $esi 查看寄存器里面的值,即地址 0x402400的值,即为第一颗炸弹的答案。

Phase_2

观察 read_six_numbers 发现要输入6个数字,6个数字会依次存在 %rsp,%rsp+4,%rsp+8,%rsp+12...%rsp+24cmpl $0x1,(%rsp), 第一个数字是1,再接下去看跳转到52%rsp+4对应第2个数字,放进%rbx中将%rbp设置成%rsp+24(%rbp是用来判断循环是否退出的寄存器),之后跳转到27,这里将第1个数赋值给%eax将%eax*2去和第2个数对比,如果相等就继续,以此类推,可以发现这个循环就是用来判断输入的数字是否依次增大一倍的,所以第二题的拆弹密码就是:1 2 4 8 16 32

Phase_3

phase_3函数的反汇编代码

断点逐步执行指令,并打印出 0x4025cf 的内容

说明 sscanf 输入的两个整数存在 0x4025cf 中。反汇编后存在很多条jmp指令,可见是switch结构的语句判断。要跳转过去的地址是 0x402470+%rax+8,而eax就是我们输入的第一个数。

之后的每一个jmp都看做是一个case语句。每条 case 语句里,都是将 某个立即数 赋值给 寄存器 %eax, 最后都跳转到<phase_3+123> 的位置判断第二个数字是否匹配。

而 %eax 的值,是根据输入的第一个数 跳转到相应的case语句中赋值的,所以 %eax 有很多的取值可能。但注意:cmpl $0x7,0x8(%rsp),第一个输入的数字一定要小于7,否则会直接引爆炸弹。

我们选择输入的第一个参数为 3,则对应的跳转到十六进制 0x100 ,即 256。

Phase_4

phase_4函数

查看  func4 函数的反汇编代码,func4内部在调用func4,递归的汇编

给每条指令加上了注释:

对应的c语言程序

int func4(int target, int step, int limit) {
  /* edi = target; esi = step; edx = limit */
  int temp = (limit - step) * 0.5;
  int mid = temp + step;
  if (mid > target) {
    limit = mid - 1;
    int ret1 = func4(target, step, limit);
    return 2 * ret1;
  } else {
    if (mid >= target) {
      return 0;
    } else {
      step = mid + 1;
      int ret2 = func4(target, step, limit);
      return (2 * ret2 + 1);
    }
  }
}

最后推出其一个答案为(7,0)

Phase_5

要求输入的字符串长度=6

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值