今天开始解决逆向工程拆除“二进制炸弹”的前两道题目,对 汇编的一些语句进行了了解,觉得还是有些难度。
准备知识
- 将bomb全部反汇编命令:objdump -d bomb>1.txt
- 1.txt可以用notepad++打开,选择语言为A->assembly,则带有颜色区别,也可以进行搜索查询,比较方便。
- 了解gdb调试命令:r、k、c、q、si、s、b、delete
- 汇编基本指令:
- Je 相等时跳转
- Jg 大于时跳转
- Jl 小于时跳转
- Ja 无符号数大于时跳转
- eax 常用于保存返回值
- ecx 常用于计数
- edi 目的变址
- ebx 基址
- esi 源变址
gdb的使用
-
我尝试性地用gdb调试了一下,进入bomb的上一层目录就是bomb3后,输入 gdb bomb,没有找到gdb,根据提示安装gdb
-
安装完gdb之后,-q进入gdb调试
phase_1
-
用Notepad打开汇编代码,首先要解决的问题是phase_1,用ctrl+F查找phase_1;
-
b phase_1在调用phase_1()函数前设置断点,然后用命令 r运行程序
-
输入 b *0x804c16a(炸弹所在地址,第二行),回车显示断点设好了。
-
现在就可以gdb run跑起来了,或者q退出
-
从上述的汇编代码可以推出,%eax用来保存输入的字符串。如果输入的字符串与内存0x804a16c处的字符串相同,炸弹就不会爆炸,可以进入到第二个函数,完成第一个函数的破解!
所以,只需要查看0x804a16c处的字符串。
-
用命令查看 0x804a16这个地址存放的值,s代表用字符串的形式读取数据。
-
输入之后,成功了。
phase_2
在Notepad中找到phase_2的汇编代码部分:
-
栈开辟代码部分
-
然后看到一个非常显眼的函数调用:read_six_numbers 可以判断应该是输入6个数字。lea是加载有效地址的指令,就相当于c语言中的&,在这里结合栈是向小地址生长的,后进的放在小地址先被弹出,在此处应该是将输入的第一个数字放在了-0x18(%ebp)的地方。
-
在这里第一个数跟1进行比较,也就是第一个数要为1才不会爆炸。所以第一个数字为1。
-
esi出现一般会是循环或者数组中的变址,在此处考虑是循环的结束条件。第二句是取第二个数,第三句是将第一个数与第一个数相加,第四句是比较第一个数的两倍与第二个数的关系。比较是否6个数结束了,没有则跳到0x8048bdb。
-
后一个输入的数字是前一个输入数字的两倍,得到数字:1 2 4 8 16 32,尝试成功!