计算机系统实验之二进制炸弹

实验报告

计算学部

目  录

第1章 实验基本信息

1.1 实验目的

1.2 实验环境与工具

1.2.1 硬件环境

1.2.2 软件环境

1.2.3 开发工具

1.3 实验预习

第2章 实验环境建立

2.1 Ubuntu下CodeBlocks反汇编(10分)

2.2 Ubuntu下EDB运行环境建立(10分)

第3章 sum剖析

3.1 导致异常的临界n值(最小n值)是多少(5分)

3.2 论述找到临界n值的整个过程 (5分)

3.3 为什么是这个值?通过gdb调试验证并分析说明(10分)

第4章 炸弹破解与分析

4.1 阶段1的破解与分析

4.2 阶段2的破解与分析

4.3 阶段3的破解与分析

4.4 阶段4的破解与分析

4.5 阶段5的破解与分析

4.6 阶段6的破解与分析

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

第5章 总结

5.1 请总结本次实验的收获

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

参考文献

第1章 实验基本信息

1.1 实验目的

熟练掌握计算机系统的ISA指令系统与寻址方式

熟练掌握Linux下调试器的反汇编调试跟踪分析机器语言的方法

增强对程序机器级表示、汇编语言、调试器和逆向工程等的理解

1.2 实验环境与工具

1.2.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 实验预习

上实验课前,必须认真预习实验指导书(PPT或PDF)

了解实验的目的、实验环境与软硬件工具、实验操作步骤,复习与实验有关的理论知识。

请写出C语言下包含字符串比较、循环、分支(含switch)、函数调用、递归、指针、结构、链表等的例子程序sample.c。

生成执行程序sample.out。

用gcc –S或CodeBlocks或GDB或OBJDUMP等,反汇编,比较。

列出每一部分的C语言对应的汇编语言。

修改编译选项-O (缺省2)、O0、O1、O3、Og、-m32/m64。再次查看生成的汇编语言与原来的区别。

注意O1之后缺省无栈帧,RBP为普通寄存器。用 -fno-omit-frame-pointer加上栈指针。

GDB命令详解 –tui模式 ^XA切换  layout改变等等

有目的地学习: 看VS的功能,GDB命令用什么?

第2章 实验环境建立

2.1 Ubuntu下CodeBlocks反汇编(10分,选做)

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

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

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

2.2 Ubuntu下EDB运行环境建立(10分,选做)

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

图2-2  Ubuntu下EDB截图

3章 sum剖析

3.1 导致异常的临界n值(最小n值)是多少(5分)

262003

3.2 论述找到临界n值的整个过程 (5分)

首先手动依次输入n,根据二分法判断得到n在261800到262500。

因为尝试的过程中发现每次运行sum可执行文件,n是不固定的,但是在gdb中运行的时候每次n是固定值,是因为在gdb中发现rsp寄存器每次初始值和结束值是固定的,所以n不变。那么考虑会不会是sum可执行文件由于系统的栈随机化导致每次结果不一样,输入echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

来暂时取消栈随机化的功能,再次验证,发现这次运行sum可执行文件,每次结果都一样了。

得到sum1和sum2的临界值n为262003。

3.3 为什么是这个值?通过gdb调试验证并分析说明(10分)

在gdb过程中观察rsp寄存器的值从0x7fffffffddf0到0x7fffff7feff0,就得到以下内容并退出。0x7fffff7feff0是rsp寄存器的栈顶,再超出就会爆栈。

接下来分析sum的汇编代码。

经过单步调试,可知在进入sum函数时候,rsp寄存器的值会减8来存储返回地址,随后又push %rbp来保存调用者的栈帧基址指针,此时rsp寄存器的值又减8,随后通过sub来使rsp寄存器的值减16,来为当前函数局部变量分配空间,故调用一次sum函数需要减去32个字节。

而0x7fffffffddf0减去0x7fffff7feff0得到十进制数8384000,8384000/32=262000,这与结果几乎一致,故合理。


