实验报告
实 验(三)
题 目 Binary Bomb
二进制炸弹
专 业 计算学部
学 号 190110920
班 级 7
学 生 麦昌瀚
指 导 教 师 吴锐
实 验 地 点 G709
实 验 日 期 2021.4.19
计算机科学与技术学院
目 录
2.1 Ubuntu下CodeBlocks反汇编(10分)... - 4 -
2.2 Ubuntu下EDB运行环境建立(10分)... - 4 -
第1章 实验基本信息
1.1 实验目的
熟练掌握计算机系统的ISA指令系统与寻址方式
熟练掌握Linux下调试器的反汇编调试跟踪分析机器语言的方法
增强对程序机器级表示、汇编语言、调试器和逆向工程等的理解
1.2 实验环境与工具
1.2.1 硬件环境
i5-9300H 16G内存
1.2.2 软件环境
Win10 Ubuntu20.04
1.2.3 开发工具
Visual Studio Codeblocks GDB EDB
1.3 实验预习
写出C语言下包含字符串比较、循环、分支(含switch)、函数调用、递归、指针、结构、链表等的例子程序sample.c。
生成执行程序sample.out。
用gcc –S或CodeBlocks或GDB或OBJDUMP等,反汇编,比较。
列出每一部分的C语言对应的汇编语言。
修改编译选项-O (缺省2)、O0、O1、O2、O3,-m32/m64。再次查看生成的汇编语言与原来的区别。
有目的地学习VS的功能GDB命令。
第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的破解与分析
密码如下:Wow! Brazil is big.
破解过程:
1.进入edb调试界面,点击运行程序。观察后使用单步进入按键进入bomb! phase_1的子程序中
2.分析phase_1函数发现,它调用了两个函数strings_not_equal和explode_bomb,猜测前者比较两个字符串是否相等,后者使炸弹爆炸。调用strings_not_equal函数后,进行了test指令,检验%eax是否为0,若为0则字符串相等跳转到leave,释放栈帧,否则,跳转到explode_bomb函数,程序爆炸。调用strings_not_equal函数之前的mov,esi,0x40314c中的立即数0x40314c中的内容就是第一关的密码,通过与用户输入的字符串进行比较来判断用户输入的字符串是否正确,因此只需要查看内存区0x40314c中的内容即可知道第一关的密码。
3.2 阶段2的破解与分析
密码如下: 1 2 4 8 16 32
破解过程:
rbp-0x30存输入的数据
检测输入的是否为6个数和第一个数是否为1,不是则爆炸
(核心步骤)循环5次检验后一个数是否为前一个数的两倍
3.3 阶段3的破解与分析
密码如下:switch(i)
case 0:269 case 1:374 case 2:384 case 3:885
case 1:710 case 1:986 case 1:713
破解过程:
- 尝试输入2和-227,观察栈中可知[rbp-4]存储第一个数,[rbp-8]存储第二个数
- 根据cmp函数和ja跳转,得出第一个数大于等于0且小于等于7
- 根据ax中存储的第一个输入数,跳转到rax*8+0x403170内存指示的地址,观察可知此时各地址处有不同的数被存到eax中与输入的第二个数比较,猜测这些数为答案,并进一步得出switch各选项。
3.4 阶段4的破解与分析
密码如下:
176 2
264 3
352 4
破解过程:
外层函数:
func4函数:
- 尝试输入77和3,程序首先初始化栈,检验输入数据是否为2个,调用func4函数
- 观察栈中可知[rbp-4]存储第二个数,[rbp-8]存储第一个数
- 根据cmp函数和jle跳转,得出第二个数大于1且小于等于4
- 对于func4函数,si、bx存第一个参数,di存第二个参数,ax存返回值。(初始情况两个参数分别为[rbp-4]和常数9)
- 分析后得递归结构
int func4(a, b)
if b=0 return 0;
else if b=1 return a;
else return func4(a, b-1) + func4(a, b-2) +a ;
3.5 阶段5的破解与分析
密码如下:
字符排序 | 1 | 2 | 3 | 4 | 5 | 6 |
Ascall码 | 0x_2 | 0x_5 | 0x_c | 0x_4 | 0x_f | 0x_7 |
对应字符 | 2"Bbr… | 5%Eeu… | ,Ll<\… | 4$Ddt… | /Oo?_… | 7'Ggw… |
密码:按上述顺序依次抽取每个元素位置对应的一种元素构成组合。
如 25<4o7, "%\$?', BELDOG ……
破解过程:
bx存有存输入的字符的地址,设为b
循环的初始条件是eax=0,终止条件是eax>5,每次循环结束eax的值会自动加1,每次循环开始时使cx等于ax
0x4031b0为首地址的数组存有一串字符r [16] = maduiersnfotvbyl
rbp-0x17为首地址的数组存结果,设为p
(核心步骤)取b[ax] & 0xf 结果为k ,r[k]的值存到p[ax] , 最后将p中结果与0x403169中的字符串比较
3.6 阶段6的破解与分析
密码如下:
6 4 2 3 1 5
破解过程:
(1)
检验输入的个数是否为6
rbp-0x40存有输入的六个数
eax记录外循环次数,edx记录内循环次数
检验输存在相同则爆炸,因此需要输1-6之间6个不同的数
(2)
rbp-0x40存有输入的六个数,设为p
cx存有循环次数n
取p[n] 为 k,将0x4052d0 + (k-1)*16 存入rbp + n*8 -0x70
完成后的堆栈情况:
(3)
ax存有循环次数n
cx初始值为rbp -0x70 中的地址值([cx]即链表节点地址,[cx+8]为下一项的地址)
取rbp + n*8 -0x70中存储的地址值k ,将k存到 [cx+8] ,然后将cx置为k
完成后的内存:
(4)
bx初始值为rbp -0x70 中的地址值,即链表首地址
检验按顺序(dword)0x4052d0 + n*16(即链表中的数据)值从小到大排列
最终得出大小关系大小为:node6<node4<node2<node3<node1<node5
3.7 阶段7的破解与分析(隐藏阶段)
密码如下:
破解过程:
第4章 总结
4.1 请总结本次实验的收获
首先,我通过本次实验更加熟练掌握了使用gdb和edb深入调试复杂程序,能更迅速准确地分析出汇编代码的逻辑与含义,进而推断出c语言代码,同时更清晰直观地了解了内存区与堆栈区的结构,受益匪浅。
4.2 请给出对本次实验内容的建议
建议老师可以多讲一些edb指令和常见功能的使用,还可以给出gdb更全面的使用方法。
注:本章为酌情加分项。