Binary Bomb 二进制炸弹--拆弹 哈工大计算机系统LAB2 2023春

第1章 实验基本信息

1.1 实验目的

  1. 熟练掌握计算机系统的ISA指令系统与寻址方式
  2. 熟练掌握Linux下调试器的反汇编调试跟踪分析机器语言的方法
  3. 增强对程序机器级表示、汇编语言、调试器和逆向工程等的理解

1.2 实验环境与工具

1.2.1 硬件环境

  1. X64 CPU;2GHz;2G RAM;256GHD Disk 以上

1.2.2 软件环境

Windows7/10 64位以上;VirtualBox/Vmware 11以上;Ubuntu 16.04 LTS 64位/优麒麟 64位 以上

1.2.3 开发工具

Visual Studio 2010 64位以上;CodeBlocks 64位;vi/vim/gedit+gcc

1.3 实验预习

  1. 上实验课前,必须认真预习实验指导书(PPT或PDF)
  2. 了解实验的目的、实验环境与软硬件工具、实验操作步骤,复习与实验有关的理论知识。
  3. 请写出C语言下包含字符串比较、循环、分支(含switch)、函数调用、递归、指针、结构、链表等的例子程序sample.c。
  4. 生成执行程序sample.out。
  5. 用gcc –S或CodeBlocks或GDB或OBJDUMP等,反汇编,比较。
  6. 列出每一部分的C语言对应的汇编语言。
  7. 修改编译选项-O (缺省2)、O0、O1、O3、Og、-m32/m64。再次查看生成的汇编语言与原来的区别。
  8. 注意O1之后缺省无栈帧,RBP为普通寄存器。用 -fno-omit-frame-pointer加上栈指针。
  9. GDB命令详解 –tui模式 ^XA切换  layout改变等等
  10. 有目的地学习: 看VS的功能,GDB命令用什么

第2章 实验环境建立

2.1 Ubuntu下CodeBlocks反汇编

CodeBlocks运行hello.c。反汇编查看printf函数的实现。

要求:C、ASM、内存(显示hello等内容)、堆栈(call printf前)、寄存器同时在一个窗口。

图2-1  Ubuntu下CodeBlocks反汇编截图

2.2 Ubuntu下EDB运行环境建立

用EDB调试hello.c的执行文件,截图,要求同2.1

图2-2  Ubuntu下EDB截图

第3章 各阶段炸弹破解与分析

3.1 阶段1的破解与分析

密码如下:When I get angry, Mr. Bigglesworth gets upset.

破解过程:

1.运行gdb bomb,设置断点 b phase_1

2.查看401409指令,它跳转到40140d爆炸。看401409之前的指令4013fd~401407,并看函数string_not_equal,看函数名和函数内容大致意思是比较输入的内容是否与%esi存储的内容是否一致,如果一致则令%eax为0,否则为1。

  

并且后面的test  %eax,%eax和jne 40140d则是判断若%eax不为0,就执行explode_bomb。因此需要输入的密码与%esi中的字符串相等。

3.%esi中的字符串来源于0x403150(mov $0x403150,%esi),查看0x403150存储的内容,得到第一个密码. 

4.验证:

3.2 阶段2的破解与分析

密码如下:1 2 4 8 16 32

破解过程:

1. 运行gdb bomb,设置断点 b phase_2

2.查看0x401421及上几条的指令,并查看read_six_numbers函数,看函数名猜测是要输入6个数。在401957指令有一个地址$0x403303,查看地址存放内容是%d %d %d %d %d %d。可见是要输入六个int型数。

  

3.输入六个int型数1 2 3 4 5 6查看成功运行到0x401421指令的下一条指令

  

4.查看接下来的指令,首先0x401462 cmpl 0x401426 $0x1,-0x30(%rbp)即比较1和和在-0x30(%rbp)里存的值,且值不等于1时爆炸,故第一个数必须等于1,往后面分析0x40142c mov $0x1,%ebx可知,%ebx的初始值为1,然后到0x40143e判断其是否大于5,大于5则跳出循环,每次循环一次,0x40143f 指令会让%ebx加1。

在第i次循环内,0x401447~指令,是将%ebx给%edx,此时%edx为上面%ebx的值; -0x1(rbx)给%eax,然后ctql 将%eax符号扩展到%rax,-0x30(%rbp,%rax,4)(查询可知这个地址存放是第i个输入值,具体解释看下面的注)给%eax, 接下0x401453add %eax,%eax是自加,也就是*2,然后是比较大小0x401455 cmp %eax,-0x30(%rbp,%rdx,4),-0x30(%rbp,%rdx,4)(查询可知这个地址存放是第i+1个输入值,具体解释看下面的注)若两者不相等则会爆炸。简单来说就是第i次循环,比较的是第i+1个输入的值是否是第i个输入值得两倍,若每次都是则可以拆弹。由于第一个数必须是1,所以接下来必然是2,4,8,16,32,拆弹完毕。

  

