实验目的:进一步了解机器级代码,提高汇编语言、调试器和逆向工程等方面原理与技能的掌握。
实验环境:C、linux
实验获取:进入csapp官网,点击linux/x86-64 binary bomb下载实验压缩包。
实验说明:一共有6个关卡,每个关卡可以输入一串字符,只有输入正确才能拆出炸弹。
只有可执行程序,不知道六个关卡函数具体的代码都是什么。
可以应用反汇编技术把可执行程序转化为汇编程序。通过阅读汇编程序,推断出程序的具体作用,从而给出正确的密码输入。
sCS:APP3e, Bryant and O'Hallaron
解压:tar -xvf bomb.tar
从bomb.c可以看出phase_1接受一个输入,需要反汇编推测phase_1对input做了什么处理。
反汇编整个程序:
objdump -d bomb > bomb.txt
bomb.txt可以查看bomb的汇编代码
gdb进入调式模式
gdb bomb
在phase_1函数打断点
(gdb)break phase_1
运行到断点处
(gdb)run
可以看到断点在0x400ee0,从汇编文件中可以找到phase_1的汇编代码
此外,还可以在gdb中查看phase_1的汇编代码
disas phase_1
看到和%rsp和%rsi相关的,就是出栈和入栈相关的汇编代码
在使用 test %eax, %eax
指令后,通常会检查标志位,以确定 %eax
中的值是否为零。如果结果为零,则零标志位会被设置为 1,表示 %eax
中的值为零;如果结果不为零,则零标志位会被清除为 0,表示 %eax
中的值不为零。
如果%eax不为0,执行explode_bomb函数,所以只有当string_not_equal返回的值为0,才可以解开炸弹。
查看string_not_equal的汇编代码
- 该函数保存了一些寄存器的值(
%r12
、%rbp
、%rbx
)并将参数传递到寄存器中(%rdi
和%rsi
) - 两次调用
string_length
函数,分别计算了两个输入字符串的长度,将长度分别存储在%r12d
和%eax
中。 - 对比字符串长度,如果长度不相等 (
jne 40139b
),则直接返回 1,表示字符串不相等。 - 如果字符串长度相等,接着执行逐字符比较的部分: 首先检查
%rbx
指向的字符是否为字符串结束符(\0
),如果是,则直接返回 0,表示字符串相等。 如果不是结束符,则比较%rbx
和%rbp
指向的字符。如果不相等,立即返回 1,表示字符串不相等。如果相等,则继续比较下一个字符。循环执行字符比较的过程,直到找到不相等的字符或者两个字符串都到达结尾为止。最后,根据比较结果,将 1 或 0 存储在%eax
中作为返回值,表示字符串是否不相等。最后,恢复被保存的寄存器值,并通过ret
指令返回函数。
查看0x402400地址的值,就是要和输入比较的值。
炸弹一被拆除!