目录

  • 实验概述
    • 2.2 实验内容及过程
      • 2.2.1 阶段1 字符串比较
      • 2.2.2 阶段2 循环
      • 2.2.3 阶段3 条件/分支
      • 2.2.4 阶段4 递归调用和栈
      • 2.2.5 阶段5 指针
      • 2.2.6 阶段6 链表/指针/结构
      • 2.2.7 阶段7 隐藏阶段

实验概述

  • 实验目的:增强对程序的机器级表示、汇编语言、调试器和逆向工程等方面原理与技能的掌握。
  • 实验目标:需要拆除尽可能多的炸弹。
  • 实验要求:使用gdb调试器和objdump来反汇编炸弹的可执行文件,并单步跟踪调试每一阶段的机器代码,从中理解每一汇编语言代码的行为或作用,进而设法“推断”出拆除炸弹所需的目标字符串。
  • 实验语言:c。
  • 实验环境:linux(root用户名为vicai)

2.2 实验内容及过程

一个“binary bombs”(二进制炸弹,下文将简称为炸弹)是一个Linux可执行C程序,包含了6个阶段(phase1~phase6)。炸弹运行的每个阶段要求你输入一个特定的字符串,若你的输入符合程序预期的输入,该阶段的炸弹就被“拆除”,否则炸弹“爆炸”并打印输出 "BOOM!!!"字样。实验的目标是拆除尽可能多的炸弹层次。

每个炸弹阶段考察了机器级语言程序的一个不同方面,难度逐级递增:

  • 阶段1:字符串比较
  • 阶段2:循环
  • 阶段3:条件/分支
  • 阶段4:递归调用和栈
  • 阶段5:指针
  • 阶段6:链表/指针/结构
  • 另外还有一个隐藏阶段,但只有当你在第4阶段的解之后附加一特定字符串后才会出现。
  • 为了完成二进制炸弹拆除任务,你需要使用gdb调试器和objdump来反汇编炸弹的可执行文件,并单步跟踪调试每一阶段的机器代码,从中理解每一汇编语言代码的行为或作用,进而设法“推断”出拆除炸弹所需的目标字符串。这可能需要你在每一阶段的开始代码前和引爆炸弹的函数前设置断点,以便于调试。

通过gdb调试bomb程序:

通过执行以下指令,可以反汇编bomb,并将结果保存到bomb.asm文件中,然后通过gedit或more可以方便地察看汇编代码:

2.2.1 阶段1 字符串比较

  1. 任务描述:通过phase_1的反汇编代码找出要输入的字符串;
  2. 实验设计:利用gdb结合断点来动态地分析;
  3. 实验过程:
    观察phase_1的反汇编代码,如图2.1.1所示:

    通过分析,发现在调用strings_not_equal对比字符串之前,有两个压栈的指令,其中一个是将函数入参送入栈中,还有一个地址送入了栈,函数入参应该就是输入的字符串所在地址,猜测另一个地址就是正确字符串的首址,于是在phase_1处下个断点,然后运行,随意输入一个字符,触发断点,再用x命令查看字符串。如图2.1.2所示:

    故猜测“Public speaking is very easy.”就是所需字符串。重新执行该程序,直接输入该字符串,观察结果。如图2.1.3所示:
  4. 实验结果:如图2.1.3所示,阶段一拆弹成功!
    阶段一很简单,找出字符串首地址就可以了,没有什么大的难点。
    为了提高调试效率,可以将解析的结果保存到文件中,在调试时以参数方式提供给程序运行,方法如下:
    第一步:建立一个参数文件,比如“b.txt”文件,然后用vim或gedit编辑该文件,写入“Public speaking is very easy.”:

2.2.2 阶段2 循环

  1. 任务描述:通过phase_2的反汇编代码推断第二阶段要输入的数据;
  2. 实验设计:利用gdb结合断点来动态分析;
  3. 实验过程:
    观察phase_2的前一部分反汇编代码,如图2.2.1所示:

    a) 由1处可发现输入的应该是6个数字,而且通过<read_six_numbers>将字符串拆分为6个数,存入ebp -0x18的位置上,可能是通过数组存储;
    b) 在2处马上就比较了第一个数:cmpl $0x1, -0x18(%ebp),说明输入的第一个数如果不是1,那么炸弹就将爆炸;
    c) 紧接着进入了一个循环,关键语句为cmp %eax,(%esi,%ebx,4)。其中,%eax可根据前一条语句计算得出值为1×2=2,而(%esi,%ebx,4)中存储的是后面输入中的5个数其中的一个。比较前后两者,如果不满足“第n个数的值=第n-1个数的值×n”就爆炸;

    由图2.2.3可知,%ebx寄存器的值就是用来计数的,inc之后表示当前为第n个数,当n大于5时就退出循环。而每次循环都会进行以上的判断,当循环结束时,如果都符合要求则本关通过。推测可能的代码如下:
