Bootstrap

CSAPP Bomb Lab实验全面解析(包含代码和具体分析)

一、实验目的

  1. 提升汇编语言逆向分析能力
  2. 理解程序控制流与内存管理的底层机制
  3. 掌握动态调试(GDB)与静态分析(objdump)结合的技术
  4. 培养解决复杂问题的系统性思维

二、实验环境

  • 操作系统:Ubuntu 22.04 LTS (64位)
  • 工具链
    • bomblab压缩包——下载bomblab压缩包并输入$ tar –xvf bomb.tar进行解压缩,下载地址:CS:APP3e, Bryant and O'Hallaron,点击handout即可下载(在虚拟机里面)

    • objdump 反汇编器——使用命令objdump -d bomb > bomb.asm将bomb变成asm文件则可以直接用vim打开修改
    • GDB 调试器 (版本 12.1)——在终端使用命令:sudo apt-get install gdb安装
    • hexedit 二进制查看工具

三、实验内容与详细分析

Phase_1:字符串匹配

反汇编代码关键片段
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>
破解步骤
  1. 定位字符串地址:通过mov $0x402400,%esi确定预设字符串存放地址

  2. 查看内存内容

    (gdb) x/s 0x402400
    -> "Border relations with Canada have never been better."
    
  3. 验证答案:输入该字符串即可通过

  4. 整体运行指令图(Ctrl+D可以退出gdb):


Phase_2:等比数列验证

反汇编代码关键逻辑
400f02:	83 7c 24 04 01       	cmpl   $0x1,0x4(%rsp)   ; 检查第一个数是否为1
400f0a:	39 d8               	cmp    %ebx,%eax        ; 比较当前数与前一个数×2
400f17:	83 c3 01            	add    $0x1,%ebx        ; 循环计数器递增
破解步骤
  1. 输入要求:6个整数组成的等比数列
  2. 数学关系:an=2×an−1an​=2×an−1​,初始值为1
  3. 答案示例1 2 4 8 16 32

Phase_3:跳转表与分支选择

反汇编代码关键逻辑
400f6a:	ff 24 c5 70 24 40 00 	jmpq   *0x402470(,%rax,8) ; 跳转表基地址
400f75:	b8 37 01 00 00       	mov    $0x137,%eax       ; 对应分支目标值
破解步骤
  1. 查看跳转表

    (gdb) x/8a 0x402470
    -> 0x400f7c, 0x400fb9, ...  # 各分支入口地址
    
  2. 分支匹配:选择第一个输入为1,对应第二个输入需为311(0x137)

  3. 答案示例1 311


Phase_4:递归函数终止

反汇编代码关键逻辑
40103e:	8d 7c 24 10         	lea    0x10(%rsp),%edi
401042:	e8 81 ff ff ff      	callq  400fc8 <func4>    ; 递归调用
401058:	83 f8 00            	cmp    $0x0,%eax        ; 要求返回值为0
破解步骤
  1. 递归分析func4需要返回0
  2. 输入验证:输入7 0可满足终止条件
  3. 栈帧查看
    (gdb) x/2wx $rsp+0x10  # 查看输入数值存储位置
    

Phase_5:字符映射转换

反汇编代码关键逻辑
40108b:	0f b6 0c 03         	movzbl (%rbx,%rax,1),%ecx  ; 取字符低4位
40108f:	88 0c 24            	mov    %cl,(%rsp)
401092:	48 8b 14 24         	mov    (%rsp),%rdx
401096:	83 e2 0f            	and    $0xf,%edx         ; 取低4位作为索引
401099:	0f b6 92 b0 24 40 00 	movzbl 0x4024b0(%rdx),%edx ; 查表
破解步骤
  1. 字符表查看

    (gdb) x/s 0x4024b0
    -> "maduiersnfotvbyl"
    
  2. 映射关系:输入字符ASCII码低4位对应表中字符

  3. 示例答案"9?>567"(映射结果为"ionefg")


Phase_6:链表节点排序

反汇编代码关键逻辑
4011ab:	8b 52 08            	mov    0x8(%rdx),%edx   ; 遍历链表节点
4011d7:	48 89 d1            	mov    %rdx,%rcx        ; 节点指针交换
4011f5:	41 89 04 94         	mov    %eax,(%r12,%rdx,4) ; 存储排序结果
破解步骤
  1. 链表结构分析

    (gdb) x/24wx 0x6032d0
    -> Node1: 0x14c (data), 0x6032e0 (next)
       Node2: 0x0a8 (data), 0x6032f0 (next)
    
  2. 排序要求:按节点data降序排列输入序号

  3. 答案示例4 3 2 1 6 5

总结果:

所有Phase完成之后的结果应该如下:


四、隐藏阶段触发方法

  1. 触发条件:在Phase_4答案后追加字符串"DrEvil"
  2. 调试验证
    (gdb) break secret_phase
    (gdb) x/s 0x402619  # 查看隐藏提示信息
    

五、实验总结

1. 关键技术收获

  • 逆向工程技能:通过反汇编与动态调试理解程序控制流
  • 内存分析能力:掌握查看寄存器、栈空间与全局数据区的方法
  • 算法逆向能力:从机器代码还原递归、循环等高级语言结构
  • 系统安全意识:理解缓冲区验证与输入过滤的重要性

2. 难点与突破

阶段核心难点解决方法
Phase3跳转表分支匹配结合内存查看与寄存器跟踪
Phase5字符映射关系推导ASCII码位运算分析
Phase6链表指针操作逻辑还原逐节点内存查看与数据对比

3. 实验意义

  • 教学价值:将抽象的汇编指令与具体的程序行为建立直接关联
  • 工程意义:培养从二进制层面诊断软件问题的能力
  • 安全启示:揭示输入验证不足导致的漏洞风险

附录:实验关键数据速查表

地址内容描述示例值/用途
0x402400Phase_1预设字符串"Border relations..."
0x402470Phase_3跳转表基地址分支入口地址列表
0x4024b0Phase_5字符映射表"maduiersnfotvbyl"
0x6032d0Phase_6链表起始节点Node1 {332, 0x6032e0}
;