注:%rsp=-0x30(%rbp),所以-0x30(%rbp,%rax,4)是0x7ffffffe2f0+%rax*4,在寻这个地址时%rax里存放的是0,1,2,3,5所以-0x30(%rbp,%rax,4)对应地址和存放值是下图所示的,也就是我们输入的1,2,3,4,5

 

-0x30(%rbp,%rdx,4)是0x7fffffffe2f0+%rdx*4, %rdx里的值是每次循环%ebx的值,%ebx是1,2,3,4,5,所以对应的地址值和存放的值是下图所示的,也就是我们输入的2 3 4 5 6

 

5.验证:

 

3.3 阶段3的破解与分析

密码如下:0 -485;

或1 -1178或2 -504或3 -821或4 0或5 -821

破解过程:

1.在phase_3断点,先查看phase_3函数里的内容。查看输入的值是什么类型,查看0x40330f地址的内容,发现为”%d %d”,确定输入的是两个int型数据。

  

2. 接下来看__isoc99_sscanf@plt后的内容%eax,%eax为isco99sscanf的返回参数,小于等于1爆炸,所以至少有两个输入值,这也对应了前文说的%d %d,后面的指令是输入两个int型数据后要执行的指令。首先是mov -0x4(%rbp),%eax 和cmp $0x7,%eax,下一条跳转ja是超过(无符号>)所以它们的意思是输入的第一个值大于7则爆炸,所以第一个值应小于等于7的无符号数即第一个数有8种情况分别是0,1,2,3,4,5,6,7。

  

又下图可见,如果第一个输入大于5的数,就会跳转爆炸,因此第一个数只有0~5六种情况。

   

3. 接下来的指令401492 jmpq *0x4031c0(,%rax,8),可知跳转表在0x4031c0处

 

而switch的对象是%rax(%rax的值是输入的第一个值),而第一个值只有8种情况,所以表共有8项,0~7。因此用gdb的x指令看0x4031c0处开始的8个字节:

 

可知case 0 跳转到指令0x4014da,case 1跳转到指令0x4014a0,case 2跳转到0x4014e1,case 3跳转到指令0x4014e8,case 4跳转到指令0x4014ef,case 5跳转到指令0x4014f6,case 6跳转到指令0x4014fd,case 7跳转到指令0x401504,和图中标注一致。

也就是说,如图,十六进制转十进制之后,则第一个值为0时,eax此时为693;第一个值为1时,eax此时为0;第一个值为2时,eax此时为0;第一个值为3时,eax此时为0;第一个值为4时,eax此时为0;第一个值为5时,eax此时为0;第一个值为6时,eax此时为0;第一个值为7时,eax此时为0。

但由于如果输入大于5的值。前文已经证明会跳转爆炸,因此只用看0~5即可。

  

4. 之后根据赋值后的跳转(已经用相同颜色标出),进行一系列相应的加减法,得到最终值。

可得:0 -485;1 -1178;2 -504;3 -821;4 0;5 -821是最终答案。

 

 5. 验证:

所有答案按顺序验证如下:

 

3.4 阶段4的破解与分析

密码如下:36 3

破解过程:在phase_4设置断点,先看phase_4函数内容。

1.先看红框里的内容,熟悉的格式,先看0x40334f里的内容,发现是“%d %d”,接下来的指令是%eax作为输入的返回值与2比较,如果不相等则爆炸,所以可知我们必须输入两个int型数据。

  

2.分析接下来的指令,红框的指令是将第一个参数传给%eax,然后%eax先与1比较,如果eax小于等于1就跳转爆炸,说明第一个参数不能是负数。绿框的指令是将4与%eax比较,然后按条件跳转,因为下一条指令是爆炸,所以我们要让指令跳转,所以第一个参数还应x小于等于4。现在1<第一个参数<=4,蓝框中的指令是把第一个数传给%esi, 5传给%edi, 然后调用了func4()。所以接下来看func4的内容。

    

3.易知这是一个递归求解的过程。先假设输入2 3,然后在401589处查看第二个数的数值,因为此处是其第一次出现。(查看结果见下第二张图)

 

      由rax=3可知第二个数就是3

4. 现在查看第一个数值应该是多少,我观察发现最后一次比较是在4015a5处,进行正确性判定,将处理过的eax和输入数值判定。所以我们查看此地址处rax的值,发现等于36,因此可知第一个数应该是36,我们进行一下尝试,如下图,发现正确。

 

5. 验证:

 

3.5 阶段5的破解与分析

密码如下:013457(或者其他数组数值相加为44的六个数的数组下标)

破解过程:

