这个lab主要考察gdb的使用和对汇编代码的理解。后者在平时的作业中涉及得较多,这里不再赘述,主要介绍一下gdb。其实偶对这个也不是很熟,有错误请指正。

简单的说,gdb是一款强大的调试工具,尽管它只有文本界面(需要图形界面可以使用ddd,不过区别不大),但是功能却比eclipse等调试环境强很多。

接下来看看怎样让它为lab2拆炸弹服务,在命令行下运行gdb bomb就能开始调试这个炸弹程序,提高警惕,恩。

首先最重要的,就是如何阻止炸弹的引爆,gdb自然提供了一般调试工具都包括的断点功能——break命令。

在gdb中输入help break能够看到相关的信息。

可以看到 break 允许我们使用行号、函数名或地址设置断点。

ctrl+z暂时挂起当前的gdb进程,运行 objdump –d bomb | more 查看反编译后的炸弹文件,可以看到里面有这么一行(开始的那个地址每个人都不同):

08049719 <explode_bomb>:

这个就是万恶的引爆炸弹的函数了,运行 fg 返回 gdb 环境,在这个函数设置断点:break explode_bomb (可以使用tab键自动补齐)

显示

Breakpoint 1 at 0x8049707

接下来你可以喘口气,一般情况下炸弹是不会引爆的了

下面我们来拆第一个炸弹,首先同样是设置断点,bomb.c中给出了各个关卡的函数名,第一关就是phase_1,使用break phase_1在第一关设置断点

接下来就开始运行吧,输入run

我们已经设置了炸弹断点,这些恐吓可以直接无视。

输入ABC继续(输入这个是为了方便在后面的测试中找到自己的输入串地址)

提示Breakpoint 2, 0x08048c2e in phase_1 (),说明现在程序已经停在第一个关了

接下来就是分析汇编代码,使用disassemble phase_1显示这个函数的汇编代码

注意其中关键的几行:

这个lab很厚道的一点就是函数名很明确地说明了函数的功能 ^_^

估计这三行代码的意思就是比较两个字符串相等,不相等的话应该就会让炸弹爆炸了

因为字符串很大,所以传递给这个比较函数的肯定是他们的地址,分别为0x80499b4和0x8(%ebp)

我们先来看后者,使用p/x *(int*)($ebp + 8)查看字符串所在的地址

$1 = 0x804a720
````

继续使用`p/x *0x804a720`查看内存中这个地址的内容

$2 = 0x434241


连续的三个数,是不是想起什么了?把这三个数分别转换为十进制,就是67 66 65,分别为 CBA 的 ASCII 码,看来这里保存了我们输入的串。

接下来 0x80499b4 里肯定保存着过关的密码 `p/x *0x80499b4`

$3 = 0x62726556


c中的字符串是以0结尾的,看来这个字符串还不止这个长度,继续使用

`p/x *0x80499b4@10` 查看这个地址及其后面36个字节的内容,终于在第二行中出现了终结符”0x0”(不一定是四个字节)

$4 = {0x62726556, 0x7469736f, 0x656c2079, 0x20736461, 0x75206f74, 0x656c636e, 0x202c7261, 0x72616e69, 0x75636974, 0x6574616c, 0x69687420, 0x2e73676e, 0x0, 0x21776f57, 0x756f5920, 0x20657627, 0x75666564, 0x20646573, 0x20656874, 0x72636573}


把开头到0x0的所有信息字节下来,通过手算或者自己写程序得出最后的密码串(注意little endian中字符的排列方式!)

输入run重新运行,输入刚才得出的密码串,如果前面的计算正确的话,就会提示

Phase 1 defused. How about the next one?


关于这个lab的一些其他心得:

1. VMware中开发很不舒服,屏幕小、字体丑@@、需要Ctrl+Alt切换回windows,不怎么方便,推荐在windows下使用pietty登录虚拟机中的linux系统(RedHat 9默认安装了sshd),个人觉得这样比较方便。

2. ASCII查询可以在linux终端中运行man ascii。

3. 退出gdb后,再次进入时一定要注意使用break给explode_bomb上断点,不可大意 ~.~

4. 后面的几关涉及递归等内容,也有和前面几次作业很相似的东东。

5. gdb中还有一个很好用的jump指令,可以在运行时任意跳转。
  
6. 看汇编代码时,使用`objdump -d bomb > bomb.asm`把汇编代码保存到bomb.asm中,然后使用sftp工具把这个文件下载到windows或者直接在vim中查看,这样比在gdb中看方便一些。

7. 个人认为lab2和期中考试不冲突,这个lab2可以帮你理清很多汇编语言的概念

其他补充:

sfox:
可以通过GDB中的<u>x /s addr</u>输出以\0结尾的字符串

ICSLab:
为了防止每次拆的时候都不停的输入之前的stage的key,可以把key存入文本文件,一行一个key,不要有多余字符

然后GDB run 的时候用`gdb bomb`

(gdb) b … … (gdb) r password.txt ``` 这样bomb就会自动从password.txt中读入之前的密码直到到达最后一个空行处,如Lab2的说明文档中所述。