Bootstrap

计算机系统实验——二进制炸弹(bomb)包括secret_phase

实验题目:本实验设计为一个黑客拆解二进制炸弹的游戏。我们仅给黑客(同学)提供一个二进制可执行文件bomb_64和主函数所在的源程序bomb_64.c,不提供每个关卡的源代码。程序运行中有6个关卡(6个phase),每个关卡需要用户输入正确的字符串或数字才能通关,否则会引爆炸弹(打印出一条错误信息)!要求同学运用GDB调试工具和objdump反汇编工具,通过分析汇编代码,找到在每个phase程序段中,引导程序跳转到“explode_bomb”程序段的地方,并分析其成功跳转的条件,以此为突破口寻找应该在命令行输入何种字符串来通关。
实验目的:
1.理解程序(控制语句、函数、返回值、堆栈结构)是如何运行的
2.掌握GDB调试工具和objdump反汇编工具

实验环境:
Ubuntu 12.04,GDB调试工具
实验内容及操作步骤:
第一关:phase_1
对phase_1进行分析:
在这里插入图片描述
发现将0x804a24c作为第二个参数传入函数,然后返回值=0则跳过爆炸进入下一关。根据函数的名字可以推测:输入的内容应该与地址0x804a24c的字符内容相同,才可能得到返回值=0猜测可能基本八九不离十了,但是为了准确一点,我们还是分析一下<strings_not_equal>的汇编代码:
在这里插入图片描述
通过对<strings_not_equal>汇编指令的分析,可能得到我们的猜测是正确的
所以我们就将地址0x804a24c保存的字符串打印出来:
在这里插入图片描述
将这个字符串输入进入第二关

在这里插入图片描述

第二关:phase_2
分析phase_2代码
在这里插入图片描述
所以我们的分析结果就是这六个数为1 2 4 8 16 32
将这6个数输入进入第三关
在这里插入图片描述

第三关:phase_3
分析phase_3代码

在这里插入图片描述在这里插入图片描述
通过我们对代码的分析,可以知道我们要输入三个数,第一个代表其switch跳转的值,
第二个参数等于对应switch保存到eax中的值,第三个参数代表其对应switch给出的值,但是我们如何传入这三个参数,需要进行
gdb调试:
首先,我们随便输入三个数1 2 3进行调试:
在这里插入图片描述
首先运行到0x8048c04,三个参数都已经传入的地址
在这里插入图片描述
此时esp的值如下:
在这里插入图片描述
查看0x40(%esp)的值
在这里插入图片描述
发现这里保存了一个地址
在这里插入图片描述
查看这个地址里保存的字符串
在这里插入图片描述
发现这是将我们的输入当做输入的字符串
再查看这个地址0x804a29a里的字符串
在这里插入图片描述在这里插入图片描述

发现我们输入的这三个数要以十进制数,字符,十进制数的形式输入
我们输入的两个整数也都保存到了对应的内存地址
在这里插入图片描述

我们先使用指令x/10gx查看一下跳转表的内容:
在这里插入图片描述
注意08048c0b是0号,08048c2d是1号
所以我们可以得到以下结论:
第一个参数输入0-7任意一个数,并根据这个数找到其对应地址进行下一步操作,例如,假如我第一个参数选择1,我们就要到0x08048c2d这个地址进行下一步操作
在这里插入图片描述
并根据这里的代码知道第三个参数要输入十进制的174,eax保存0x73也就是十进制的115
跳转到8048d03
在这里插入图片描述
得知第二个参数时115,但是以前的分析我们知道第二个参数要用字符输入,所以我们将其转化为ascii码,115对应的是s
所以我们输入 1 s 174就可以进入到第四关

在这里插入图片描述

第四关:phase_4
分析phase_4代码:
在这里插入图片描述

这道题其实思路很简单,我们并不需要看func4这个函数,刚开始我不知道还傻傻的看了好久的func4这个函数,这道题就是要我们输入两个数,将第二个参数进行一系列处理之后的返回值与第一个参数进行比较,如果相等就通过,而且第二个参数要求大于一小于四,我们可以取任意一个值,然后使用gdb调试到8048dc2这个地址打印出%eax这个返回值,这个就是我们取的第二个参数所对应的第一个参数

gdb调试:
我们先看输入的格式
在这里插入图片描述
是两个十进制数
再取第二个参数为3,第一个参数未知,取1
在这里插入图片描述
到达最后判断这一步,输出eax中的值
在这里插入图片描述
所以第二个参数3对应第一个参数就是99
我们再输入3 99,通过第四关,进入第五关
在这里插入图片描述

第五关:phase_5
分析phase_5代码:
在这里插入图片描述

这道题就是要我们输入6个字符,由这六个字符所对应的ascii码的低四位找到0x804a2cc字符数组所对应的6个字符,并将其与存到0x804a2a3的字符相比较,相等则跳过爆炸
我们先来查看0x804a2cc字符数组
在这里插入图片描述
再查看0x804a2a3的字符数组
在这里插入图片描述
根据这个找到对应的字符
在这里插入图片描述
oilers在上表中对应着a4f567
而a到z的ascii码16进制从61到7a,由低四位可以发现其中一个字符串为jdoefg,
当然还有另外的字符串,不过我们有这个就可以通关了。
在这里插入图片描述

第六关:phase_6
分析phase_6代码:
在这里插入图片描述
在这里插入图片描述
查看
在这里插入图片描述
按照由大到小排序得4 5 3 6 1 2
验证:

在这里插入图片描述
第七关:secret_phase
分析代码:
在这里插入图片描述在这里插入图片描述在这里插入图片描述

Fun7函数总结

我们用伪代码来总结下函数:

Int Fun7(node* addr, int input){

   If(addr==null)  return -1;

   If(*addr <= input){

   If(*addr == input ) return 0;

   Else 2*fun7(addr+8,input)+1;

}

Else 2*fun7(addr+4,input);

}

这个过程类似于BST的搜索,但是在返回值处理上有一点细微的差别。我们的目标是让这个函数返回值为1,那我们只能逆着来推了。
返回值为1,那么肯定是2*0+1得到,说明下一层返回值为0;
返回值为0,说明是此时结点值=输入值,那么我们只要找到这个结点值就可了
顺着上面的思路,我们可以看出,这个二叉树的遍历顺序是:右
在这里插入图片描述在这里插入图片描述

我们只要把50输进去就好了
验证:
在这里插入图片描述
实验结果及分析:
在这里插入图片描述

;