【实验记录】csapp实验二(详细):BOMB LAB

这篇博客详述了一次完成csapp实验BOMB LAB的过程,涉及7个phase的解谜。每个phase都需要通过调试找出输入格式、避免爆炸点、理解循环和递归,使用gdb进行调试。博主分享了每个phase的关键洞察,例如phase_1的答案是'Public speaking is very easy.',phase_2是斐波那契数列的前六个数,phase_3涉及字符串和ASCII值,phase_4是递归函数,phase_5处理数字和数组,phase_6涉及到链表和指针操作,最后的secret_phase则需要额外的输入触发。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

总共7个phase,非常好玩…
进入每一个phase时,我们应该弄清楚的是:
1、输入格式:需要我们输入什么,是字符串,还是整数,还是字符,输入个数是多少?
2、爆炸点:哪些语句可能引起爆炸,通常为一个比较语句cmp,这是解题的关键,告诉应该输入的值是多少。因此,找到这些爆炸点即可能跳到<explode_bomb>爆炸函数的语句,在这些地方打上断点哦。
3、循环、递归:当发现jump会往之前的语句跳时,可能是循环或者递归,建议在这段代码做个标记,弄清楚每一段在做什么操作。
4、每个寄存器是用来干什么的:
在这里插入图片描述
最常使用的gdb语句:
1、b+空格+地址/函数名打断点
2、x /s+地址/寄存器 打印该地址处的字符串,s可以换成其他字母,d打印十进制整数,c打印字符,x打印十六进制整数。
3、i r查看寄存器的值(同info r)。
4、stepi单步进入,不跳过子函数;nexti跳过子函数,逐步执行主函数。
5、continue跳到下一个断点。
6、run开始运行。

另外!!可以画图帮助理解!!

命令行中进入实验,然后打开gdb开始调试:

gdb ./bomb

然后在每个炸弹处打断点:phase_1 到 phase_6

(gdb) b phase_1

phase_1

000000000400ead <phase_1>:
  400ead:	48 83 ec 08          	sub    $0x8,%rsp
  400eb1:	be 8c 24 40 00       	mov    $0x40248c,%esi
  400eb6:	e8 4b 05 00 00       	callq  401406 <strings_not_equal>
  400ebb:	85 c0                	test   %eax,%eax
  400ebd:	74 05                	je     400ec4 <phase_1+0x17>
  400ebf:	e8 41 06 00 00       	callq  401505 <explode_bomb>
  400ec4:	48 83 c4 08          	add    $0x8,%rsp
  400ec8:	c3                   	retq   

进入phase_1后,第二行看到比较输入参数和存储在地址 0x40248c 处的值,gdb调试中输入并得到:

(gdb) x /s 0x40248c
0x40248c:       "Public speaking is very easy."

答案 :Public speaking is very easy.

phase_2

小 tips:先把炸弹找出来,然后在可能跳到炸弹的地方打断点。

000000000400ec9 <phase_2>:
  400ec9:	55                   	push   %rbp
  400eca:	53                   	push   %rbx
  400ecb:	48 83 ec 28          	sub    $0x28,%rsp
  400ecf:	64 48 8b 04 25 28 00 	mov    %fs:0x28,%rax
  400ed6:	00 00 
  400ed8:	48 89 44 24 18       	mov    %rax,0x18(%rsp)
  400edd:	31 c0                	xor    %eax,%eax
  400edf:	48 89 e6             	mov    %rsp,%rsi
  400ee2:	e8 40 06 00 00       	callq  401527 <read_six_numbers>
  400ee7:	83 3c 24 00          	cmpl   $0x0,(%rsp)       //x1=0
  400eeb:	75 07                	jne    400ef4 <phase_2+0x2b>     
  400eed:	83 7c 24 04 01       	cmpl   $0x1,0x4(%rsp)    //x2=1
  400ef2:	74 05                	je     400ef9 <phase_2+0x30>
  400ef4:	e8 0c 06 00 00       	callq  401505 <explode_bomb>
  400ef9:	48 89 e3             	mov    %rsp,%rbx
  400efc:	48 8d 6c 24 10       	lea    0x10(%rsp),%rbp//x5
                                           //循环
  400f01:	8b 43 04             	mov    0x4(%rbx),%eax//x2 x3..x5
  400f04:	03 03                	add    (%rbx),%eax //x1+x2  x2+x3.. x4+x5
  400f06:	39 43 08             	cmp    %eax,0x8(%rbx)
                  //x3=x1+x2=1 x4=x2+x3=2 x5=x3+x4 x6=x4+x5=5
  400f09:	74 05                	je     400f10 <phase_2+0x47>
  400f0b:	e8 f5 05 00 00       	callq  401505 <explode_bomb>
  400f10:	48 83 c3 04          	add    $0x4,%rbx//x2->x5
  400f14:	48 39 eb             	cmp    %rbp,%rbx//比较x2和x5 x3和x5..
  400f17:	75 e8                	jne    400f01 <phase_2+0x38>   
                                           //循环结束 
  400f19:	48 8b 44 24 18       	mov    0x18(%rsp),%rax
  400f1e:	64 48 33 04 25 28 00 	xor    %fs:0x28,%rax
  400f25:	00 00 
  400f27:	74 05                	je     400f2e <phase_2+0x65>
  400f29:	e8 f2 fb ff ff       	callq  400b20 <__stack_chk_fail@plt>
  400f2e:	48 83 c4 28          	add    $0x28,%rsp
  400f32:	5b                   	pop    %rbx
  400f33:	5d                   	pop    %rbp
  400f34:	c3                   	retq   

