计组实验-Bomb Lab -2

先打断点,运行chmod +x *修改权限成可执行程序,disas把机器码转化为反汇编代码,然后查看函数汇编代码

复制代码
Dump of assembler code for function phase_1:
   0x0000000000001264 <+0>:     sub    $0x8,%rsp
   0x0000000000001268 <+4>:     lea    0x1841(%rip),%rsi        # 0x2ab0
   0x000000000000126f <+11>:    callq  0x1774 <strings_not_equal>
   0x0000000000001274 <+16>:    test   %eax,%eax
   0x0000000000001276 <+18>:    jne    0x127d <phase_1+25>
   0x0000000000001278 <+20>:    add    $0x8,%rsp
   0x000000000000127c <+24>:    retq   
   0x000000000000127d <+25>:    callq  0x1a78 <explode_bomb>
   0x0000000000001282 <+30>:    jmp    0x1278 <phase_1+20>
End of assembler dump.

解释汇编代码

  1. **`sub $0x8,%rsp`**:
  • 减少栈指针,分配 8 字节的栈空间。
  1. **`lea 0x1841(%rip),%rsi`**:
  • 计算一个内存地址,并将其存储在 `rsi` 寄存器中。这个地址是一个字符串常量的地址,地址为 `0x2ab0`。
  1. **`callq 0x1774 <strings_not_equal>`**:
  • 调用 `strings_not_equal` 函数,比较两个字符串是否相等。一个字符串是用户输入的,另一个字符串是 `rsi` 寄存器中存储的字符串常量。
  1. **`test %eax,%eax`**:
  • 测试 `eax` 寄存器的值。如果 `eax` 为 0,表示字符串相等;否则,表示字符串不相等。
  1. **`jne 0x127d <phase_1+25>`**:
  • 如果字符串不相等,跳转到 `0x127d`,调用 `explode_bomb` 函数。
  1. **`add $0x8,%rsp`**:
  • 恢复栈指针。
  1. **`retq`**:
  • 返回调用者。
  1. **`callq 0x1a78 <explode_bomb>`**:
  • 调用 `explode_bomb` 函数,表示输入错误,炸弹爆炸。
  1. **`jmp 0x1278 <phase_1+20>`**:
  • 跳转到 `0x1278`,恢复栈指针并返回。

找到rip的地址加上偏移的0x1842即可

然后查找这个地址附件的字符串

跟第一关一样的方法

还是先解析反汇编代码

