计组实验-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 %rbp 和 push %rbx:保存 rbp 和 rbx 寄存器的值。
  • 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:比较 rbx 和 rbp,检查是否到达第六个数字。
  • 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 %rbx 和 pop %rbp:恢复 rbx 和 rbp 寄存器的值。

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

相关推荐
honsor几秒前
以太网温湿度传感器|动环监控核心采集设备,协议、组网、Zabbix接入实战
linux·服务器·ubuntu
Android系统攻城狮几秒前
Linux FFmpeg深度解析之avcodec_default_get_buffer2调用流程与实战(二十)
linux·运维·服务器·ffmpeg·音视频进阶·ffmpeg音视频
十碗阳春面5 分钟前
阿里云 Ubuntu 22.04 部署 Flarum 论坛:从空白服务器到中文界面、公网 IP 访问
服务器·ubuntu·阿里云
十二同学啊5 分钟前
Python 工程化详解:项目结构、依赖管理、代码质量、测试与部署
java·开发语言·python
YIN_尹9 分钟前
【git原理与使用】git基本操作及底层原理(一)
java·git·elasticsearch
Android系统攻城狮10 分钟前
Linux FFmpeg深度解析之av_parser_init调用流程与实战(二十一)
linux·运维·服务器·ffmpeg·音视频进阶·ffmpeg音视频
Ramble_Naylor19 分钟前
Rust深度解读:高性能 Web 网关与 Axum 架构剖析
前端·架构·rust
程序员飞哥19 分钟前
AI 编程额度怎么用才不浪费?
java·前端·后端
柳杉20 分钟前
用 Codex 魔改卡神开源的 AIHOT,我做了个 3D 技术雷达
前端·aigc
王亚博_Abel22 分钟前
AI 编程时代怎么选前端框架?同一个应用让 Agent 用 12 种框架各写 5 遍,我整理出这套选型方法
前端·人工智能·前端框架