二进制炸弹

二进制炸弹文件:https://download.csdn.net/download/qq_49712456/35492341

一、 实验目的

1)锻炼阅读x86汇编代码的能力
2)熟练Linux系统的基本操作

二、 实验内容

1)在Ubuntu中运行二进制文件
2)反汇编二进制文件,读懂汇编代码
3)找到正确的输入,通关

三、 实验环境

在 Linux 操作系统中完成,需要用到 gdb,objdump,make

四、 实验过程

1)进入操作

进入文件夹,尝试测试并引爆炸弹
在这里插入图片描述

使用gdb打开bomb53
在这里插入图片描述

设置第一个断点
在这里插入图片描述

运行该程序,随意输入后,程序跳至断点处
在这里插入图片描述

反汇编当前代码,即可得到第一题的汇编代码
在这里插入图片描述

2)第一关

分析第一题的汇编代码
地址0x0000000008000ca2处,call一个函数<strings_not_equal>
eax存储函数返回值
callq与0x0000000008000caf处的retq对应,用于调用函数
由名字可知这个函数的作用在于判断两个字符串是否相等
若字符串相等返回1,不相等返回0,函数返回值保存在eax累加器中
test %eax,%eax
用于检查eax中寄存器的值是否为0
jne 0x8000cb0 <phase_1+30>
判断test的结果是否不为0,若是则跳转值0x8000cb0 <phase_1+30>处
若跳转,则会运行callq 0x8000b8c <explode_bomb>,从而引爆炸弹
所以没有跳转,程序在0x0000000008000caf处由retq停止运行
使用ni运行至test命令,再查看eax的值
在这里插入图片描述

test结果为0,说明两字符串相等
call调用函数之前,lea 0x201403(%rip),%rsi将参数存入当做输入值
用x/s以字符串形式打印0x82020a0的内容,可得到一串字符
在这里插入图片描述

Religion will be one when God is dead.即为第一题的答案
在gdb中运行程序,通过第一关
在这里插入图片描述

3)第二关

反汇编第二关,获取第二关的汇编语言
在这里插入图片描述

callq 0x8000c4c <read_six_numbers>调用函数
根据名字判断该函数用于输入六个数字
在这里插入图片描述

mov $0x0,%ebx 为ebx赋值0
jmp 0x8000ce3 <phase_2+39> 无条件跳转值地址0x8000ce3
cmp $0x5,%ebx 将5与ebx的值进行比较,即结束循环的条件
jg 0x8000d06 <phase_2+74> 若5等于ebx的值,则跳转至0x8000d06
movslq %ebx,%rax 将ebx的值存入rax中
lea 0x20138e(%rip),%rdx # 0x8202080 <magic_num>
用于将magic_num中的数字加载进rdx中
mov (%rdx,%rax,4),%ecx 将rdx中存储的magic_num第%rax个数存入ecx
cmp %ecx,(%rsp,%rax,4) 比较magic_num第%rax个数和输入的第%rax个数
je 0x8000ce0 <phase_2+36> 相等则从0x8000ce0开始循环
若果je不跳转,则会运行至callq 0x8000b8c <explode_bomb>,炸弹爆炸
综上所述,该程序的运行思路为:
输入6个数,存入一个数组,从第一个遍历到最后一个
如果输入的数字与magic_num对应的数字相等,则会跳过炸弹
经尝试,发现magic_num中存储的是四字节,且有6个数
利用命令x/6gx,输出0x8202080后的6个四字节数
在这里插入图片描述

将十六进制数转为十进制
在这里插入图片描述

602 659 384 67 390 923 即为第二题答案

4)第三关

设置第三个断点
在这里插入图片描述

输入前两题的答案,开始第三题
在这里插入图片描述

反汇编第三题代码
在这里插入图片描述

__isoc99_sscanf@plt 初步判断scanf为输入函数
用x/s观察输入参数类型和个数
在这里插入图片描述

lea 0x2012ff(%rip),%rsi # 0x8202043 <fmt_phase_3>
传入函数<fmt_phase_3>,选择continue,查看该函数
在这里插入图片描述
在这里插入图片描述

