深入理解计算机系统 BombLab 实验报告
又快有一个月没写博客了,最近在看《深入理解计算机系统》这本书,目前看完了第三章,看完这章,对程序的机器级表示算是有了一个入门,也对 C 语言里函数栈帧有了一个初步的理解。
为了加深对书本内容的认识,以后每学习完一部分章节,就完成相应书本附带的实验题目。
第三章对应的实验是 BombLab,下面是我做这个实验的过程。
BombLab 分为 6 个普通关卡和一个隐形关卡,为了开始闯关,得先弄清楚从哪里开始行动。
首先使用 objdump 命令 objdump -t bomb > bomb_symboltable 来生成 bomb 文件的符号表(部分),如下:
bomb: file format elf64-x86-64 SYMBOL TABLE:
0000000000400238 l d .interp 0000000000000000 .interp
0000000000400254 l d .note.ABI-tag 0000000000000000 .note.ABI-tag
0000000000400274 l d .note.gnu.build-id 0000000000000000 .note.gnu.build-id
0000000000400298 l d .gnu.hash 0000000000000000 .gnu.hash
00000000004002c8 l d .dynsym 0000000000000000 .dynsym
00000000004005c8 l d .dynstr 0000000000000000 .dynstr
0000000000400736 l d .gnu.version 0000000000000000 .gnu.version
...
...
...
...
...
0000000000000000 F *UND* 0000000000000000 __ctype_b_loc@@GLIBC_2.3
0000000000603750 g O .bss 0000000000000008 stderr@@GLIBC_2.2.5
0000000000000000 F *UND* 0000000000000000 __sprintf_chk@@GLIBC_2.3.4
0000000000000000 F *UND* 0000000000000000 socket@@GLIBC_2.2.5
这个文件内容太多,我们只提取出含有关键字 bomb 的行,如下:
0000000000000000 l df *ABS* 0000000000000000 bomb.c
00000000004013ba g F .text 0000000000000002 initialize_bomb_solve
000000000040143a g F .text 0000000000000022 explode_bomb
000000000060375c g O .bss 0000000000000004 bomb_id
00000000004013a2 g F .text 0000000000000018 initialize_bomb
其中 000000000040143a g F .text explode_bomb 这一行就是用来引爆炸弹用的,我们可以先记住这个地址,以备用。
下面我们再对 bomb 文件进行反汇编,使用命令 objdump -d bomb > bomb_disassamble 可以得到 bomb 文件的反汇编文件,由于文件内容太多,这里就不全部贴出来了,在接下来的闯关中,会陆陆续续的讲这个文件中的一些汇编贴出来使用。
有了这些准备条件,下面我们开始闯关!
注意:接下来所有贴出来的函数的反汇编代码,都可以通过对 bomb 文件进行反汇编得到。
第一关:
0000000000400ee0 <phase_1>:
400ee0: ec sub $0x8,%rsp
400ee4: be mov $0x402400,%esi
400ee9: e8 4a callq <strings_not_equal>
400eee: c0 test %eax,%eax
400ef0: je 400ef7 <phase_1+0x17>
400ef2: e8 callq 40143a <explode_bomb>
400ef7: c4 add $0x8,%rsp
400efb: c3 retq
首先看第一条指令 sub $0x8,%rsp,这条指令用来分配 8 字节的函数栈帧,指令 mov $0x402400,%esi ,则将立即数 0x402400 传入寄存器 %esi 中,然后调用 strings_not_equal 这个函数, test %eax,%eax 这条指令判断寄存器 %eax 里是否为 0,如果为 0,则直接跳到 add $0x8,%rsp ,将函数指针加 8,释放栈帧。如果不为 0,则执行 callq 40143a <explode_bomb> ,引爆炸弹。
下面对 strings_not_equal 函数的反汇编代码进行分析:
<strings_not_equal>:
: push %r12
40133a: push %rbp
40133b: push %rbx
40133c: fb mov %rdi,%rbx
40133f: f5 mov %rsi,%rbp
: e8 d4 ff ff ff callq 40131b <string_length>
: c4 mov %eax,%r12d
40134a: ef mov %rbp,%rdi
40134d: e8 c9 ff ff ff callq 40131b <string_length>
: ba mov $0x1,%edx
: c4 cmp %eax,%r12d
40135a: 3f jne 40139b <strings_not_equal+0x63>
40135c: 0f b6 movzbl (%rbx),%eax
40135f: c0 test %al,%al
: je <strings_not_equal+0x50>
: 3a cmp 0x0(%rbp),%al
: 0a je <strings_not_equal+0x3a>
: eb jmp 40138f <strings_not_equal+0x57>
40136a: 3a cmp 0x0(%rbp),%al
40136d: 0f 1f nopl (%rax)
: jne <strings_not_equal+0x5e>
: c3 add $0x1,%rbx
: c5 add $0x1,%rbp
40137a: 0f b6 movzbl (%rbx),%eax
40137d: c0 test %al,%al
40137f: e9 jne 40136a <strings_not_equal+0x32>
: ba mov $0x0,%edx
: eb jmp 40139b <strings_not_equal+0x63>
: ba mov $0x0,%edx
40138d: eb 0c jmp 40139b <strings_not_equal+0x63>
40138f: ba mov $0x1,%edx
: eb jmp 40139b <strings_not_equal+0x63>
: ba mov $0x1,%edx
40139b: d0 mov %edx,%eax
40139d: 5b pop %rbx
40139e: 5d pop %rbp
40139f: 5c pop %r12
4013a1: c3 retq
由于 strings_not_equal 函数会用到 string_length 函数,所以将 string_length 函数的反汇编代码一并贴出来:
000000000040131b <string_length>:
40131b: 3f cmpb $0x0,(%rdi)
42 40131e: je <string_length+0x17>
: fa mov %rdi,%rdx
: c2 add $0x1,%rdx
: d0 mov %edx,%eax
: f8 sub %edi,%eax
40132b: 3a cmpb $0x0,(%rdx)
40132e: f3 jne <string_length+0x8>
49 : f3 c3 repz retq
: b8 mov $0x0,%eax
: c3 retq
代码 2 ~ 4 行先保存相关的寄存器值。
代码 5 ~ 6 行将传给函数的参数保存进寄存器中。
看到这里,也许能得到两个合理的猜想:
- strings_not_equal 函数用来比较两个字符串是否相等,这个函数的一个参数就是在函数调用前,通过 mov $0x402400,%esi 这条指令来指定,也许 0x402400 这个值就是已经存放在内存中的某个字符串的首地址(只是猜想)。
- strings_not_equal 函数的第二个参数是通过 %rdi 来指定,可能就是我们输入的字符串的首地址。
如果是这样的话,那 0x402400 这个地址处存放的字符串就是 phase_1 的答案。
下面我们通过 GDB 来验证我们的猜想。
首先使用 gdb bomb 来启动我们需要调试的程序 bomb(前提是这个程序由 gcc bomb.c -g -o bomb 生成)。
命令行进入下面的模式:
这是我们再输入:
break explode_bomb
break phase_1
来为程序设置相应的断点。
然后执行 run 来运行,程序会在第一个断点处停下,这时需要我们输入一个字符串,由于只是来验证猜想,先随便输入一个字符串,接着会到达第二个断点处,如下:
接下来我们使用 stepi 命令来单步执行,使用 disas 命令可以查看我们当前执行到什么地方,最后使用 print 命令来查看寄存器相关的信息,如下:
所以字符串Border relations with Canada have never been better.就是 phase_1 最终的答案。
第二关
这是 phase_2 的反汇编代码:
0000000000400efc <phase_2>:
400efc: push %rbp
400efd: push %rbx
400efe: ec sub $0x28,%rsp
400f02: e6 mov %rsp,%rsi
400f05: e8 callq 40145c <read_six_numbers>
400f0a: 3c cmpl $0x1,(%rsp)
400f0e: je 400f30 <phase_2+0x34> # 满足条件,跳转到 20 行
400f10: e8 callq 40143a <explode_bomb> # 不满足,直接引爆炸弹
400f15: eb jmp 400f30 <phase_2+0x34>
400f17: 8b fc mov -0x4(%rbx),%eax
400f1a: c0 add %eax,%eax
400f1c: cmp %eax,(%rbx)
400f1e: je 400f25 <phase_2+0x29> # 满足条件,跳转到 16 行
400f20: e8 callq 40143a <explode_bomb> # 不满足,则引爆炸弹
400f25: c3 add $0x4,%rbx
400f29: eb cmp %rbp,%rbx
400f2c: e9 jne 400f17 <phase_2+0x1b> # 满足条件,跳转到 11 行
400f2e: eb 0c jmp 400f3c <phase_2+0x40> # 不满足,跳转到 23 行
400f30: 8d 5c lea 0x4(%rsp),%rbx
400f35: 8d 6c lea 0x18(%rsp),%rbp
400f3a: eb db jmp 400f17 <phase_2+0x1b>
400f3c: c4 add $0x28,%rsp
400f40: 5b pop %rbx
400f41: 5d pop %rbp
400f42: c3 retq
函数功能分析:
这个函数先保存相应的寄存器(第 2 ~ 3 行),接着为函数分配 0x28 字节的栈帧(第 4 行),
这是 read_six_numbers 的反汇编代码:
000000000040145c <read_six_numbers>:
40145c: ec sub $0x18,%rsp
: f2 mov %rsi,%rdx
: 8d 4e lea 0x4(%rsi),%rcx
: 8d lea 0x14(%rsi),%rax
40146b: mov %rax,0x8(%rsp)
: 8d lea 0x10(%rsi),%rax
: mov %rax,(%rsp)
: 4c 8d 4e 0c lea 0xc(%rsi),%r9
40147c: 4c 8d lea 0x8(%rsi),%r8
: be c3 mov $0x4025c3,%esi
: b8 mov $0x0,%eax
40148a: e8 f7 ff ff callq 400bf0 <__isoc99_sscanf@plt>
40148f: f8 cmp $0x5,%eax
: 7f jg <read_six_numbers+0x3d> # 满足条件则跳转到 17 行
: e8 a1 ff ff ff callq 40143a <explode_bomb>
: c4 add $0x18,%rsp
40149d: c3 retq
函数功能分析:
范德萨发
深入理解计算机系统 BombLab 实验报告的更多相关文章
- 《深入理解计算机系统》实验一 —Data Lab
本文是CSAPP第二章的配套实验,通过使用有限的运算符来实现正数,负数,浮点数的位级表示.通过完成这13个函数,可以使我们更好的理解计算机中数据的编码方式. 准备工作 首先去官网Lab Assig ...
- 《深入理解计算机系统》实验二 —— Bomb Lab
这是CSAPP的第二个实验,主要让我们理解代码的机器级表示,最重要的是理解每个寄存器的作用以及如何使用这些寄存器.本次的实验内容有点晦涩难懂,对于这些内容多看下习惯就好了. 本次实验中的bomb文 ...
- 《深入理解计算机系统》实验三 —— Buf Lab
这是CSAPP的第三个实验,主要让我们熟悉GDB的使用,理解程序栈帧的结构和缓冲区溢出的原理. 实验目的 本实验的目的在于加深对IA-32函数调用规则和栈结构的具体理解.实验的主要内容是对一个可执 ...
- 深入理解计算机系统 (CS:APP) 缓冲区漏洞实验 – Buffer Lab 解析
原文地址:https://billc.io/2019/05/csapp-cachelab/ 写在前面 这是 CSAPP 官网上的第 4 个实验 buflab,也是学校要求的第三个实验.这个实验比上一个 ...
- 第五次实验报告:使用Packet Tracer理解OSPF路由协议
目录 1 实验目的 2 实验内容 3. 实验报告 3.1 建立网络拓扑结构 4. 配置 4.1 配置并激活串行地址和以太网地址 4.1.1 R1 4.1.2 R2 4.1.3 R3 4.1.4 PC ...
- 第四次实验报告:使用Packet Tracer理解RIP路由协议
目录 1 实验目的 2 实验内容 3. 实验报告 3.1 建立网络拓扑结构 3.2 配置参数 3.3 测试网络连通性 3.4 理解RIP路由表建立和更新 4. 理解RIP消息传得慢 5. 拓展 1 实 ...
- CS:APP3e 深入理解计算机系统_3e ShellLab(tsh)实验
详细的题目要求和资源可以到 http://csapp.cs.cmu.edu/3e/labs.html 或者 http://www.cs.cmu.edu/~./213/schedule.html 获取. ...
- 北京电子科技学院(BESTI)实验报告1
北京电子科技学院(BESTI)实验报告1 课程: 信息安全系统设计基础 班级:1452.1453 姓名:(按贡献大小排名)郑凯杰 .周恩德 学号:(按贡献大小排名)20145314 .20145217 ...
- 实验二实验报告 20135324&&20135330
北京电子科技学院(BESTI) 实 验 报 告 课程: 深入理解计算机系统 班级: 1353 姓名: 杨舒雯 张若嘉 学号: 20135324 20135330 成绩: 指导教师: 娄嘉鹏 实验日期: ...
随机推荐
- JavaScript动态广告弹出框
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 使用Toast进行用户提醒(转)
Toast是Android提供的一个轻量级的用户提醒控件,使用也很简单,就相当一个极简的dialog!!!下面将向您介绍一些Toast的详细用法: 1.普遍使用的方法: Context context ...
- Gamma 函数与exponential power distribution (指数幂分布)
1. Γ(⋅) 函数 Γ(α)=∫∞0tα−1e−tdt 可知以下基本性质: Γ(α+1)=αΓ(α) Γ(1)=1 ⇒ Γ(n+1)=n! Γ(12)=π√ 2. 指数幂分布(exponential ...
- matlab Tricks(二十七)—— 可变输入参数输出参数的适配
matlab 内置的对 varargin/varargout(nargin/nargout)的支持,使得 matlab 的输入参数和输出参数,有了更为灵活的传递和使用: 比如对于 matlab 原生支 ...
- 图解Http协议 url长度限制
http请求报文的格式 一般请求所带有的属性: http响应报文的格式: 响应首部一般包含如下内容: 一.技术基石及概述 问:什么是HTTP? 答:HTTP是一个客户端和服务器端请求和响应的标准TCP ...
- 静态库、动态库,dll文件、lib文件,隐式链接、显式链接浅见
静态链接.动态链接 静态库和动态库分别应用在静态链接方式和动态链接方式中,所谓静态链接方式是指在程序执行之前完成所有的链接工作,把静态库一起打包合入,生成一个可执行的目标文件(EXE文件).所谓动态链 ...
- NS2网络模拟(2)-丢包率
1: #NS2_有线部分\LossRate.awk 2: 3: BEGIN { 4: #Initialize the variable 5: Lost = 0; #the Sum of Lost pa ...
- WPF之VLC流媒体播放
原文:WPF之VLC流媒体播放 最近在做关于在WPF使用VLC流媒体播放的问题,现在可以在WPF中实现VLC本地播放了,流播放解决了,在下面的代码中注释流媒体播放那两段代码,更多的在乎大家摸索了^^, ...
- android viewpager fragment切换时界面卡顿解决办法
目前开发的程序在切换View时界面卡顿现象比较严重,影响用户体验,当前项目共就四个View,每个View也只是按钮,所以可以同时加载,不让其它view销毁. 只需在Adapter中重载destroyI ...
- 【iOS发展-89】UIGestureRecognizer完整的旋转手势识别、缩放和拖拽等效果
(1)效果 (2)代码 http://download.csdn.net/detail/wsb200514/8261001 (3)总结 --先依据所需创建不同类型的手势识别.比方: UITapGest ...