bomblab
bomblab
开始愉快的拆除炸弹吧,(bushi)
通过这次实验可以基本掌握gdb的使用,这次使用了pwndgb插件
可以使用objdump
查看反汇编程序,也可以在gdb
里使用disassemble反汇编
超详细的wpCSAPP | Lab2-Bomb Lab 深入解析 - 知乎 (zhihu.com)

pwndgb的基本指令
指令 | 效果 |
---|---|
s | 单步步入 |
n | 单步步过 |
r | 重新运行 |
c | 继续运行 |
i b, i r | 查看断点、寄存器 |
return | 退出当前函数 |
search 114514 | 查找114514 |
b *0x114514 , b fun_name | 在0x114514处下断点、在函数fun_name处下断点 |
delete ,delete 114514 | 删除所有断点,删除114514号断点 |
disassemble main | 反汇编main函数 |
vmmap | 显示进程的内存映射 |
cyclic 50 | 生成50个用来溢出的字符 |
cyclic -l 字符串 | 定位字符串再溢出字符的位置 |
p 0xffffceec-0xffffcf58 | 计算0xffffceec-0xffffcf58的值 |
phase_1

在phase_1处下断点b phase_1
,然后使用s
单步

发现传入四个参数,其中rdi寄存器存储我们输入的值,rsi寄存器存储着字符串。然后通过函数strings_not_equal
可以判断出函数是将这两个字符串进行比较,然后通过test eax, eax
对返回值进行判断
如果
eax
的值为零,则零标志位 (ZF) 将被设置为 1。如果
eax
的值非零,则零标志位 (ZF) 将被设置为 0.
当ZF
标志位为1时,跳转到phase_1+23
,否则调用explode——bomb

可以通过x/s
查看内存
显然,phase_1
的答案为Border relations with Canada have never been better.
phase_2
删除所有断点,进入phase2
,下断点,s
单步

进入read_six_numbers
函数

cmp eax, 5
应该是每成功处理一个输入,eax++。scanf函数返回已成功赋值的数据项数,返回值存储在eax寄存器。
eax==5即全部参数处理完毕,由此我们可以确定我们要输入六个参数。

然后继续分析phase_2
,直接disassemble phase_2

1 | cmp DWORD PTR [rsp],0x1 |
判断第一个字符是否为1,否则bomb!!
1 | add eax,eax |
每次输入的数就是前面数的两倍

从bomb.c 文件中可以看到,当输入两个命令行参数时,我们可以以一个文件作为输入,因此可以创建ans.txt文件作为输入

第一个参数为 /home/randolfluo/Desktop/csapp/bomb/bomb
第二个参数为 ans.txt
因此执行 argc为2的代码
phase_3


调用scanf函数,若已成功赋值的数据项数eax>1
成立,则jg
有符号大于则跳转,避开爆炸,因此必须要有三个输入
而我们从scanf函数的format中可以看到,输入了两个整型。但!回车就是第三个输入。

1 | 0x400f6a <phase_3+39> cmp dword ptr [rsp + 8], 7 |
判断第一个输入小于7,然后进行后续跳转
1 | 0x400f75 <phase_3+50> jmp qword ptr [rax*8 + 0x402470] <phase_3+118> |
通过你输入的第一个值来跳转不同验证代码,rax*8 + 0x402470
,查看0x402470处的内存,因为linux在x86-64是小端序。小端序意味着较低地址的字节排放在内存中的较低地址,而较高地址的字节排放在内存中的较高地址。

如果输入 1,则跳转到0x0000000000400fb9
则第二个数则0x137,化为十进制即311
phase_4
依然是输入两个整型,将phase_4反汇编一下
1 | Dump of assembler code for function phase_4: |

调用了fun
函数,,同时将第一个输入存放进%rdi
寄存器。
发现fun函数是个递归函数
。我们需要找到最快方式跳出循环
jle 0x400ff2
可以使用word
进行分析,其中不同颜色表示不同的跳转地址。

我们可以得出两个条件输入<=7
和输入>=7
,那么我们输入的第一个数为7
,所以我们的输入为7 0
phase5
再次使用word
大法

通过输入的字符串每个元素的低四位
来索引
字符串maduiersnfotvbylSo you think you can stop the bomb with ctrl-c, do you?
的值,最后与flyers
进行比较,相同则通关。

写个脚本
1 | array='maduiersnfotvbylSo you think you can stop the bomb with ctrl-c, do you?' |
phase_6
下次一定~