cmu二进制炸弹

本篇文章参考了:http://www.cnblogs.com/remlostime/archive/2011/05/21/2052708.html大神的文章,有时候没思路了会来看一下,但是保证本文的每个阶段都是自己独立思考后总结写出来的。

Phase_1

对于phase1,我们只要关注一下红色框两行的代码,分别是将内存0x8049678的处的字符串A和ebp+0x8处的字符串B作为参数来调用strings_not_equal子程序,那么这里的逻辑也很明了——要想知道要求我们输入的字符串,只要查看内存0x8049678处的字符串就可以了:


读到phase_4终于想明白为啥DWORD PTR [ebp+0x8]代表的是子程序接受的参数了,子程序调用的模型如下图所示:


ebp+0x4是跨越ebp的4个字节,再加4是跨越返回地址的4个单元,就是这样



Phase_2

首先我们还是关注红色的部分,phase_2将eax和[ebp+0x8]这两处的值作为参数传递给<read_six_numbers>子程序,在这里:push eax是因为phase_2在子程序调用后还要用到eax的值,而调用的子程序恰好也要用到eax的值,为了维护eax,caller选择将其压栈,这也是保存eax的一种方法;而[ebp+0x8]处的值则是程序从键盘上读取的我们的输入,作为调用phase_2的参数,而对于这个参数的安放,是整个phase_2最关键的地方!

这两行是read_six_numbers子程序内部的两行代码,首先ebp+0x8处是传递给该子程序的参数,即phase_2的ebp+0x8,即我们键盘输入的6个数。然后该proc用sscanf从该输入中读取数据——放到哪里呢?

没错,就是phase_2子程序的绿色一行,如果不加以严谨的测试,我们只通过看代码,黄色的一行设置esi的指定位置,以及后续的循环过程,都能帮助我们推测出read_six_numbers的sscanf函数就是将输入的字符串读取到了[ebp-0x20]这个位置

如果最科学的做法应该是这样的:我们在绿线的那行设置断点,然后执行程序,然后对第2个函数的参数输入23 x x x x x,x是随机一个整数(不超过int范围),然后我们再观察[ebp-0x20]处的DWORD,就会发现这个值是23——这就证明了我们上面的猜测~



Phase_3

首先看刚开始的红色部分,都是作为调用sscanf函数的参数来压栈的,首先第一个红框不难看出是用来存储参数,那么那个内存地址里面是啥呢?观察一下就可以明了:

没错,就是传递sscanf函数所需要的字符串格式的参数,然后我们从[ebp+0x8]所指向的内存中来读取我们所需要的内容到相应的位置即可

还有一点需要注意,就是绿色框的switch选择语句,我们可以通过相应的指令显示出该内存地址后面的所有16进制内容:

那么到底该选择哪一个呢,我们再看下面的黄色语句,他告诉我们其中一个参数的值是必须要小于等于5的,也就是eax*4<=20,即我们最多可以选择到0x8048bcc这条内存地址,然后从第一个地址到底6个地址任选一条来运算,求得的答案都可以通过phase_3,后面的算数过程没什么难度,就不细说了。



Phase_4:

同phase_3查看内存0x804996b处的值,可以看到是“%d”,可见sscanf是input读取一个数字的,这点通过后面的返回值eax也可以看出来。

黄色框说明我们输入的这个数一定是个正数。

绿色的框告诉我们func4(input)的返回值是144D(0x90),思路也很显而易见,我们关注func4函数的返回值即可

这是func4函数的disassembly-code,首先棕色的框可以看出每次调用子程序用ebx来保存参数的值

然后就是判断参数的值,如果大于1,就调转到偏移地址为20的地方,反之则跳转到50偏移地址处,中间具体的运算过程在下面给出:

func(1):1

return 1

func(2):2

esi = 0

esi += func(1) = 0+1 = 1

ebx = 2-2 = 0    NO

return esi+1 = 1+1 = 2

func(3):3

esi = 0

esi += func(2) = 0+2 = 2

ebx = 3-2 = 1    NO

return esi+1 = 2+1 = 3

func(4):5

esi = 0

esi += func(3) = 0+3 = 3

ebx = 4-2 = 2    OK

esi += func(2-1) = 3+1 = 4

ebx = 2-2 = 0    NO

return esi+1 = 4+1 = 5

func(5):8

esi = 0

esi += func(4) = 0+5 = 5

ebx = 5-2 = 3    OK

esi += func(3-1) = 5+2 = 7

ebx = 3-2 = 1    NO

return esi+1 = 7+1 = 8

func(6):13

esi = 0

esi += func(5) = 0+8 = 8

ebx = 6-2 = 4    OK

esi += func(4-1) = 8+3 = 11

ebx = 4-2 = 2    OK

esi += func(2-1) = 11+1 = 12

ebx = 2-2 = 0    NO