复制代码
0x0000000000001284 <+0>:     push   %rbp
   0x0000000000001285 <+1>:     push   %rbx
   0x0000000000001286 <+2>:     sub    $0x28,%rsp
   0x000000000000128a <+6>:     mov    %fs:0x28,%rax
   0x0000000000001293 <+15>:    mov    %rax,0x18(%rsp)
   0x0000000000001298 <+20>:    xor    %eax,%eax
   0x000000000000129a <+22>:    mov    %rsp,%rsi
   0x000000000000129d <+25>:    callq  0x1ab4 <read_six_numbers>
   0x00000000000012a2 <+30>:    cmpl   $0x0,(%rsp)
   0x00000000000012a6 <+34>:    jne    0x12af <phase_2+43>
   0x00000000000012a8 <+36>:    cmpl   $0x1,0x4(%rsp)
   0x00000000000012ad <+41>:    je     0x12b4 <phase_2+48>
   0x00000000000012af <+43>:    callq  0x1a78 <explode_bomb>
   0x00000000000012b4 <+48>:    mov    %rsp,%rbx
   0x00000000000012b7 <+51>:    lea    0x10(%rbx),%rbp
   0x00000000000012bb <+55>:    jmp    0x12c6 <phase_2+66>
   0x00000000000012bd <+57>:    add    $0x4,%rbx
   0x00000000000012c1 <+61>:    cmp    %rbp,%rbx
   0x00000000000012c4 <+64>:    je     0x12d7 <phase_2+83>
   0x00000000000012c6 <+66>:    mov    0x4(%rbx),%eax
   0x00000000000012c9 <+69>:    add    (%rbx),%eax
   0x00000000000012cb <+71>:    cmp    %eax,0x8(%rbx)
   0x00000000000012ce <+74>:    je     0x12bd <phase_2+57>
   0x00000000000012d0 <+76>:    callq  0x1a78 <explode_bomb>
   0x00000000000012d5 <+81>:    jmp    0x12bd <phase_2+57>
   0x00000000000012d7 <+83>:    mov    0x18(%rsp),%rax
   0x00000000000012dc <+88>:    xor    %fs:0x28,%rax
   0x00000000000012e5 <+97>:    jne    0x12ee <phase_2+106>
   0x00000000000012e7 <+99>:    add    $0x28,%rsp
   0x00000000000012eb <+103>:   pop    %rbx
   0x00000000000012ec <+104>:   pop    %rbp
  • push %rbppush %rbx:保存 rbprbx 寄存器的值。
  • sub $0x28,%rsp:为局部变量分配 40 字节的栈空间。
  • mov %fs:0x28,%rax:从 fs 段寄存器中读取栈保护值。
  • mov %rax,0x18(%rsp):将栈保护值保存到栈中。
  • xor %eax,%eax:将 eax 寄存器清零。
  • mov %rsp,%rsi:将栈指针传递给 rsi,作为 read_six_numbers 函数的参数。
  • callq 0x1ab4 <read_six_numbers>:调用 read_six_numbers 函数,读取六个数字并存储在栈中。
  • cmpl $0x0,(%rsp):比较第一个数字是否为 0。
  • jne 0x12af <phase_2+43>:如果第一个数字不为 0,跳转到 0x12af,调用 explode_bomb
  • cmpl $0x1,0x4(%rsp):比较第二个数字是否为 1。
  • je 0x12b4 <phase_2+48>:如果第二个数字为 1,跳转到 0x12b4
  • callq 0x1a78 <explode_bomb>:如果条件不满足,调用 explode_bomb
  • mov %rsp,%rbx:将栈指针保存到 rbx
  • lea 0x10(%rbx),%rbp:计算 rbp 的值,指向第六个数字。
  • jmp 0x12c6 <phase_2+66>:跳转到循环开始处。
  • add $0x4,%rbx:将 rbx 加 4,指向下一个数字。
  • cmp %rbp,%rbx:比较 rbxrbp,检查是否到达第六个数字。
  • je 0x12d7 <phase_2+83>:如果到达第六个数字,跳转到 0x12d7
  • mov 0x4(%rbx),%eax:将下一个数字保存到 eax
  • add (%rbx),%eax:将当前数字加到 eax
  • cmp %eax,0x8(%rbx):比较 eax 和下一个数字。
  • je 0x12bd <phase_2+57>:如果相等,跳转到 0x12bd,继续循环。
  • callq 0x1a78 <explode_bomb>:如果不相等,调用 explode_bomb
  • mov 0x18(%rsp),%rax:从栈中恢复栈保护值。
  • xor %fs:0x28,%rax:检查栈保护值是否被修改。
  • jne 0x12ee <phase_2+106>:如果栈保护值被修改,跳转到 0x12ee
  • add $0x28,%rsp:恢复栈指针。
  • pop %rbxpop %rbp:恢复 rbxrbp 寄存器的值。

可以看出来是反汇编代码是一段斐波那契数列

相关推荐
程序员小崔日记2 小时前
20块钱注册一年 .COM 域名!Spaceship 最新优惠教程,支付宝即可付款(附优惠码)
服务器·腾讯云·域名
IKUN家族2 小时前
Spring MVC(一)
java·spring·mvc
实心儿儿3 小时前
Linux —— 进程间关系和守护进程
linux·运维·服务器
林浅不想努力3 小时前
LVS知识点总结
服务器·云原生·lvs
石小石Orz3 小时前
我发现了开发者AI产品营收的新方向
前端·虚拟现实
老马识途2.04 小时前
关于跨域问题的总结
java·前端
Dawn-bit4 小时前
Linux磁盘管理详解
linux·运维·服务器·计算机网络·云计算
都叫我大帅哥4 小时前
Java日期时间三十年战争:从Date考古到LocalDateTime革命,以及数据库与前端的那点事儿
java
Muscleheng4 小时前
SpringBoot 集成 DeepSeek 实现 RAG 文档问答
java·spring boot·ai·springai
2501_936415695 小时前
可变参数&综合练习&斗地主游戏
java·windows·游戏