二进制炸弹拆弹记录

学校布置了二进制炸弹的作业,一边查攻略一边自己拆,零零总总花了两三天拆完了。拆的时候感觉看一看前人的经验,进度真的快很多,所以虽然自己也只是个小白,还是想把心得放上来供大家参考。

写在前面

感谢 https://www.cnblogs.com/liqiuhao/p/7624880.html和https://blog.csdn.net/the_v_/article/details/46842337/这两位大佬的无私奉献,我的炸弹是参考这两篇拆的。

0.gdb断点

我在拆炸弹之前特别担心炸弹爆炸,即便知道gdb调试可以设断点,还是不明白怎么操作。所以在最前面先演示一下断点的设置和运行结果,让大家放心拆弹无惧爆炸hhh

怎么进入炸弹文件我就跳过了,应该拆弹之前都会有讲或者有参考步骤的文件之类的。

那么假设我们已经cd到了炸弹所在处,接着就是gdb调试。

(@前面是我的学号,就不显示了)直接输入 gdb bomb(或者是你的炸弹的名字)

然后变成这样,可以直接输入gdb指令啦。


输入 break *0x401751(炸弹所在地址,观察callq  xxxxxx<explode_bomb>),回车显示断点设好了。

之后可以直接输入 run开始跑炸弹,如果输错了结果炸弹爆炸,会显示


你的断点就生效了。这个时候就可以继续gdb调试(run 或者x/s 0xxxxxxxx看看数据),或者输入q退出。退出之后,再次gdb bomb要记得重新设断点。如果你的断点设在了炸弹前面,千万不要输入c(continue),不然继续运行的就是爆炸了。

接下来正式开始拆弹!


*csapp 3rd P120:%r(e)di 第一个参数;%r(e)si 第二个参数;%r(e)dx 第三个参数;%r(e)cx 第四个参数,%eax函数返回值。后面maybe会用到。

1.phase1 字符串比较

0000000000400f90 <phase_1>:
  400f90:	48 83 ec 08          	sub    $0x8,%rsp  //当前输入
  400f94:	be 50 27 40 00       	mov    $0x402750,%esi    //把0x402750中的内容,作为第二个参数
  400f99:	e8 da 04 00 00       	callq  401478 <strings_not_equal>//发现调用了一个比较两个字符串的函数
  400f9e:	85 c0                	test   %eax,%eax
  400fa0:	74 05                	je     400fa7 <phase_1+0x17>//返回值是不是0,上网查的:test 自己,再加上je,就是比较是不是0
  400fa2:	e8 aa 07 00 00       	callq  401751 <explode_bomb>//不然炸
  400fa7:	48 83 c4 08          	add    $0x8,%rsp
  400fab:	c3                   	retq   

strings_not_equal (我只看了如果字符串相同返回什么)