return esi+1 = 12+1 = 13

func(7):21

esi = 0

esi += func(6) = 0+13 = 13

ebx = 7-2 = 5    OK

esi += func(5-1) = 13+5 = 18

ebx = 5-2 = 3    OK

esi += func(3-1) = 18+2 = 20

ebx = 3-2 = 1    NO

return esi+1 = 20+1 = 21

func(8):34

esi = 0

esi += func(7) = 0+21 = 21

ebx = 8-2 = 6    OK

esi += func(6-1) = 21+8 = 29

ebx = 6-2 = 4    OK

esi += func(4-1) = 29+3 = 32

ebx = 4-2 = 2    OK

esi += func(2-1) = 32+1 = 33

ebx = 2-2 = 0    NO

return esi+1 = 33+1 = 34

func(9):55

esi = 0

esi += func(8) = 0+34 = 34

ebx = 9-2 = 7    OK

esi += func(7-1) = 34+13 = 47

ebx = 7-2 = 5    OK

esi += func(5-1) = 47+5 = 52

ebx = 5-2 = 3    OK

esi += func(3-1) = 52+2 = 54

ebx = 3-2 = 1    NO

return esi+1 = 54+1 = 55

func(10):11

esi = 0

esi += func(9) = 0+55 = 55

ebx = 10-2 = 8    OK

esi += func(8-1) = 55+21 = 76

ebx = 8-2 = 6    OK

esi += func(6-1) = 76+8 = 84

ebx = 6-2 = 4    OK

esi += func(4-1) = 84+3 = 87

ebx = 4-2 = 2    OK

esi += func(2-1) = 87+1 = 88

ebx = 2-2 = 0    NO

return esi+1 = 88+1 = 89

func(11):

esi = 0

esi += func(10) = 0+89 = 89

ebx = 11-2 = 9    OK

esi += func(9-1) = 89+34 = 123

ebx = 9-2 = 7    OK

esi += func(7-1) = 123+13 = 136

ebx = 7-2 = 5    OK

esi += func(5-1) = 136+5 = 141

ebx = 5-2 = 3    OK

esi += func(3-1) = 141+2 = 143

ebx = 3-2 = 1    NO

return esi+1 = 143+1 = 144

一定要注意每次调用结束后esi的值都还要变回调用前的,也就是一直是0,这儿被坑了好久。。


Phase_5:

前面没什么好说的,绿色部分是循环体,作用是把phase_5的参数经过变换后转移到ecx所指向的地址中,edx作为循环变量从1到6

很容易得知题目给我们的提示是转换后的字符串等于内存0x80496c2起始的内容,我们查看这个内容

在这里转换后的字符没什么用,转换后的ASCII码是我们破解这层炸弹的关键,而每个ASCII码的获得如图一红色方框所示:

先将原操作数的ASCII码存到eax中,然后保留其后四位,再将后四位当成偏移地址来寻找相应的新的ASCII码

根据0x80496c2中的6个数字,我们可以反过来分别推出原来6个char的ASCII码的后四位,然后我们可以测出abcdef的ASCII码的后四位,发现是从0001开始增长的,这样可以列出a-z的后四位ASCII码,然后将相应的字符带入即可(此题有4种答案都是正确的)

转换后        al           转换前

116/t        1101        m

105/i        0000        p

116/t        1101        m

97/a        0101        e/u

110/n        1011        k

115/s        0001        a/q


Phase_6:

这题是对我智商的侮辱,我拒绝贴出来。


secrete_phase:

这个炸弹折腾了能有一个周,今天下午把第6个拆出来了,感觉对汇编的兴趣并不是太大,就没再做这个,不过我参考的文章里有对secrete_phase的详解释,大家可以去看。

时间: 2024-10-14 00:17:25

cmu二进制炸弹的相关文章

二进制炸弹实验(持续更新)

一.前期准备 首先,既然这是CSAPP这本书上的实验,我们就得想办法找到书上的实验素材,不能随便自己编炸弹.这里课本上给了一个卡内基梅隆大学的edu网址csapp.cs.cmu.edu,然而,防火墙阻挡了我们的脚步.这里给大家两种解决思路: (一)多费点时间精力,CSDN博客园上有少量博主曾在博客里共享过CSAPP的实验资源,例如这一个,亲测可下载: (二)直接选择科学上网工具,搭梯子即可. 因为二进制炸弹实验网上有很多破解教程,所以写这个炸弹素材的人就很坏,我发现他隔几个月就会发布一版更新炸弹

逆向工程之二进制炸弹第一发

 down了二进制炸弹实验,名字就很酷是不是.简要介绍下,二进制炸弹是一个可执行文件,运行时,提示用户输入6个不同的字符串,如果其中的任何一个不正确,炸弹就会爆炸.初步判断有六个级别,难度逐级递增.这个实验需要学生通过对程序反汇编和逆向工程来判断是哪6个答案,从而拆除它的炸弹. 文档里面提示用到了gdb和objdump,那么问题来了.第一步怎么做? 照惯例我神游了一番,然后打开objdump –help翻看帮助,有个-t 参数,可以打印程序的符号表,据我所知符号表里面存储的是一些函数名和变量名,