1.   if (arr[0] != 1)  explode_bomb();
2.  for (int i = 1; i <= 5; i++) {
3.      if ((i+1) * arr[i-1] != arr[i])
4.          explode_bomb();
5.  }

由此可以得到答案为1 2 6 24 120 720,验证结果如下:

2.2.3 阶段3 条件/分支

  1. 任务描述:通过phase_3的反汇编代码推断第三阶段要输入的数据;
  2. 实验设计:利用gdb结合断点来动态地分析;
  3. 实验过程:
    观察phase_3的前一部分反汇编代码,由图2.3.1可知内部含有sscanf函数,猜测是格式字符串,而sscanf输入了3个参数,但格式未知。

    由图2.3.2可知,通过gdb调试得到sscanf输入数据格式为:整数,字符,整数。

    进一步查看汇编代码,发现第一个数要小于等于7,而紧接着跳转到0x80497e8这个地址。

    可是后面的代码中又都可以跳转到<phase_3+0xf7>这个位置,猜测可能是switch语句,如果是则需要查找跳转表。

    检测内存值,发现全部为phase_3内的地址,验证了switch语句的猜想。

    既然要求第一个数小于等于7,那么先用0进行测试。由图2.3.5可知。eax为0时就跳转到0x8497e8指向的位置(若为1则跳转到0x8048c00,以此类推),同时还可以看到0x80497eb存储的内容为0x8048be0。
    由图2.3.1已知ebp-0x4中存储的是第3个参数,由图2.3.6可看到其值需要为0x309=777D。同时还设置了bl=0x71,用je跳转到了0x8048c8f。

    来到0x8048c8f,发现是将bl的值与ebp-0x5(由图2.3.1已知存储着第2个参数)进行比较,字符值为0x71,换算成字符为’q’。

    因此答案为0 q 777(根据第一个数字不同,还可以是1 b 214等等)最终结果如下:

2.2.4 阶段4 递归调用和栈

  1. 任务描述:通过phase_4以及func4的反汇编代码推断第四阶段要输入的数据;
  2. 实验设计:利用gdb结合断点来动态地分析;
  3. 实验过程:

首先还是观察phase_4的反汇编代码,由图2.4.1可知依然是sscanf;

再次进行调试,由图2.4.2可知输入是一个整数,且由图2.4.1可知该参数必须大于0;

由图2.4.3可知,数据传入到了func4函数中,且返回值必须为0x37=55D,此时需要进一步探明func4函数得到输入参数;

由图2.4.4不难发现,func4存在自身调用的情况,推测是递归结构;

由此推测伪代码如下:

int func4 (int n) {  if (n <= 1)  return 1;  else  return func4(n-1) + func4(n-2);
}

通过计算得出n=9时,返回值即为0x37=55D,验证结果如下:

2.2.5 阶段5 指针

  1. 任务描述:通过phase_5的反汇编代码推断第五阶段要输入的数据;
  2. 实验设计:利用gdb结合断点来动态地分析;
  3. 实验过程:
    首先由图2.5.1可知,字符串长度必须为6;

    用户输入字符串后,首地址存储到ebx中,而esi为模式串首地址;

    由图2.5.1可以看出,用户输入字符串后,低4位的值作为索引,找到模式串中该索引对应的字符,放入新数组中。其流程图如图2.5.3所示:

    根据图2.5.4的调试结果,已知模式串与匹配串如下:
pat[]="isrveawhobpnutfg\260\001";  // 模式串
str[]="giants";  // 匹配串


用户输入后需要pat[ecx[i]]=str[i],其中i in (0,5),因此
ecx[6]={15,0,5,11,13,1},但用户是从键盘输入的字符,这些值在ASCii对应的字符无法从键盘输入。
而每个字符8位,低4位不能改变,因此高四位可以任意加1,于是可能的一种结果为ecx[6]={ 79,80,69,75,77,65},对应字符OPEKMA,验证结果如图2.5.5所示;

2.2.6 阶段6 链表/指针/结构

  1. 任务描述:通过phase_6的反汇编代码推断第五阶段要输入的数据;
  2. 实验设计:利用gdb结合断点来动态地分析;
  3. 实验过程:
    由图2.6.1可以看出,依然是首先读入6个数字,存放在ebp-0x18的地方,推测可能是数组的首地址;

    图2.6.1

