实验三还是挺好玩的,拆炸弹,这个实验每个人的炸弹都不一样,所以只能靠自己啦。
可以下载一个工具(忘了叫啥),可以将汇编语言直接转换为c语言,然后直接破解炸弹。
第六个炸弹我们都是1-6个数字的一个排序,所以。。。就算你没看懂汇编语言,你也可以以试错的方式把答案试出来哦。
把火炬传下去!
实验报告
实 验(三)
题 目 Binary Bomb
二进制炸弹
专 业 计算机类
学 号 xxx
班 级 xxx
学 生 xxxx
指 导 教 师 xxxx
实 验 地 点 xxxx
实 验 日 期 xxxx
计算机科学与技术学院
目 录
2.1 Ubuntu下CodeBlocks反汇编(10分).................................................. - 4 -
2.2 Ubuntu下EDB运行环境建立(10分).................................................... - 4 -
第3章 各阶段炸弹破解与分析............................................................................. - 5 -
3.7 阶段7的破解与分析(隐藏阶段).................................................................. - 6 -
4.2 请给出对本次实验内容的建议..................................................................... - 7 -
第1章 实验基本信息
1.1 实验目的
熟练掌握计算机系统的ISA指令系统与寻址方式
熟练掌握Linux下调试器的反汇编调试跟踪分析机器语言的方法
增强对程序机器级表示、汇编语言、调试器和逆向工程等的理解
1.2 实验环境与工具
1.2.1 硬件环境
X64 CPU;2GHz;2G RAM;256GHD Disk 以上
1.2.2 软件环境
Windows7 64位以上;VirtualBox/Vmware 11以上;Ubuntu 16.04 LTS 64位/优麒麟 64位;
1.2.3 开发工具
GDB/OBJDUMP;EDB;KDD等1.3 实验预习
上实验课前,必须认真预习实验指导书(PPT或PDF)
了解实验的目的、实验环境与软硬件工具、实验操作步骤,复习与实验有关的理论知识。
请写出C语言下包含字符串比较、循环、分支(含switch)、函数调用、递归、指针、结构、链表等的例子程序sample.c。
生成执行程序sample.out。
用gcc –S或CodeBlocks或GDB或OBJDUMP等,反汇编,比较。
列出每一部分的C语言对应的汇编语言。
修改编译选项-O (缺省2)、Og、O0、O1、O2、O3、Og,-m32/m64。再次查看生成的汇编语言与原来的区别。
堆栈访问[rbp+-n]或[rsp+n]。-fno-omit-frame-pointer。
GDB命令详解 –tui模式 ^XA切换 layout改变等等
第2章 实验环境建立
2.1 Ubuntu下CodeBlocks反汇编(10分)
CodeBlocks运行hellolinux.c。反汇编查看printf函数的实现。
要求:C、ASM、内存(显示hello等内容)、堆栈(call printf前)、寄存器同时在一个窗口。
图2-1 Ubuntu下CodeBlocks反汇编截图
2.2 Ubuntu下EDB运行环境建立(10分)
用EDB调试hellolinux.c的执行文件,截图,要求同2.1
图2-2 Ubuntu下EDB截图
第3章 各阶段炸弹破解与分析
每阶段15分,密码10分,分析5分,总分不超过80分
3.1 阶段1的破解与分析
密码如下:Crikey! I have lost my mojo!
破解过程:
1).先运行可执行文件bomb,随意输入一些东西,发现程序被引爆,通关密码错误。
2).查看汇编代码分析以找到正确的通关密码,由于直接反汇编查看汇编代码在终端界面的小黑框里不方便看,用gdb指令查看又特别麻烦,因此edb来查看汇编代码。在终端输入“./edb --run bomb”指令,再用用edb跳转符先跳转至main函数的部分。但是在main函数下发现了它调用了phase_1到phase_6以及phase_defused函数,由此可猜测phase_1到phase_6即为所要找的关卡。
3).一关一关来,进入edb调试界面,查看phase_1的汇编代码。首先先输入一个试测的答案,然后再通过edb单步进入的按键进入bomb! phase_1的子程序中,如截图所示。
4).分析phase_1函数的汇编代码发现,它调用了两个函数strings_not_equal和explode_bomb(我也查看了这两个函数的汇编代码,前者在里面两次次调用了string_length函数,猜测是为了实现字符串的比较,总之,从这两个函数里没有分析出很有用的东西),根据单词的字面意思,前者是比较两个字符串是否相等,后者是一个爆炸函数。以下为strings_not equal函数的汇编代码,大概就是先比较两字符串是否相等,若相等,再逐个比较字符是否一样,一样则字符串相等,反之,直接不等,若字符串相等%eax返回0,否则,返回1:再接着析phase_1的汇编代码,发现在调用strings_not_equal函数后,进行了test指令,比较%eax与%eax是否位0,若为0则字符串相等跳转到leave,释放栈帧,否则,跳转到explode_bomb函数,程序爆炸。
5).根据上述分析可知,调用strings_not_equal函数之前的mov,esi,0x40314c中的立即数0x40314c中的内容就是第一关的密码,它通过与用户输入的字符串进行比较来判断用户输入的字符串是否正确,因此只需要查看0x40314c中的内容即可知道第一关的密码。如图所示得出密码为:Crikey! I have lost my mojo!
3.2 阶段2的破解与分析
密码如下:3 4 6 9 13 18
1 2 4 7 11 16
n n+1 n+1+2 n+1+2+3 n+1+2+3+4 n+1+2+3+4+5(n>=0)
........
破解过程:
1).了解第一关的经验,先进入edb调试界面下,然后查看phase_2的汇编代码,看了一遍代码后发现里面调用了函数read_six_numbers,猜测应该是读入六个数字,而后进行了两次相等跳转和不相等跳转以及两次跳转到explode_bomb函数.
2).分析phase_2的汇编代码:
1)、首先栈帧指针%esp、%ebp以及寄存器%esi、%ebx入栈,接着开了40字节(16进制的28等于10进制的48)的内存,栈帧结构中已经明确标出。
2)、然后令rsi指向%rbp-0x30地址,再调用read_six_numbers函数,此函数应该是参数的输入入口。它表明应该传入6个参数。接着比较rbp-0x30地址处的值是否小于0,若小于0,则跳转到explode_bomb函数处,程序爆炸,为了让程序不爆炸,所以要保证rbp-0x30地址处的值大于0,由此猜测此处存储的值即为参数1。且参数1的值应该大于0.
3)然后再把ebx的值赋为1,再把ebx和5做比较,如果ebx大于5则跳转至explode_bomb函数处,程序爆炸,否则继续执行下一条指令:把ebx的值赋给rax,即等于1,再把rbx的值-1通过中间寄出器edx赋值给rdx,并且赋值给ecx,因此ecx和为1,rdx为0。
4)add ecx,[rbp+rdx*4-0x30]者调整指令是整个phase_2的关键。rdx*4它指明了输入的数据应该占四个字节,且连续的存储在堆栈中,其中第一个数存放在rbp-0x30中,第i个数存放在rbp+rdx*4-0x30中,其中edx的值即代表了第几个参数。它把ecx的值与[rbp+rdx*4-0x30]相加再赋值给ecx.再比较ecx的值与[rbp+rax*4-0x30],相等则跳转至3)4)分析的命令中继续执行,否则跳转至explode_bomb函数处,程序爆炸。
5)再次循环时,ebx的值加1,[rbp+rdx*4-0x30]的指令也指向了第二个参数,同时ecx的值在第一个参数的基础上加上了1,然后再比较第二个参数和、ecx的大小,相等则继续执行循环体,不相等则爆炸。因此第二个参数比第一个参数大1,再次执行循环体可知第三个参数比第二个参数大2..........因此当执行五次循环后,ebx大于5程序结束。
3.3 阶段3的破解与分析
密码如下:2 -227
破解过程:
1)有了前面两关的经验,在过第三关的时候,一开始我就直接进入bomb文件的edb调试界面,反汇编得到phase_3函数的汇编代码,观察整个phase_3函数的汇编代码,我发现它跟前面两关有一个相似之处,调用了两个函数,其中一个仍是爆炸函数,另一个是__isoc99_sscanf@plt函数,
2)开始分析phase_3函数的反汇编代码:
前面几条指令都是在栈上分配空间,不再细说。Call bomb!__isoc99_sscanf@plt函数说明调用函数读入参数。cmp eax,1.如果eax小于等于1,则调用explode_bomb函数,直接爆炸,说明读入的第一个参数应该大于1.再比较第一个参数和7,如果参数大于7则直接爆炸,说明第一个参数1<=x<7.
这条指令根据输入的第一个参数,跳转到不同的地方。说明这是一个switch语句。推测有多个答案,第一个参数不同会导致跳往不同的地方。
于是我输入第一个参数为2,发现跳转的指令如下,并一步一步跟踪:
可以看出 第一个参数(2) +0x387-0x153+0x153-0x153+0x153-0x153=-227
再比较-227和第二个参数是否相同,如果不相同则爆炸,因此第二个参数为-227.
并且推算出switch的c语句如图:
3.4 阶段4的破解与分析
密码如下:66 2
99 3
132 4
破解过程:phase的汇编代码和func4的汇编代码如图所示
如图所示,可以看到首先在堆栈上给参数分配存储空间,参数1和参数2分别分配在rbp-8和rbp-4上。
Call bomb!__isoc99_sscanf@plt函数说明调用函数读入参数。cmp eax,2.如果eax不等于2,则调用explode_bomb函数,直接爆炸,因此phase必须读入两个参数。
从图中可以看出,把第二个参数赋值给寄存器eax,并分别和1和4进行比较,当eax小于等于1和大于4的时候都会bomb!!!说明第二个参数的值应该大于1小于等于4。
把第一个参数赋值给edi,把第二个参数赋值给ebx,然后分别把参数传给func4函数并调用func4函数。
分析func4第一条指令可知,如果第一个参数为0,则返回值为0
分析第二条指令可得,如果第一个参数等于1,则函数返回第二个参数即edi
接下来,在其他情况下将进行递归调用。
再一次调用func4时,第一个参数的值已经减去了1。
第二次调用func4时,第二个参数的值已经减去了2。
当第一个参数大于1时,函数返回值为func4(第一个参数-1,第二个参数)+func4(第一个参数-2,第二个参数)+第二个参数。
可推出func4的c语言代码如上图所示.
验证第二个参数分别为2、3、4时的正确性
3.5 阶段5的破解与分析
密码如下:9/>567
)_^%&g
第几个元素 | 0 | 1 | 2 | 3 | 4 | 5 |
Ascall码 | 0x_9 | 0x_f | 0x_e | 0x_5 | 0x_6 | 0x_7 |
对应的字符 | I,i,9,), | /,?,O,_,o, | ,.,>,^,~ | %,5,E,e | &,6,F,f | 1,g,G |
按上述顺序依次抽取每个元素位置对应的一种元素构成的组合即
破解过程:phase_5的汇编代码如图所示
以下逐行分析代码:
首先压栈,然后在栈上分配存储空间。
这一行说明读入的字符串的长度为6
上图表明这是一个循环语句
循环的初始条件是eax=0,终止条件是eax>5,每次循环结束eax的值会自动加1 。
分析循环语句: rbp-0x17为首地址的数组用s来表示,0x4031b0位首地址的数组用r来表示。rbx为首的地址的数组用input来表示(数组元素均是输入的六个字符)
通过查看0x4031b0的地址内容可以得出数组r[19]=”maduiersnfotvbylWow”.
通过分析指令可以得出该函数的c语言代码为:
char r[19]="maduiersnfotvbulWow";
void phase_5(char *input){
char s[7];
if(string_length(input)!=6)
explode_bomb();
else
for (int edx=0;edx<5;edx++){
int eax=(int )(input[edx]&0xf);
s[edx]=r[eax];
s[7]="\0"
}
if(string_not_equal(s,"flyers"))
expolde_bomb();
}
接下来,调用string_not_equal函数,判断esi和edi是否相等,不相等爆炸,相等直接返回值。查看esi的值为:flyers
因此最终通过判断可以得出六个字符为:
第几个元素 | 0 | 1 | 2 | 3 | 4 | 5 |
Ascall码 | 0x_9 | 0x_f | 0x_e | 0x_5 | 0x_6 | 0x_7 |
对应的字符 | I,i,9,), | /,?,O,_,o, | ,.,>,^,~ | %,5,E,e | &,6,F,f | 1,g,G |
因此最后的密码就是 按上述顺序依次抽取每个元素位置对应的一种元素构成的组合即可。比如 9/>567 , )_^%&g , 等等验证如图:
3.6 阶段6的破解与分析
密码如下:5 6 4 1 3 2
破解过程:
通过对汇编代码的分析,需要输入六个数据,
该指令是对输入的六个数据依次判别这六个数据是否有相等的数据,如果有,直接爆炸。说明输入的六个数据均不相等。
通过对剩下的指令分析可以得出:phase_6主要就是对链表的重新排序。通过用户输入的数据来对原来链表的数据按从小到大的顺序排列。
所以:首先看原链表的数据的大小关系
然后通过输入六个数据将原链表按从小到大顺序排列。
这个指令表明需要将地址为0x4052d0的数据赋值给edx。推测这就是所需要排序的链表的首节点。打印它的内容如下:
可以看到链表共有6个节点,大小关系为:node5<node6<node4<node1<node3<node2
因此输入的六个数据应该为5 6 4 1 3 2才可以将链表重新排序。
3.7 阶段7的破解与分析(隐藏阶段)
密码如下:
破解过程:
第4章 总结
4.1 请总结本次实验的收获
首先,通过本次实验学会了如何使用gdb和edb,能够自主的分析出汇编代码的意思,进而推断出c语言代码。会读懂汇编代码了。
4.2 请给出对本次实验内容的建议
建议老师可以多讲一些其他的edb指令的使用,还可以讲一下gdb的使用.
注:本章为酌情加分项。
参考文献
为完成本次实验你翻阅的书籍与网站等
[1] 林来兴. 空间控制技术[M]. 北京:中国宇航出版社,1992:25-42.
[2] 辛希孟. 信息技术与信息服务国际研讨会论文集:A集[C]. 北京:中国科学出版社,1999.
[3] 赵耀东. 新时代的工业工程师[M/OL]. 台北:天下文化出版社,1998 [1998-09-26]. http://www.ie.nthu.edu.tw/info/ie.newie.htm(Big5).
[4] 谌颖. 空间交会控制理论与方法研究[D]. 哈尔滨:哈尔滨工业大学,1992:8-13.
[5] KANAMORI H. Shaking Without Quaking[J]. Science,1998,279(5359):2063-2064.
[6] CHRISTINE M. Plant Physiology: Plant Biology in the Genome Era[J/OL]. Science,1998,281:331-332[1998-09-23]. http://www.sciencemag.org/cgi/ collection/anatmorp.