前5行和后7行可以跳过,callq 401527 <read_six_numbers>告诉我们读取6个数,猜测输入为6个整数。
往下看,有给在栈中,栈顶保存的值应为x1=0,向上x2=1,否则会jump到
401505 <explode_bomb>炸弹爆炸。
然后在%rbp中保留了x5,即lea 0x10(%rsp),%rbp 0x10是16,栈顶为x1,每4位一个整数,那么0x10(%rsp)就是x5,然后进入循环,循环过程打在代码数字里面了,最后发现是斐波那契数列的前六个数。
答案 : 0 1 1 2 3 5

phase_3

粗略地总体看一下,中间有很多400f8e: 00类似的语句,然后它们之间的代码好像做的都是差不多是操作。

000000000400f35 <phase_3>:
  400f35:	48 83 ec 28          	sub    $0x28,%rsp
  400f39:	64 48 8b 04 25 28 00 	mov    %fs:0x28,%rax
  400f40:	00 00 
  400f42:	48 89 44 24 18       	mov    %rax,0x18(%rsp)
  400f47:	31 c0                	xor    %eax,%eax
  400f49:	4c 8d 44 24 14       	lea    0x14(%rsp),%r8
  400f4e:	48 8d 4c 24 0f       	lea    0xf(%rsp),%rcx
  400f53:	48 8d 54 24 10       	lea    0x10(%rsp),%rdx
  400f58:	be aa 24 40 00       	mov    $0x4024aa,%esi     // "%d %c %d"
  400f5d:	e8 7e fc ff ff       	callq  400be0 <__isoc99_sscanf@plt> 
  400f62:	83 f8 02             	cmp    $0x2,%eax      //输入的东西个数为3
  400f65:	7f 05                	jg     400f6c <phase_3+0x37>
  400f67:	e8 99 05 00 00       	callq  401505 <explode_bomb>
  
  400f6c:	83 7c 24 10 07       	cmpl   $0x7,0x10(%rsp)
  400f71:	0f 87 fc 00 00 00    	ja     401073 <phase_3+0x13e> //不可以跳<=7
  400f77:	8b 44 24 10          	mov    0x10(%rsp),%eax
  400f7b:	ff 24 c5 c0 24 40 00 	jmpq   *0x4024c0(,%rax,8)
  400f82:	b8 77 00 00 00       	mov    $0x77,%eax
  400f87:	81 7c 24 14 91 03 00 	cmpl   $0x391,0x14(%rsp) //相等
  400f8e:	00 
  400f8f:	0f 84 e8 00 00 00    	je     40107d <phase_3+0x148>
  400f95:	e8 6b 05 00 00       	callq  401505 <explode_bomb>
  400f9a:	b8 77 00 00 00       	mov    $0x77,%eax
  400f9f:	e9 d9 00 00 00       	jmpq   40107d <phase_3+0x148>
  400fa4:	b8 6a 00 00 00       	mov    $0x6a,%eax
  400fa9:	81 7c 24 14 f6 02 00 	cmpl   $0x2f6,0x14(%rsp)
  400fb0:	00 
  400fb1:	0f 84 c6 00 00 00    	je     40107d <phase_3+0x148>
  400fb7:	e8 49 05 00 00       	callq  401505 <explode_bomb>
  400fbc:	b8 6a 00 00 00       	mov    $0x6a,%eax
  400fc1:	e9 b7 00 00 00       	jmpq   40107d <phase_3+0x148>
  400fc6:	b8 61 00 00 00       	mov    $0x61,%eax
  400fcb:	81 7c 24 1
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值