bomblab 的博客、视频挺多的,但是步骤都太“友善”了。既然每次都是 explode_bomb
函数爆炸的,那么不执行这个函数不就完事儿了吗?这的确是“作弊”,但是我的目的不在于得到每一个 phase 的正确答案, 而是希望每个 phase 随便输入,但是仍然能通关。
一种方式是修改二进制文件 bomb
, 我暂时不会。
另一种方式,是在 gdb 运行期间, 使用 set
命令修改 call explode_bomb
汇编指令为 nop
指令,那么程序就能继续往下运行, 而不是由于 explode_bomb()
中的 call exit
导致结束。本篇讲使用set
的具体做法。
文章目录
1. 最小例子
直接修改 call explode_bomb() 的过程,过于庞大。先弄懂这个简化的例子,其他都能搞定:
test2.c:
#include <stdio.h>
#include <stdlib.h>
static void die()
{
printf("You lose\n");
exit(1);
}
static void congrat()
{
printf("You win!\n");
return;
}
int main()
{
die();
congrat();
return 0;
}
正常执行 test.c, 会看到 “You lose”。我们希望在gdb里做手脚,使得gdb里能够看到 “You Win!” 的输出。
关键命令:
set {
char[5]}0x00005555555551b1={
0x90,0x90,0x90,0x90,0x90}
完整命令
(gdb) start
Temporary breakpoint 1 at 0x11ac
Starting program: /home/zz/work/zcnn/csapp/bomblab/a.out
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Temporary breakpoint 1, 0x00005555555551ac in main ()
(gdb) disassemble
Dump of assembler code for function main:
0x00005555555551a4 <+0>: endbr64
0x00005555555551a8 <+4>: push rbp
0x00005555555551a9 <+5>: mov rbp,rsp
=> 0x00005555555551ac <+8>: mov eax,0x0
0x00005555555551b1 <+13>: call 0x555555555169 <die>
0x00005555555551b6 <+18>: mov eax,0x0
0x00005555555551bb <+23>: call 0x55555555518a <congrat>
0x00005555555551c0 <+28>: mov eax,0x0
0x00005555555551c5 <+33>: pop rbp
0x00005555555551c6 <+34>: ret
End of assembler dump.
(gdb) ni
0x00005555555551b1 in main ()
(gdb) disassemble
Dump of assembler code for function main:
0x00005555555551a4 <+0>: endbr64
0x00005555555551a8 <+4>: push rbp
0x00005555555551a9 <+5>: mov rbp,rsp
0x00005555555551ac <+8>: mov eax,0x0
=> 0x00005555555551b1 <+13>: call 0x555555555169 <die>
0x00005555555551b6