观察图2.6.2中代码结构,发现是与阶段2相同的循环,根据汇编代码,尝试写出其伪码如下:

for (int i = 0; i<=5; i++) {  if (arr[i] >= 6)  explode_bomb();  for (int j = i+1; j <= 5; j++) {  if (arr[i] == arr[j])  explode_bomb();  }
}


图2.6.2
循环结束后,进入了第二部分,由图2.6.3发现esi=ebp-0x34,但此时ebp-0x34的内容未知;

图2.6.3
于是在文件内进行查找,由图2.6.4发现其位于函数开头,值为0x804b26c,结构类似字符串;

图2.6.4
为了确定我们的猜测,如图2.6.5进行调试,但打印只显示一个node1,此时推断esi可能是结构体;

图2.6.5
而之前在第二部分中,曾看到图2.6.6中mov 0x8(%esi),%esi的操作,这非常类似于链表中node=node->next的行为;

图2.6.6
根据图2.6.4已知esi值为0x804b26c,不妨通过调试验证链表的猜想。结果如图2.6.7所示;可见首尾地址相同(已用同一颜色标出),就是链表;

图2.6.7
由图2.6.8可推测第二部分伪码如下,其功能为:
输入6个数字,如3 4 1 2 5 6,则原来链表中第3个元素排到第一位, 第4个元素排到第二位,第1个元素排到第三位,以此类推……

for (int i = 0; i <= 5; i++) {  for (int j = 0; arr[i] > j; j++) {  node = node->next;  }  a[i]= node; // a[i]是一个新数组
}


图2.6.8

第二部分结束,观察剩余代码,发现第三部分功能为“重新串接链表”,如图2.6.9所示,第四部分功能位“检测链表值是否位降序”,如图2.9.10所示;

图2.6.9
图2.6.10

此外已由图2.6.7得知,原链表各结点值分别为fd、2d5、12d、3e5、d4、1b0,即253、725、301、997、212、432,因此输入为4 2 6 3 1 5

图2.6.11
如图2.6.12所示,完成了炸弹的拆除任务!

图2.6.12

2.2.7 阶段7 隐藏阶段

  1. 任务描述:找出隐藏阶段开启方式并且拆除隐藏阶段的炸弹;
  2. 实验设计:利用gdb结合断点来动态地分析;
  3. 实验过程:
    不难发现,反汇编代码中只有<phase_defuse>、<secret_phase>、< fuc7 >尚未调用。于是观察<phase_defused>代码,如图2.7.1所示,一共有2个比较,分别是“与常数0x6”和“与字符串”的比较;

    图2.7.1

结合隐藏阶段的开启条件,推测与0x6的比较是指在阶段6完成后,才能开启隐藏阶段。为了验证这个猜想,首先需要知道0x804b480中的值,警告调试,如图2.7.2可知初始值为0;

图2.7.2

在第6阶段设下断点,如图2.7.3所示,通过前面5个阶段后0x804b480的值变为了6,说明猜想是正确的;

图2.7.3

再看看老朋友sscanf,由图2.7.1可知0x8049d03中的内容送入了sccanf函数,通过调试得知输入格式为数字+字符串;那么由图2.7.1可知另一个地址0x804b770中可能存放的就是第一个数字;

图2.7.4

在phase_6设置断点(不运行至此0x804b770始终为空),由图2.7.5可知,第一个数字为9,与第4阶段输入内容相同,推测是在第4阶段输入的数据后加上一段字符串以开启隐藏阶段;

图2.7.5

回到图2.7.1,可以看到字符串首地址为0x8049d09,用x命令观察,如图2.7.6所示,因此我们尝试在第4阶段输入“9 austinpowers”;

图2.7.6

如图2.7.7所示,成功开启了隐藏阶段。因此现在我们回到<secret_phase>函数,开始着手隐藏阶段的炸弹拆除任务;

图2.7.7

如图2.7.8可观察到输入的字符串被转换成了整数,且整数val减1后与1000进行了比较,尝试输入1001,结果如图2.7.9所示,意外成功拆除了炸弹;

图2.7.8

图2.7.9