4章 炸弹破解与分析

每阶段20分,密码10分,分析10分,总分不超过60分
(如果第二章没做,本章最高总分为80分)

4.1 阶段1的破解与分析

密码如下:I am just a renegade hockey mom.

破解过程:

先在gdb bomb中观察main函数如下图,可知在调用phase_1之前先要调用read_line读入字符串返回到%rax,并mov至%rdi。

随后为了测试,先输入字符串xby666,并用disas来反汇编phase_1函数,发现在phase_1函数中,string_not_equal是通过判断输入的字符串%rdi和%esi中地址为0x403150的字符串是否相等来决定是否爆炸,如果相等那么%eax为0,不会跳转到explode_bomb,即不会爆炸。

读取%rdi的值,发现就是刚刚输入的xby666,而地址为0x403150的字符串就是第一阶段的答案。

4.2 阶段2的破解与分析

密码如下:1 2 4 8 16 32

破解过程:

先得到phase_2的反汇编代码,发现调用了read_six_numbers函数,可能是输入六个数来判断。分析之后得到循环流程,为了直观,通过下图C代码来展示,即答案应该是以1为首项,2为公比的等比数列,为1、2、4、8、16、32。

4.3 阶段3的破解与分析

密码如下:5 y 841、4 w 498...(不止一组解)

破解过程:

得到上图phase_3的反汇编代码,发现调用了sscanf,而sscanf的返回值%eax为匹配成功的个数,%eax在大于2的情况下才不会bomb,所以猜测至少要输入三个值。接下来查看输入类型,查看地址为0x40319e的值为%d %c %d,所以先按照这个格式输入5 x 7来测试。

由8-16行可知传入了三个地址,在后面查看地址的值,发现这三个地址存放的正是输入的三个值。

在40行可知,把5传给了%eax,并与7作比较,如果比7大就会bomb,这里我们可以得知第一个数应该要小于等于7。

随后跳转到229行,判断第三个值是否和0x349一致,不一致则bomb,可得十进制表示为841。

接着继续测试,到了第320行,要比较第二个值和与%eax中后八位的0x79是否一致,不一致则bomb,可得字符为y。

所以结果为 5 y 841。经过观察发现不止一组解,因为是一个switch语句,例如第一个数为4时,后面对应的就是w 498,经过测试4 w 498也是一组解。

4.4 阶段4的破解与分析

密码如下:14 45

破解过程:

在phase_4的反汇编代码中,第26行要读入两个值,否则bomb。在第39行判断第一个值是否为负数,如果是负数则bomb。接下来在第43行判断第一个值是否小于等于14,否则bomb。在第66行调用func4,如果返回值不是45,则bomb,在第76行判断第二个值是否等于45,否则bomb。所以第一个值的确定关键就在于func4内部。

分析之后为了更加直观,用C代码来写func4函数,并在main函数中调用phase_4函数,因为第一个值只能在1到14之间,所以遍历这十四种情况,发现只有第一个值为14的时候,func4的返回值为45,所以结果为14 45。

4.5 阶段5的破解与分析

密码如下:CGILON(不止一组解)

破解过程:

由第17行可知要输入一个六位的字符串,之后进入循环,其中计数器%eax从0到5每循环一次加1,%ecx为累加器,当六次循环之后,%ecx的值如果为50,那么拆弹成功,问题在于%ecx怎么累加。%ecx每次会加上(0x403200+4*%rdx)地址的值,查看发现0x403200是一个数组的首地址。

而%edx为(%eax+%rbx)中地址的值与0xf做按位与,即只取低四位值,取值范围为0-15,正好可以取到上图中的16个数组元素,因为%eax是从0到5的,而%rbx存储的正是输入的六位字符串首地址,这里以123456为例。

