这是《深入理解计算机系统(第3版)》的配套实验,实验相关的代码和说明可以从官网下载。
选择BombLab作为开始,是因为做PWN的时候屡屡因为GDB使用不熟练而无从下手(对,哪怕有WP还是搞不定)。吐槽一下,如果有GDB的文档就能熟练使用,就好像拿到一本汽车的使用说明书就能考过驾照一样。所以选择了通过CSAPP的实验加强对GDB的使用。
环境与工具
- Ubuntu 16.04
- 安装了GDB的插件peda
phase_1
首先在phase_1处下一个断点:
b phase_1
看一下phase_1的反汇编代码:
gdb-peda$ disas phase_1
Dump of assembler code for function phase_1:
0x0000000000400ee0 <+0>: sub rsp,0x8
0x0000000000400ee4 <+4>: mov esi,0x402400 #用于和输入做比较的字符串地址
0x0000000000400ee9 <+9>: call 0x401338 <strings_not_equal>
0x0000000000400eee <+14>: test eax,eax #<strings_not_equal>的返回值为0
0x0000000000400ef0 <+16>: je 0x400ef7 <phase_1+23>
0x0000000000400ef2 <+18>: call 0x40143a <explode_bomb>
0x0000000000400ef7 <+23>: add rsp,0x8
0x0000000000400efb <+27>: ret
End of assembler dump.
<+4>的一行,esi寄存器存入了一个地址,该地址中是用于在中比较的字符串。用GDB的x命令查看一下:
gdb-peda$ x/s 0x402400
0x402400: "Border relations with Canada have never been better."
新建一个./input.txt,第一行输入:
Border relations with Canada have never been better.
在gdb中设置从该文件输入:
gdb-peda$ set args ./input.txt
重新运行
gdb-peda$ r
Starting program: /mnt/hgfs/pwn/csapp/bombLab/bomb ./input.txt
Welcome to my fiendish little bomb. You have 6 phases with
which to blow yourself up. Have a nice day!
Phase 1 defused. How about the next one?
phase_1的Bomb拆除!
phase_2
看一下代码:
gdb-peda$ disas phase_2
Dump of assembler code for function phase_2:
0x0000000000400efc <+0>: push rbp
0x0000000000400efd <+1>: push rbx
0x0000000000400efe <+2>: sub rsp,0x28 #rsp是存储6个数字的栈顶
0x0000000000400f02 <+6>: mov rsi,rsp
0x0000000000400f05 <+9>: call 0x40145c <read_six_numbers> #读入6个数字
0x0000000000400f0a <+14>: cmp DWORD PTR [rsp],0x1 #第一个数字为1
0x0000000000400f0e <+18>: je 0x400f30 <phase_2+52>
0x0000000000400f10 <+20>: call 0x40143a <explode_bomb>
0x0000000000400f15 <+25>: jmp 0x400f30 <phase_2+52>
0x0000000000400f17 <+27>: mov eax,DWORD PTR [rbx-0x4] #循环体:开始
0x0000000000400f1a <+30>: add eax,eax #将上一个数字乘2
0x0000000000400f1c <+32>: cmp DWORD PTR [rbx],eax
0x0000000000400f1e <+34>: je 0x400f25 <phase_2+41>
0x0000000000400f20 <+36>: call 0x40143a <explode_bomb>
0x0000000000400f25 <+41>: add rbx,0x4 #rbx加4,取下一个数字
0x0000000000400f29 <+45>: cmp rbx,rbp #判断是否已经将6个数字做比较
0x0000000000400f2c <+48>: jne 0x400f17 <phase_2+27> #循环体:结束
0x0000000000400f2e <+50>: jmp 0x400f3c <phase_2+64>
0x0000000000400f30 <+52>: lea rbx,[rsp+0x4]
0x0000000000400f35 <+57>: lea rbp,[rsp+0x18] #rbp留出6个数字的空间
0x0000000000400f3a <+62>: jmp 0x400f17 <phase_2+27>
0x0000000000400f3c <+64>: add rsp,0x28 #退出phase_2
0x0000000000400f40 <+68>: pop rbx
0x0000000000400f41 <+69>: pop rbp
0x0000000000400f42 <+70>: ret
End of assembler dump.
在./input.txt的第2行输入:
1 2 4 8 16 32
重新运行
gdb-peda$ r
Starting program: /mnt/hgfs/pwn/csapp/bombLab/bomb ./input.txt
Welcome to my fiendish little bomb. You have 6 phases with
which to blow yourself up. Have a nice day!
Phase 1 defused. How about the next one?
That's number 2. Keep going!
phase_2的Bomb拆除!
phase_3
gdb-peda$ disas phase_3
Dump of assembler code for function phase_3:
0x0000000000400f43 <+0>: sub rsp,0x18
0x0000000000400f47 <+4>: lea rcx,[rsp+0xc] #存放读取的第二个数字
0x0000000000400f4c <+9>: lea rdx,[rsp+0x8] #存放读取的第一个数字
0x0000000000400f51 <+14>: mov esi,0x4025cf #0x4025cf: "%d %d"
0x0000000000400f56 <+19>: mov eax,0x0
0x0000000000400f5b <+24>: call 0x400bf0 <__isoc99_sscanf@plt>
0x0000000000400f60 <+29>: cmp eax,0x1
0x0000000000400f63 <+32>: jg 0x400f6a <phase_3+39> #读取数字的个数大于1
0x0000000000400f65 <+34>: call 0x40143a <explode_bomb>
0x0000000000400f6a <