CMU_CSAPP_LAB2_BOMBLAB

CSAPP第二章的第一个实验BombLab实验记录。

实验内容主要使用 gdb 、objdump 等指令在终端调试程序,利用反汇编查看各个函数运行的汇编代码,了解各个函数的执行过程。

附gdb指令精简手册:http://csapp.cs.cmu.edu/public/students.html


Phase_1

首先打开终端输入 gdb bomb 进入调试界面。

查看 phase_1 的汇编指令:

(gdb) disas phase_1
Dump of assembler code for function phase_1:
   0x0000000000400ee0 <+0>:	sub    $0x8,%rsp
   0x0000000000400ee4 <+4>:	mov    $0x402400,%esi
   0x0000000000400ee9 <+9>:	callq  0x401338 <strings_not_equal>
   0x0000000000400eee <+14>:	test   %eax,%eax
   0x0000000000400ef0 <+16>:	je     0x400ef7 <phase_1+23>
   0x0000000000400ef2 <+18>:	callq  0x40143a <explode_bomb>
   0x0000000000400ef7 <+23>:	add    $0x8,%rsp
   0x0000000000400efb <+27>:	retq   
End of assembler dump.

函数首先接收户输入的字符串,再将立即数 0x402400 输入到寄存器 esi ,接着调用函数<string_not_equal>,很容易猜到寄存器 esi 中保存了要和用户输入的字符串进行比较的字符串的首地址,即立即数 0x402400 。

(gdb) x/s 0x402400
0x402400:	"Border relations with Canada have never been better."

通过地址直接查看字符串,这就是我们需要输入的内容!

(gdb) run
Starting program: /home/liuyuan/Downloads/CSAPP/bomb/bomb 
Welcome to my fiendish little bomb. You have 6 phases with
which to blow yourself up. Have a nice day!
Border relations with Canada have never been better.
Phase 1 defused. How about the next one?

通过测试!

进一步细致理解函数运行过程:

将函数 phase_1 设置断点,运行程序,随便输入一些内容( "Nice day!" ),程序会停留在进入函数体的过程之前:

(gdb) break phase_1
Breakpoint 1 at 0x400ee0
(gdb) run
Starting program: /home/liuyuan/Downloads/CSAPP/bomb/bomb 
Welcome to my fiendish little bomb. You have 6 phases with
which to blow yourself up. Have a nice day!
Nice day!

Breakpoint 1, 0x0000000000400ee0 in phase_1 ()

此时查看各个寄存器的数据:

(gdb) info registers
rax            0x603780	6305664
rbx            0x0	0
rcx            0x9	9
rdx            0x1	1
rsi            0x603780	6305664
rdi            0x603780	6305664
rbp            0x402210	0x402210 <__libc_csu_init>
rsp            0x7fffffffdd98	0x7fffffffdd98
r8             0x60467a	6309498
r9             0x7ffff7fe5540	140737354028352
r10            0x3	3
r11            0x7ffff7a14890	140737347930256
r12            0x400c90	4197520
r13            0x7fffffffde80	140737488346752
r14            0x0	0
r15            0x0	0
rip            0x400ee0	0x400ee0 <phase_1>
eflags         0x202	[ IF ]
cs             0x33	51
ss             0x2b	43
ds             0x0	0
es             0x0	0
fs             0x0	0
gs             0x0	0

这是并没有出现 0x402400 。猜测刚刚输入的数据保存地址为 0x603780:

(gdb) x/s 0x603780
0x603780 <input_strings>:	"Nice day!"

回到前面的汇编指令,第二条指令将立即数 0x402400 移到寄存器 esi,让程序执行两条汇编指令,再查看寄存器的状态:

(gdb) stepi 2
0x0000000000400ee9 in phase_1 ()
(gdb) i r
rax            0x603780	6305664
rbx            0x0	0
rcx            0x9	9
rdx            0x1	1
rsi            0x402400	4203520
rdi            0x603780	6305664
rbp            0x402210	0x402210 <__libc_csu_init>
rsp            0x7fffffffdd90	0x7fffffffdd90
r8             0x60467a	6309498
r9             0x7ffff7fe5540	140737354028352
r10            0x3	3
r11            0x7ffff7a14890	140737347930256
r12            0x400c90	4197520
r13            0x7fffffffde80	140737488346752
r14            0x0	0
r15            0x0	0
rip            0x400ee9	0x400ee9 <phase_1+9>
eflags         0x206	[ PF IF ]
cs             0x33	51
ss             0x2b	43
ds             0x0	0
es             0x0	0
fs             0x0	0
gs             0x0	0

看到寄存器 esi (即 rsi 的低 32 位)被更新了!


Phase_2

首先查看 Phase_2 的汇编代码:

(gdb) disas phase_2
Dump of assembler code for function phase_2:
=> 0x0000000000400efc <+0>:	push   %rbp
   0x0000000000400efd <+1>:	push   %rbx
   0x0000000000400efe <+2>:	sub    $0x28,%rsp
   0x0000000000400f02 <+6>:	mov    %rsp,%rsi
   0x0000000000400f05 <+9>:	callq  0x40145c <read_six_numbers>
   0x0000000000400f0a <+14>:	cmpl   $0x1,(%rsp)
   0x0000000000400f0e <+18>:	je     0x400f30 <phase_2+52>
   0x0000000000400f10 <+20>:	callq  0x40143a <explode_bomb>
   0x0000000000400f15 <+25>:	jmp    0x400f30 <phase_2+52>
   0x0000000000400f17 <+27>:	mov    -0x4(%rbx),%eax
   0x0000000000400f1a <+30>:	add    %eax,%eax
   0x0000000000400f1c <+32>:	cmp    %eax,(%rbx)
   0x0000000000400f1e <+34>:	je     0x400f25 <phase_2+41>
   0x0000000000400f20 <+36>:	callq  0x40143a <explode_bomb>
   0x0000000000400f25 <+41>:	add    $0x4,%rbx
   0x0000000000400f29 <+45>:	cmp    %rbp,%rbx
   0x0000000000400f2c <+48>:	jne    0x400f17 <phase_2+27>
   0x0000000000400f2e <+50>:	jmp    0x400f3c <phase_2+64>
   0x0000000000400f30 <+52>:	lea    0x4(%rsp),%rbx
   0x0000000000400f35 <+57>:	lea    0x18(%rsp),%rbp
   0x0000000000400f3a <+62>:	jmp    0x400f17 <phase_2+27>
   0x0000000000400f3c <+64>:	add    $0x28,%rsp
   0x0000000000400f40 <+68>:	pop    %rbx
   0x0000000000400f41 <+69>:	pop    %rbp
   0x0000000000400f42 <+70>:	retq   
End of assembler dump.

函数基本栈帧处理后,调用了一个名为 <read_six_numbers> 的函数,顾名思义,应该是读取六个数字,我们也可以反汇编这个函数的机器指令,查看其汇编指令:

(gdb) disas 0x40145c
Dump of assembler code 
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值