计算机系统基础实验 BombLab
本内容是本人的作业备份,仅作参考,不可抄袭!
实验任务概述:
本实验通过要求你使用课程所学知识拆除一个“binary bombs”来增强对程序的机器级表示、汇编语言、调试器和逆向工程等方面原理与技能的掌握。一个“binary bombs”(32位二进制炸弹,下文将简称为炸弹)是一个Linux可执行程序,包含了7个阶段(或层次、关卡)。炸弹运行的每个阶段要求你输入一个特定字符串,你的输入符合程序预期的输入,该阶段的炸弹就被拆除引信即解除了,否则炸弹“爆炸”打印输出 “BOOM!!!”。实验的目标是拆除尽可能多的炸弹层次。
每个炸弹阶段考察了机器级程序语言的一个不同方面,难度逐级递增:
➢ 阶段1:字符串比较
➢ 阶段2:循环
➢ 阶段3:条件/分支
➢ 阶段4:递归调用和栈
➢ 阶段5:指针
➢ 阶段6:链表/指针/结构
另外还有一个隐藏阶段(树型结构),只有当你在第4阶段的解后附加一特定字符串后才会出现。
为完成二进制炸弹拆除任务,你需要使用gdb调试器和objdump来反汇编炸弹的可执行文件并跟踪调试每一阶段的机器代码,从中理解每一汇编语言代码的行为或作用,进而设法推断拆除炸弹所需的目标字符串。比如在每一阶段的开始代码前和引爆炸弹的函数前设置断点。
实验步骤:
1.分析main函数
分析bomb.c
分析bomb.c可知,炸弹的运行机制:由read_line获取输入得到input,然后再将input传递给phase_1等函数,然后执行phase_1,如果执行正确,则拆弹成功,进入phase_2.
而(8048d0d)处为调用<strings_not_equal>函数前进行的入栈,并且传入了一个地址,猜测入栈的eax,就是题目要求的字符串B,而另一个入栈的0x8(%ebp)猜测就是输入的A
- b *(0x8048d17) 在此处设立断点,去看eax中的值
- x/s $ebp+0x8 这里将($ebp+0x8)中的内容入栈了,通过x/s查看其中的内容,发现是我们之前输入的“rrr”,可以得知返回的就是A,说明将A入栈了
- x/s $eax 以字符串的形式去看eax中存放的东西,得到字符串I turned the moon into something I call a Death Star. ,可知这就是我们要的字符串B
- 重新输入A= I turned the moon into something I call a Death Star. 顺利通过
(1)b*(0x8048d66)观察在调用函数<read_six_numbers>后内存的存放情况
(2)x/16wx $ebp-0x24查看从($ebp-0x24)开始,16个32位数的存放。可以发现从($ebp-0x24)~($ebp)存放的是输入的A B C D E F:0 1 1 2 3 4
(3)而分析(8048d66)和(8048d68)可以得知如果eax不等于0就会爆炸,而eax中存放的是($ebp-0x24)也就是A,则A必须为0
(4)b*(0x8048d6d) 这里有个cmp,如果eax!=1,就会爆炸。而根据(8048d6a)可知eax中存放的是($ebp-0x20)也就是B,则B必须为1
(5)b *(0x8048d9b) 可以得知6个数除了前两个数A,B,后面的数要通过前两个数相加得到。即A=0 , B=1 ,C=A+B,D=B+C ……,即最后的输出按照累加进行输出
- b*(0x8048e15) 调用<__isoc99_sscanf@plt>后,eax=输入的数字个数,这段代码表示如果eax<=1则爆炸,则输入的数字个数需要大于1。
- p/x $eax $eax=2,输入两个数顺利通过
- b*(0x8048e23) 这里将eax和7进行了比较,需要eax<=7.而这里eax=($ebp-0x1c),查看后发现就是第一个输入A,则A<=7
- p/x $eax $eax=4,发现eax等于输入的第一个数字A=4,而eax是被($ebp-0x1c)赋值的,下一步对($ebp-0x1c)进行查看
- x/4wx $ebp-0x1c 对从($ebp-0x1c)开始的内存查看四个32位的数据,可以发现从($ebp-0x1c)~( $ebp)分别存放的是:(A B C 输入的数字个数),而查看发现C=0,也就是(4 0 0 2)
- b *(0x 8048e78)将($ebp-0x1c)与5进行比较,而($ebp-0x1c)中存放的是第一个输入A,如果A>5就爆炸,所以A<=5
- b *(0x 8048e80)可以发现这里将经过L14~L22后得到的($ebp-0x14),与eax进行比较,而eax=($ebp-0x18)=B,所以这里需要将第二个输入B与C比较,如果B=C,则phase_3通过
- 那么如何得到C的值呢,通过观察发现(0x8048e34)处跳转指令的跳转地点与第一个输入有关,是一个跳转表的结构。
- b*(0x8048e34) 设置断点后,开始跟踪,发现不同的A会得到不同的C,如果输入A=4,则在L22结束后会输出C=0,这时再让输入B=0,即可通过。
- b *(0x8048f51) 这里调用函数<__isoc99_sscanf@plt>
- b*(0x8048f5c) 这里如果($ebp-0x18)=2,则通过,否则会爆炸。而通过测试,发现($ebp-0x18)=输入的数字个数,所以可知要输入2个数A,B,这里输入“13 3”进行测试
- b *(0x8048f65) 这里如果eax=0则爆炸,而eax=($ebp-0x20)
- x/4wx ($ebp-0x20) 观察从($ebp-0x20)地址开始的4个32位的内容,发现 (($ebp-0x20)~($ebp-0x14))内存放的是 (输入的A,B,输入的数字个数,未知D),
b *(0x8048f6c) 比较($ebp-0x20)和0xe,如果($ebp-0x20)<14,才可通过,也就是A<14
- b *(0x8048f88) 调用<func4>函数并且将(第一个输入A,0,0xe)送入栈
- 进入func4函数发现内部其实是个递归调用,其中有两次调用入口,分别是X口:(8048ee2)和Y口:(8048f06)
- b *(0x8048ecd) 这里比较eax与0x8(%ebp),
- p/x $eax发现eax=7,而0x8(%ebp)=第一个输入A,如果eax<A则调转到Y口,从Y口进下一轮递归,如果eax>A,则从X口进,如果eax=A,则直接跳转到(8048f15)
- b *(0x8048f15) 可以发现这里是给eax赋0,而测试可发现这里的eax即是func4的返回参数。
- b *(0x8048f96) 这里将-0x10(%ebp), -0x14(%ebp)进行比较,即需要将-0x10(%ebp)与D进行比较,由(6)知,D=3,而-0x10(%ebp)=eax=<func4>返回的参数E,所以如果E!=3,则爆炸,所以返回的参数需要等于3,E=3
- 如何让返回参数eax=E=3,观察func4函数发现,(0x8048f15)会给eax赋0,所以要避免走(0x8048f15),而只有A=eax时会进入(0x8048f15)。
- b *(0x8048ecd) 测试发现eax的值随着A的不同而变化,这里我们输入的A=0xd,这时发现eax进行三次分别值为7 b d,用ni的指令依次往下读
第三次eax=d,A=d,进入(0x8048f15)赋值eax=0
- 然后第一次从Y口返回,b*(0x8048f10) 将eax=1
- 第二次从Y口返回,b*(0x8048f0e) 将eax=2,b*( 8048f10) eax=eax+1=3
- b *(0x8048f96) 返回参数E=3,顺利通过
- b *(0x8048f9e) -0x1c(%ebp)= -0x14(%ebp),也就是B=D=3
- 得知输入A=13,B=3
- b *(0x8048fe8) 这里调用了<string_length>函数
- b *(0x8048ff3) 这里将$0x6,-0x18(%ebp)比较,x/wx $ebp-0x18 得到-0x18(%ebp)=输入的个数,所以这里要求输入的字符个数为6
- b *(0x8049046) 这里调用了<strings_not_equal>,可知使要比较输入字符串S与key字符串是否一致,这里输入字符串“rrrrrr”
- x/s $ebx-0x2484 可以看到这里存放“flyers”,猜测与key有关
- x/s $ebp-0x13 这里存放“dddddd”,这里本来应该是我们输入的“rrrrrr”,现在变成了dddddd,说明字符串发生了某种变换,比较对应关系
- b *(0x80490x18),读取0x140(%ebx,%eax,1)= m a d u i e r s n f o t v b y l,而观察两两对应关系,只需要可以发现“flyers”在其中的顺序为”9,15,4,5,6,7”, 说明输入字符串中对应位的字符的最低4位的数值等于"9,f,e,5,6,7",即可通过这一关。查看ASCII值,得到ionefg
- b *(0x804937b) 这里调用了<read_six_numbers>,可知是需要输入6个数字
- b*(0x80490xb5) 用ni指令一步一步看代码,发现这是一处(0x80490b5—0x8049105)循环,目的是判断6个数字彼此之间并不相等 ,功能指令在b *(0x80490ea),这里将eax,edx做了比较,
- b *(0x80490c7) 这里将eax与6比较,p/x $eax eax=输入的数字,说明输入要小于6所以需要输入6个小于6的数字,b *(0x80490be) 这里要求eax>0,所以要输入6个小于6大于0的数字
- b *(0x8049161) 这段循环将每个地址赋值分别对应输入数字所对应的代码
- b *(0x804919a) 这里将-0x4c(%ebp)地址里的内容赋值给%edx,将-0x4c(%ebp)+8地址的内容赋值给%eax,x/4wx $ebp-0x4c 查看可以发现更改后,
(3) 19c (4) b3 (5) d (6) 3bb (1) 14c (2) a8
- b phase_defused 在<phase_defused>函数上打断点
- b *(0x80499db) 这里将eax与0x6进行比较,如果eax=6才可通过,p/x $eax而经过测试发现,每通过一关,eax的数量就会加1,所以这里意思是只有在第6关通过后,才可打开
- b*(8049a07)处调用<__isoc99_sscanf@plt>,先看需要输入什么类型的数据。可以发现在调用前将两个特殊地址入栈,可能是需要输入的数据,可以查看一下。
- x/s $ebx-0x2231 得$0x804adcf=“%d %d %s”,即输入两个数字加一个字符串
- x/s $eax+0xf0 得$0x804d4f0=“13,3” ,即是在第4关的输入后面加一个字符串,这里我们输入“rrr”试一下
- b *(0x8049a12) 经过测试发现,-0x60(%ebp)如果输入两个数字就是2,再输入字符串就是3,所以这里是测试是否按“%d %d %s”格式输入。
- b *(0x8049a26) 这里调用了<strings_not_equal>,说明要比较输入字符串是否与内部字符串key相同。
- x/s $ebp-0x5c 查看结果可以发现 得到“rrr”说明这是我们输入的字符串,
- x/s $ebx-0x2228 得到“DrEvil”,这就是内部字符串key,在第四关输入的时候,输入“13 3 DrEvil”,即可进入第七关
- 这里进入secret_phase b *(0x8049272) 将0x0与-0x10(%ebp)比较
- x/wx ($ebp-0x10) 得到这里的-0x10(%ebp)是指输入的数字
- b *(0x8049278) 这里将$0x3e9与-0x10(%ebp),如果输入<=1001,才可通过,这里输入一个数A:7
- b *(0x8049293) 这里调用了<func7>函数
- 进入<func7>函数,b*0x80491ea 这里将0x0,0x8(%ebp)比较
- b *(0x80491fc)这里将%eax,0xc(%ebp)比较,如果eax<=($ebp+0xc),则进入(0x804921a),如果eax>($ebp+0xc),则进入下一轮递归
- x/4wx $ebp+0xc 发现$ebp+0xc=7,是输入A。
- p/x $eax 发现eax=24
- 所以如果eax>A,则进入递归,eax=24>A=7,所以进入下一轮递归
- c指令跳转到(0x80491fc) p/x $eax 发现eax=8,eax=8>A=7,进入下一轮递归
- c指令跳转到(0x80491fc) p/x $eax 发现eax=6,eax=6<A=7, 进入(0x804921a),经过测试发现eax每轮的值为24、8、6、1
- b *(0x804921f)这里将%eax,与0xc(%ebp)比较,如果相等则将eax=0
- p/x $eax eax=6 发现eax的值等于比A小的那个数,也就是A过不去的那个数,也就是如果eax=A,则将eax=0,而由b *(0x804929e)可知 这里将<func7>的输出值与4比较,如果不等就爆炸,所以我们知道通过<func7>要得到一个4的返回值,而这个返回值存放在eax里,也就是要使eax=4
- 如果要使eax=4,则应该避免让eax归0,所以eax!=A,所以A不能等于24、8、6、1这里(eax=6)!=(A=7),可以
- b*(0x8049242) 这里将eax=eax+1
- b*(0x49240)eax=eax+eax,可以发现如果递归三次从出口出,可以刚好使eax=4,即A=7可以使eax等于4
实验答案:
计算机系统基础实验 BombLab相关推荐
- 华中科技大学计算机系统基础实验3报告,华中科技大学计算机系统基础实验报告...
华中科技大学计算机系统基础实验报告 1 课 程 实 验 报 告 课程名称: 计算机系统基础 专业班级: 学 号: 姓 名: 指导教师: 报告日期: 2016年 5月 24 日 计算机科学与技术学院2 ...
- 计算机系统基础实验报告
计算机系统基础实验报告 语言 C++ 编译器 Dev C++ 实验一:数的机器级表示 编写无符号数的转换: unsigned int unsignedToValue(char binary[],int ...
- 计算机系统基础实验-LinkLab实验
这是大三时的实验课,很久以前的东西,应要求放出来,做的不是很好.linux永远都是很重要的,希望我和大家都记得这个.实际上做到第五阶段我就不会了. 实验课程名称:计算机系统基础 实验项目名称:Link ...
- 华中科技大学计算机系统基础实验3报告,华中科技大学计算机系统基础实验报告.doc...
文档介绍: 课程实验报告课程名称:计算机系统基础专业班级:学号:姓名:指导教师:报告日期:2016年5月24日计算机科学与技术学院目录实验1: 2实验2: 9实验3: 22实验总结 30 实验1:数据 ...
- 计算机系统基础实验01运算器算术运算
计算机系统基础 运算器算术运算 实验目的 掌握ALU的算术运算原理,熟悉ALU数据传送通路和数据传送方式. 实验环境 微机,配置Windows操作系统.LC-3仿真机软件. 实验内容 ALU数据传送通 ...
- 计算机系统基础实验:认识logisim软件、门电路逻辑功能测试(仿真)
通过logisim对逻辑电路进行分析 文章目录 目录 文章目录 前言 一.使用工具 二.实验过程 1.门电路绘制 2.真值表 总结 前言 计算机系统基础也开了实验课,实验内容是利用logisim软件进 ...
- 北京邮电大学计算机系统基础实验,第1章 计算机系统基础85666.ppt
第1章 计算机系统基础85666 盘青梅 gdpqm@126.com 总结:计算机的发展阶段 冯·诺依曼计算机模型(P14) 总线系统结构图 总线(Bus)是计算机各部件传输信息的公共通道.有数据总线 ...
- 计算机系统基础实验 pa1
文章目录 pa1 实验1.修复程序中的BUG 实验2. 表达式求值 2.1填充rules, 2.2 用regex匹配字符串,并将其放入相应的`Tokens`里 2.3 括号检测 pa1 实验1.修复程 ...
- 计算机系统基础实验——数据的机器级表示
实验2 数据的机器级表示 一 .求绝对值的函数 二. 求和函数addOK 三. 条件表达式x?y:z 四. 计算浮点数f的绝对值[f] 一 .求绝对值的函数 题目要求 /* *abs Val- 求x的 ...
最新文章
- 2018.10.26 NOIP模拟 瓶子 (dp/贪心)
- 【转载】ABAP中数据和对象的动态创建和调用
- 着墨中文lisp登入_Lisp的本质 - climbdream的个人空间 - OSCHINA - 中文开源技术交流社区...
- linux网络编程之用select方法实现io复用(基于udp)
- c均值算法的设计与实现_如何使用C链表实现 LRU 算法
- 安卓签名生成工具_ios app如何进行内测?ios app和安卓app的内测有何区别?
- [BZOJ3211] 花神游历各国 - 线段树
- Ubuntu20.04安装eBPF BCC
- Json学习总结(4)——Json基础知识回顾
- vce 题库导入_Visual CertExam(VCE)试题制作教程.pdf
- 酷睿i9 12900HX性能怎么样 i912900hx相当于桌面什么cpu
- iMac一体机安装苹果和Win7双系统
- python爬取喜马拉雅音频
- SpringBoot实现Java高并发秒杀系统之Service层开发(二)
- C语言程序设计案例式教程
- 如何为您的入耳式监听器制作定制的硅胶耳模
- JavaScript 静态方法
- 中国好SaaS走进海尔:企业关注重心从纯模式创新回归资源竞争
- 『互联网架构』软件架构-git服务搭建与使用(四)
- matebook13 java开发_紧急要跑程序?华为 MateBook X Pro一键搞定立马进状态