二进制炸弹(第二次实验)

实验目的 本实验通过要求你使用课程所学知识拆除一个"binary bombs"来增强对程序的机器级表示.汇编语言.调试器和逆向工程等方面原理与技能的掌握. 一个"binary bombs"(二进制炸弹,下文将简称为炸弹)是一个Linux可执行程序,包含了6个阶段(或层次.关卡).炸弹运行的每个阶段要求你输入一个特定字符串,你的输入符合程序预期的输入,该阶段的炸弹就被拆除引信即解除了,否则炸弹"爆炸"打印输出 "BOOM!!!"

逆向工程实验---二进制炸弹(CSAPP Project)

本实验设计为一个黑客拆解二进制炸弹的游戏.我们仅给黑客(同学)提供一个二进制可执行文件bomb和主函数所在的源程序bomb.c,不提供每个关卡的源代码.程序运行中有6个关卡(6个phase),每个关卡需要用户输入正确的字符串或数字才能通关,否则会引爆炸弹(打印出一条错误信息,并导致评分下降)! 要求同学运用GDB调试工具和objdump反汇编工具,通过分析汇编代码,找到在每个phase程序段中,引导程序跳转到"explode_bomb"程序段的地方,并分析其成功跳转的条件,以此为突破口

CMU-CSAPP-Lab2拆解二进制炸弹

一. 实验目的 1.理解C语言程序的机器级表示. 2.初步掌握GDB调试器的用法. 3.阅读C编译器生成的x86-64机器代码,理解不同控制结构生成的基本指令模式,过程的实现. 二.实验工具 SecureCRT Linux Objdump命令反汇编 GDB调试工具 三.实验内容 登录bupt1服务器,在home目录下可以找到Evil博士专门为你量身定制的一个bomb,当运行时,它会要求你输入一个字符串,如果正确,则进入下一关,继续要求你输入下一个字符串:否则,炸弹就会爆炸,输出一行提示信息并向计

《CSAPP》实验二:二进制炸弹

二进制炸弹是第三章<程序的机器级表示>的配套实验,这章主要介绍了x64汇编,包括:操作数的表示方式,数据传送指令,算术和逻辑指令,控制流跳转指令,过程(procedure)的实现与运行时栈帧,C语言中的数组,struct,union以及浮点数的汇编表示等.通过这章的学习,对C有了更深的理解,可以看出,C与汇编代码的相似度很高,称之为高级汇编也不为过. 这个实验提供了一个 Linux/x86-64 二进制程序(下载地址:CSAPP: Labs),即所谓的"二进制炸弹".执行这

读完了csapp(中文名:深入理解计算机系统)

上个星期最终把csapp看完了. 我买的是中文版的,由于除了貌似评价不错以外,由于涉及到些自己不了解的底层东西,怕是看英文会云里雾里.如今看来,大概不能算是个长处,可是的确可以加快我的看书速度,否则一星期还真不大可能把这书搞定. 对csapp慕名已久,主要在于据说这本书尽量的做到相对实用,不去讲那些和实际编程没多大关系的计算机原理(毕竟是著名计算机院校里面最偏软件的cmu的作品),重点很得当,像我这样的没有本科科班出生又不想去死读些不知道以后有没实用的东西的人来说,最是适合了.感兴趣的东西就行再

CSAPP Lab2: Binary Bomb

著名的CSAPP实验:二进制炸弹 就是通过gdb和反汇编猜测程序意图,共有6关和一个隐藏关卡 只有输入正确的字符串才能过关,否则会程序会bomb终止运行 隐藏关卡需要输入特定字符串方会开启 实验材料下载地址:http://csapp.cs.cmu.edu/2e/labs.html 下面通关解法: 反汇编: objdump -d bomb > bomb_assembly_32.S Phase 1: 打开bomb_assembly_32.S,定位到<phase_1>函数,可以看到以下代码:

CSAPP Bomb Lab记录

记录关于CSAPP 二进制炸弹实验过程 (CSAPP配套教学网站Bomb Lab自学版本,实验地址:http://csapp.cs.cmu.edu/2e/labs.html) (个人体验:对x86汇编寻址模式要有清晰的了解,如mov指令涉及的是计算出的地址所指向的存储单元的值,而lea指令保留的是计算出来的地址,数字是否加$表示常数的问题等: 实验中涉及的跳表的存储方式.链表的处理等是C语言的汇编语言实现方式,处理起来较为复杂,但可对这些方式的对象底层实现方式有一个较为清晰的了解: 涉及指针操作