计算机组成原理 / 反汇编实验(2)拆弹实验相关推荐

  1. 杭电 2016 计算机组成原理,杭电计算机组成原理多功能ALU设计实验

    <杭电计算机组成原理多功能ALU设计实验>由会员分享,可在线阅读,更多相关<杭电计算机组成原理多功能ALU设计实验(6页珍藏版)>请在人人文库网上搜索. 1.杭州电子科技大学计 ...

  2. 计算机组成原理时序与启停实验,计算机组成原理时序与启停实验.doc

    <计算机组成原理时序与启停实验.doc>由会员分享,提供在线免费全文阅读可下载,此文档格式为doc,更多相关<计算机组成原理时序与启停实验.doc>文档请在天天文库搜索. 1. ...

  3. 计算机组成原理微机接口及应用实验,QY-JSJ03

    计算机由运算器.存储器.控制器.输入设备和输出设备五大部件组成,指令(程序)和数据以二进制不加区别地存储在存储器中,程序自动运行.计算机组成原理是计算机专业的一门专业基础课,是硬件课程.通过学习,可以 ...

  4. 头歌计算机组成原理汉字字库存储芯片扩展实验

    全部答案点击底部 <?xml version="1.0" encoding="UTF-8" standalone="no"?> ...

  5. 概念模型计算机实验总结,计算机组成原理——cpu的简单模型实验报告

    #cpu与简单模型机 姓名:学号: 班级:计科班 实验名称:CPU与简单模型机实验性质:综合型实验时间:2018.12.1 一.实验目的 (1) 掌握一个简单 CPU 的组成原理. (2) 在掌握部件 ...

  6. 计算机组成原理——cpu的简单模型实验报告

    #cpu与简单模型机 姓名: 学号: 班级:计科班实验名称:CPU与简单模型机 实验性质:综合型实验 时间:2018.12.1 一.实验目的 (1) 掌握一个简单 CPU 的组成原理. (2) 在掌握 ...

  7. 《计算机组成原理》课程设计任务书——TEC-2实验系统——微程序设计

    一.目的和要求 深入了解计算机各种指令的执行过程,以及控制器的组成,指令系统微程序设计的具体知识,进一步理解和掌握动态微程序设计的概念:完成微程序控制的特定功能计算机的指令系统设计和调试. 二.实验环 ...

  8. 本科课程【计算机组成原理】 - 存储器工作原理实验

    大家好,我是[1+1=王], 热爱java的计算机(人工智能)渣硕研究生在读. 如果你也对java.人工智能等技术感兴趣,欢迎关注,抱团交流进大厂!!! Good better best, never ...

  9. 计算机组成原理时序与启停实验,计算机组成原理时序与启停实验

    实验九 一.实验目的 ⒈ 掌握时序电路的原理. ⒉ 熟悉启停电路的原理. 时序与启停实验 二.实验原理 图 7-9-1 时序.启停.单次脉冲原理图 在日常生活中,我们学习.工作和休息都有一个严格的作息 ...

  10. 合肥学院计算机原理,合肥学院计算机组成原理实验三-20210415130709.docx-原创力文档...

    精品文档 精品文档 PAGE 精品文档 合肥学院计算机组成原理实验三 --------------------------------作者:------------------------------ ...

最新文章

  1. 网易云信亮相LiveVideoStackCon2020,分享RTC中AI音频算法产品化经验
  2. 更改Java包名称如何改变我的系统架构
  3. phoengap–node+websocket在线聊天室
  4. 双RocketMq集群的搭建
  5. SpringBoot :SpringBoot自动配置原理
  6. Python: subprocess.Popen()不支持unicode问题解决
  7. vue 点击文字input_vue input实现点击按钮文字增删功能示例
  8. 一个光标绘制问题的解决过程
  9. bzoj 1602: [Usaco2008 Oct]牧场行走(暴力LCA)
  10. javaScript 判断一个数是不是质数(素数)
  11. 尚学堂马士兵linux教程之文件管理
  12. hibernate复习第(三)天
  13. Uncaught SyntaxError The requested module ‘node_modules.vitevue.jsv=50ccac76‘ does not provide
  14. Java由浅入深,考试or面试专用(自我整理)
  15. 苹果退款_苹果如何退款
  16. 2022下半年软件设计师中级考试通过
  17. 3U VPX XC7VX690T计算处理板
  18. 计算机非全日制硕士 选校,非全日制研究生如何来选择学校呢?
  19. 华为鸿蒙HarmonyOS,华为鸿蒙HarmonyOS 2.0
  20. wps插入visio流程图

热门文章

  1. 在服务端录制语音视频
  2. 1 error and 0 warnings potentially fixable with the `--fix` optio
  3. uniapp报错:Browserslist: caniuse-lite is outdated. Please run next command `npm update`
  4. Windows 2016 服务器安全配置和加固
  5. sphinx mysql连表查询_sphinx
  6. 基于FPGA的乒乓ram控制系统设计
  7. FITC-LCA 绿色荧光标记小扁豆凝集素
  8. java中两个数组的并集_Java数组并集
  9. 三极管、MOSE管的作用总结
  10. 好用的谷歌浏览器插件