因为char是一字节,所以在六次循环中,(%eax+%rbx)中地址的值分别就是字符串的六位。那么就是每次只取一个字符对应的ASCII二进制的后四位去找数组对应元素。在数组中随便取一组1 3 7 11 13 15,对应的位置分别是3 7  9 12 15 14,再找一组对应的字符为CGILON,拆弹成功!分析过程可知这道题的解非常多。

4.6 阶段6的破解与分析

密码如下:6 2 5 3 4 1

破解过程:

第17行可知要读入六个数,这里先输入6 7 8 9 2 4来测试。

观察第13行发现把%rbp-0x40的地址传给了寄存器,猜想就是刚刚输入的六个数组元素,每四字节打印一个值得到下图,发现正是输入的6 7 8 9 2 4。

经过分析,发现第一个循环是个嵌套循环,第一部分为了控制元素的范围小于等于6,注意第90行是ja,所以是无符号比较,同时保证大于等于1,嵌套中的第二部分保证了不能有元素相等。为了直观,编写了如下C语言代码。

根据上述分析,输入1 2 4 3 6 5来继续测试,发现0x4052d0是一个链表头节点的地址,如下图所示。

验证一下,发现node1的4215550的十六进制表示正是node2的地址,所以node1 -> next = node2。

之后进入下一个循环,发现又有一个新地址为%rbp-0x70作为数组b,经过分析,这个循环是为了根据输入数组的值,按照下标把链表中节点的地址赋给数组b,如下为C语言代码。

下一个循环是为了把b数组中的节点地址依次连接,得到新的一条链表。

而最后一个循环是为了保证链表中的元素是递增的,否则bomb。

分析之后,便可逆向思维,按照原链表中的节点数值进行排序,即node6->node2->node5->node3->node4->node1。显然answer就是6 2 5 3 4 1。

拆弹成功!

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

密码如下:47

破解过程:

发现main函数中并没有直接的隐藏关卡入口,但每个phase结束之后都有一个phase_defused,决定考察一下这个函数。

经过测试,发现0x3c2c(%rip)的值每通过一个phase,都会加1,从1一直到6,即这两行的目的是为了检查是否前六关全部通过。

随后注意到这几行在传参,关注一下0x403399和0x405870。

可知需要输入3个参数,其中两个是之前第四题答案,而最后一个是字符串。如果匹配到不是三个参数,那么会正常显示第六关通关,随后结束。

如果匹配到三个参数,那就要确认第三个参数是不是answer。

发现0x4033a2的值就是DrEvil,这就得到了第三个参数。

在第四题答案后补上DrEvil,成功进入隐藏关卡。

第17行的atoi函数把输入字符串变成整数,并且这个值小于等于0x3e9即1001,否则bomb,接下来把0x4050f0赋值给%edi,可知这是一个节点的地址。

随后进入fun7函数,并将返回值与5比较,如果不相等则bomb,如果相等那么得到下图,拆弹结束。

所以问题关键在于fun7函数内部,下面分析fun7。

下面先探讨一下%rdi是什么,发现和0x4050f0相关,看一下发现有一堆节点,而每个节点都是32个字节,有四个值,推测第一个值是value,第二个和第三个都是地址,而第四个均为0,可能是结构体为了对齐。这样的数据结构,很容易猜到是二叉树,数一下有15个节点,推测为4层满二叉树。

为了直观,编写C语言代码如下。

接下来考虑5怎么通过递归凑出来,5=2*(2*(2*0+1))+1,所以按照fun7的递归来说,就是要先走右儿子,再走左儿子,最后走右儿子。也就是在n46节点处递归返回0,然后在n33节点返回2*0+1,在n22节点返回2*(2*0+1),最后在n1节点返回2*(2*(2*0+1))+1=5。所以input为n46节点的值,即47。


第5章 总结

5.1 请总结本次实验的收获

通过本次实验学会了如何使用gdb,能够自主的分析出汇编代码的意思,读懂汇编代码。更了解程序运行的内部逻辑,对linux的使用更加熟练自如。

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

  • 18
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值