1.先看phase_5的内容,它调用了string_length函数,然后比较6和%eax,不相等则爆炸,可见%eax是string_length的返回值,查看这个函数,发现它是计算输入的字符串的长度。由此我们知道要输入一个长度为6的字符串。

  

2.看phase_5之后的指令,看两个红框的内容可知,初始化eax为0;每次循环eax=eax+1,直到eax大于5跳出循环,并且跳转到指令0x4015f5。按照红框里的内容就是要循环6次。

蓝框中是循环的内容,它令rdx=eax,edx=%rbx+%rdx*1地址里的值,再将edx和15进行按位与,这是将输入字符拓展为32位给%edx再取%edx的后四位,之后将地址0x403200+4*%rdx内的数值加上ecx的值,并赋值给ecx。实际上这一系列的操作是在第i次(0<=i<=5)循环里将i个字符的对应ASCALL码的二进制值保留后四位存入edx。然后将0x403200+4*%rdx,也就是提取了每次数组中对应元素加上ecx的值,并赋值给ecx,也就是六次提取的数组元素的和。

另外,阿拉伯数字0的ASCII码是48(32+16),1是49,依此类推,所以当我们取阿拉伯数字的ASCII码的后四位时,也就相当于取了这个数字。所以我们输入的是什么数字,rdx中就是什么数字。

    

3. 退出循环后比较ecx(加和的结果)和0x2c(44)是否相等,不等则炸弹爆炸。

  

 因此可知,只需要输入6个数组下标,然后这6个数相加得44就好了。数组存在0x403200中,获取数组,计算相加便得到结果。

 

4. 我们可以找出其中一组答案:44=2+10+1+12+16+3

易知它的下标是013457

5. 验证成功

 

3.6 阶段6的破解与分析

密码如下:6 5 3 4 1 2

破解过程:

1.先看phase_6的内容,调用了read_six_number函数,查看这个函数。查看这个地址,发现是“”%d %d %d %d %d %d”,红框里的内容就是判断是否输入六个数,没有就炸,所以现在我们知道要输入六个int型的数据。

  

​​​​​​​2. 阅读接下来的这段反汇编可知,这是一个二重循环,外层循环由r12d控制,内层循环由ebx控制,由红框中的指令可知,输入的参数必须大于等于1,小于等于6。由蓝框中的指令可知这六个数是互不相等的。由此可知要输入的内容是1 2 3 4 5 6的一个序列。

    

3. 同时可知输入的123456序列是六个节点的序列,1,2,3,4,5,6就代表第1,2,3,4,5,6个节点。指令中有一个很明显的地址0x4052d0,查看这个地址,存储可第一个节点,内容包括数值,后继节点地址,节点名。根据后继节点地址查看所有节点内容。大红框里就是一个二重循环,将这个链表按数值从大到小进行排序,蓝框里就是个节点数值大小,所以排序后节点序列应该是653412,然后黄框里就是在比较a1,a2,a3,a4,a5,a6序列是否和653412相同,不相同则爆炸,所以密码是6 5 3 4 1 2。

  

     

4. 验证:

 

3.7 阶段7的破解与分析(隐藏阶段)

密码如下:36

破解过程:

  1. 查找发现有且仅有phase_defused里面调用了secret_phase。如下图,可分析这段内容,并查看所有出现的明码地址。可以发现在阶段4时,如果没有附加字符串,就会如蓝框所示提示拆弹成功进入阶段5,如果附加特定字符串“DrEvil”,就会如红框所示提示发现隐藏炸弹。

    

2.分析secret_phase(),红框内容中%ebx存储了输入的密码,由cmp $0x3e8,%eax知,输入的是一个数,这个数减一后无符号大于0x3e8爆炸,所以这个数应该大于等于1,小于等于1001。分析蓝框中的内容并查看这些立即数可知,%eax作为fun7的返回值,若它为空(即为0时)则拆弹成功。立即数0x4050f0存储的内容是根节点,有一棵二叉树,接下来分析fun7。

   

3.分析fun7可知它是一个递归函数对二叉树进行查询操作,它有两个参数,一个是结点地址,一个是查询值,若节点地址的值等于查询值时,返回0,否则根据值的大小查询左子树右子树。将其转化为c代码有 

     

由于最终要求返回值eax是0,易知就是根节点,所以应该输入根节点的数值,如下图,可得为0x24=36,因此答案是36。

  

最后验证:

 

第4章 总结

4.1 请总结本次实验的收获

进一步学习了汇编语言,以往很多的疑惑都在拆弹过程中得到了解决。将学习的知识在实际问题中应用,加深了记忆,理解。

4.2 请给出对本次实验内容的建议

非常好,个人觉得是很有趣的实验,每次拆完一个炸弹都很有成就感!!!有很多收获。​​​​​​​


参考文献

为完成本次实验你翻阅的书籍与网站等

[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.

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值