0000000000401478 <strings_not_equal>:
  401478:	41 54                	push   %r12
  40147a:	55                   	push   %rbp
  40147b:	53                   	push   %rbx
  40147c:	48 89 fb             	mov    %rdi,%rbx //rbx=第一个参数地址:输入
  40147f:	48 89 f5             	mov    %rsi,%rbp// rbp=第二个参数地址:地址
  401482:	e8 d4 ff ff ff       	callq  40145b <string_length>
  401487:	41 89 c4             	mov    %eax,%r12d //r12d 输入字符串长度
  40148a:	48 89 ef             	mov    %rbp,%rdi
  40148d:	e8 c9 ff ff ff       	callq  40145b <string_length>
  401492:	ba 01 00 00 00       	mov    $0x1,%edx
  401497:	41 39 c4             	cmp    %eax,%r12d   //两字符串长度比较
  40149a:	75 3f                	jne    4014db <strings_not_equal+0x63>
  40149c:	0f b6 03             	movzbl (%rbx),%eax//相等,提取输入的第一个字符
  40149f:	84 c0                	test   %al,%al
  4014a1:	74 25                	je     4014c8 <strings_not_equal+0x50>//比较输入是不是0(字符串结束),结束跳转
  4014a3:	3a 45 00             	cmp    0x0(%rbp),%al//没结束,两个字符串第一个字符比较
  4014a6:	74 0a                	je     4014b2 <strings_not_equal+0x3a>//相同跳...4b2
  4014a8:	eb 25                	jmp    4014cf <strings_not_equal+0x57>
  4014aa:	3a 45 00             	cmp    0x0(%rbp),%al//从...4bf跳到这里,看出来这个循环块 开始循环逐个比较
  4014ad:	0f 1f 00             	nopl   (%rax)
  4014b0:	75 24                	jne    4014d6 <strings_not_equal+0x5e>
  4014b2:	48 83 c3 01          	add    $0x1,%rbx//第一个字符相同到这里
  4014b6:	48 83 c5 01          	add    $0x1,%rbp//第二个字符
  4014ba:	0f b6 03             	movzbl (%rbx),%eax
  4014bd:	84 c0                	test   %al,%al
  4014bf:	75 e9                	jne    4014aa <strings_not_equal+0x32>//同样,是不是结束了
  4014c1:	ba 00 00 00 00       	mov    $0x0,%edx//比较到字符串结束了,edx=0
  4014c6:	eb 13                	jmp    4014db <strings_not_equal+0x63>//跳...4db
  4014c8:	ba 00 00 00 00       	mov    $0x0,%edx
  4014cd:	eb 0c                	jmp    4014db <strings_not_equal+0x63>
  4014cf:	ba 01 00 00 00       	mov    $0x1,%edx
  4014d4:	eb 05                	jmp    4014db <strings_not_equal+0x63>
  4014d6:	ba 01 00 00 00       	mov    $0x1,%edx
  4014db:	89 d0                	mov    %edx,%eax//如果全部相同,返回值为0
  4014dd:	5b                   	pop    %rbx
  4014de:	5d                   	pop    %rbp
  4014df:	41 5c                	pop    %r12
  4014e1:	c3                   	retq   

分析完了就知道,0x402750里面就是我们的目标字符串,于是就可以用(gdb)x/s 0x402750来查看字符串。我查出来的是“I can see Russia from my house!”中俄友谊地久天长hhhh

2.phase2 数列

0000000000400fac <phase_2>:0 1 1 2 3 5
  400fac:	55                 	push   %rbp
  400fad:	53                	push   %rbx
  400fae:	48 83 ec 28        	sub    $0x28,%rsp
  400fb2:	48 89 e6           	mov    %rsp,%rsi
  400fb5:	e8 cd 07 00 00          callq  401787 <read_six_numbers>//反正看名字知道读入六个数字..仔细看函数太头大了...
  400fba:	83 3c 24 00        	cmpl   $0x0,(%rsp)//rsp指向第一个数字,可以随便输一串数字gdb看一看,反正不怕炸哈哈哈
  400fbe:	75 07                   jne    400fc7 <phase_2+0x1b> //和0比,不等就炸(ac+1b=c7)
  400fc0:	83 7c 24 04 01          cmpl   $0x1,0x4(%rsp)//rsp+4 //第二个数字,和1比较
  400fc5:	74 21                   je     400fe8 <phase_2+0x3c> //不等爆炸,相等跳e8
  400fc7:	e8 85 07 00 00          callq  401751 <explode_bomb>
  400fcc:	eb 1a              	jmp    400fe8 <phase_2+0x3c>  
  400fce:	8b 43 f8                mov    -0x8(%rbx),%eax//eax=rbx前两个数
  400fd1:	03 43 fc           	add    -0x4(%rbx),%eax//eax=eax+eax前一个数
  400fd4:	39 03              	cmp    %eax,(%rbx)//比较rbx是否等于前两个数的和
  400fd6:	74 05              	je     400fdd <phase_2+0x31>相等跳dd 不然炸
  400fd8:	e8 74 07 00 00     	callq  401751 <explode_bomb>
  400fdd:	48 83 c3 04        	add    $0x4,%rbx//rbx后移一个
  400fe1:	48 39 eb                cmp    %rbp,%rbx //rbx是否已经超出6个的范围
  400fe4:	75 e8                   jne    400fce <phase_2+0x22>  //rbx没有超出&#
  • 20
    点赞
  • 83
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值