主代码段:
xor %eax,%eax 将eax异或,得到结果为0,存入eax中
cmp $0x1,%eax 比较1和eax是否相等,由上一代码可知不相等
jle 0x8000d77 <phase_3+86> 不执行,不会跳转
cmpl $0x0,(%rsp) 将0与第一个输入值比较
js 0x8000d83 <phase_3+98> 若小于0,则跳转至0x8000d83,引爆炸弹
cmpl $0x7,(%rsp) 将7与第一个输入值比较
jg 0x8000d8f <phase_3+110> 若大于7,则跳转至0x8000d8f,引爆炸弹
若输入的第一个值在[0, 7]区间内,jmpq *%rax跳转
跳转位置取决于输入第一个数的取值
附代码段:
第一个数取0时,cmp %eax,0x2012bb(%rip) 将第二个数与magic_num_p3进行对比
je 0x8000e7a <phase_3+345> 相等则跳过炸弹
第一个数取1时,将第二个数与magic_num_p3+4进行对比
余下几种情况同理
查看magic_num_p3对应的8个值
在这里插入图片描述
转化为十进制
在这里插入图片描述

代码整体思路:
输入两个整数,第一个整数取值范围为[0, 7]
第二个数的取值由第一个数决定,选择其中一组数据即可通关

5)第四关

设置断点,通过前3关
在这里插入图片描述

反汇编第四关,得到第四关的汇编代码
在这里插入图片描述

callq 0x8000820 __isoc99_sscanf@plt 引入输入函数
lea 0x20115e(%rip),%rsi # 0x8202040 <fmt_phase_4>
载入fmt_phase_4函数,查看该函数的输入类型和个数:
在这里插入图片描述

xor %eax,%eax 将eax异或后,结果为0,存入eax
在这里插入图片描述

callq 0x8000820 __isoc99_sscanf@plt 运行后,eax的值变为1
在这里插入图片描述

cmp $0x1,%eax 对比1和eax的值
jne 0x8000ef3 <phase_4+49> 不相等则跳转至炸弹,由上图可知相等
cmpl $0x0,0x4(%rsp) 将0与输入数比较
jg 0x8000efd <phase_4+59> 大于则能跳过炸弹
callq 0x8000e94 引入函数func4
cmp $0x37,%eax 将func4返回的结果,与0x37作比较
转化为十进制0x37 = 55
在这里插入图片描述

je 0x8000f15 <phase_4+83> 如果等于55则跳过炸弹,否则将会引爆
反汇编func4:
在这里插入图片描述

edi存储第一个参数
callq 0x8000e94 在func4中调用func4,易知该函数为递归函数
cmp $0x1,%edi 将输入数字与1比较
jg 0x8000e9f <func4+11> 若大于1则跳转,否则退出递归
mov $0x1,%eax 退出递归时返回1
lea -0x1(%rdi),%edi 将edi中的值减1,并作为参数进行递归
mov %eax,%ebp 将上述结果存入ebp中
lea -0x2(%rbx),%edi将edi中的值减2,并作为参数进行递归
add %ebp,%eax 将上述结果与ebp的值相加,即两次递归的值相加
结果存入eax,即函数返回的结果
代码整体思路:
func4函数中,每次分别递归输入值-1、输入值-2
并将两次递归结果相加,最后返回递归总结果
该函数用于计算斐波那契数列,输入的参数为计算数列中对应的数字
主函数中,若输入的数小于等于0,则爆炸
经过func4运算后,结果不等于55,则爆炸
斐波那契数列:1,1,2,3,5,8,13,21,34,55
55为第10个数,由于从0开始算起,则输入值为9
第四题答案为9
6)输入答案,通关
在这里插入图片描述

五、 问题及反思
1)开始阅读代码时,没弄清楚每个寄存器存储的是什么值,导致各个参数分不清
2)从完全不会汇编语言,到逐渐熟悉并初步掌握基础汇编语音
学习的过程很艰难很费时间,但收获颇丰
无论是在汲取知识还是磨炼心性方面,都感觉大有裨益
3)经过实验后,对汇编语言有了一定了解
经过对比,发现汇编语言和写程序的高级语言有很多不同之处
汇编语言和高级语言大多数不能一一对应
所以,在编写程序时,若出现意料之外的bug
应思考其汇编代码,从底层语言思考程序的不严谨性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ETO降临派

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值