参考教材:计算机系统基础 第二版 袁春风 机械工业出版社
参考慕课:计算机系统基础(四):编程与调试实践 https://www.icourse163.org/learn/NJU-1449521162

计算机系统实验导航

实验一:环境安装 https://blog.csdn.net/weixin_46291251/article/details/122477054

实验二:数据的存储与运算 https://blog.csdn.net/weixin_46291251/article/details/122478255

实验三:程序的机器级表示 https://blog.csdn.net/weixin_46291251/article/details/122478979

实验四:二进制程序逆向工程 https://blog.csdn.net/weixin_46291251/article/details/122479554

实验五:缓冲区溢出攻击 https://blog.csdn.net/weixin_46291251/article/details/122479798

实验六:程序的链接 https://blog.csdn.net/weixin_46291251/article/details/122480049

实验源码: xxx

准备

实验内容:

1 二进制炸弹实验的内容、方法和基本步骤;
2 程序机器级表示、分析与调试基本知识和方法的应用。

实验目标:

1 加深对程序的机器级表示、汇编与反汇编、二进制程序分析与调试、逆向工程等方面知识
的理解和掌握;
2 从程序员角度认识计算机系统,分析高级语言对应的机器行为及其对程序执行结果和性能
的影响,解决计算机系统设计、程序开发过程中的关键问题。
3 掌握各种开源的编译调试工具。

实验任务:

1 学习 MOOC 内容

https://www.icourse163.org/learn/NJU-1449521162
第五周 二进制程序逆向工程
第 1 讲 二进制炸弹实验:概述
第 2 讲 二进制炸弹实验:字符串比较
第 3 讲 二进制炸弹实验:浮点数表示
第 4 讲 二进制炸弹实验:课后实验

2 完成作业

一个二进制炸弹是-个Linux 可执行程序,包含了多个阶段(又称为层次、关卡)。在炸
弹程序运行的每个阶段要求输入一个特定字符串,如果该输入字符串符合程序的要求,该阶段的炸弹就被拆除了,否则炸弹“爆炸_即打印输出 “BOM!!” 的提示。
每个炸弹阶段考察了程序与数据的机器级表示的不同方面,难度逐级递增:
●阶段0:字符串比较
●阶段1 :浮点数表示
●阶段2 :循环
●阶段3 :条件/分支
●阶段4 :递归调用和栈
●阶段5:指针
●阶段6 :链表/指针/结构
●另外还有一个隐藏阶段作为阶段7,只有在阶段4的拆解字符串后附加一特定字符串后,才能在实验最后进入隐藏阶段。

实验的目标是拆除尽可能多的炸弹关卡一分析获得 尽可能多的正确拆解字符串。

运行二进制炸弹可执行程序bomb需要指定0或1个命令行参数(详见bomb.c源文件中
的main0函数):
如果运行时不指定参数,则程序打印出欢迎信息后,期望你按行输入每-阶段用来拆
除炸弹的字符串,程序根据输入字符串决定是通过相应阶段还是引爆炸弹导致该阶
段任务失败。
也可将拆除每一炸弹阶段的字符串按行(- 行-个字符串)记录在一个文本文件(必
需采用Unix/Linux换行格式)中(即实验结果提交文件的形式),然后将该文件作为
运行二进制炸弹程序时的唯- -命令行参数,程序将依次检查对应每一阶段的字符 串
来决定炸弹拆除成败。
注意:如果拆解字符串(来自命令行输入或文本文件)不正确导致相应炸弹阶段被引爆,
程序在输出炸弹爆炸的提示文字“BOM!!” 后,将进入下一阶段的字符串检查(等待命令行
输入或读取文件下一行)而不会终止程序的运行。因此,如果暂时未能正确获得某阶段的拆解字符串,可用任意非空字符串(即不同于空格、制表、换行的一个以上字符)临时作为拆解字符串,从而在引爆相应炸弹阶段后,跳到以后阶段继续开展实验。

phase0:字符串

实验结果记录

首先将实验文件中的bomb文件反汇编得到bomb.s文件

进入bomb.s找到phase_0函数的入口:
这里利用less打开文件,然后输入/phase_0搜索关键词,然后按N快捷键找到匹配的函数入口位置(这里是第二次出现的位置),这样就找到了phase_0的汇编代码,如下图所示:

分析phase_0的汇编代码,以了解其执行逻辑:
第一行汇编语句是push %ebp,目的是将ebp寄存器在main函数中的旧值压入栈中保存。
然后第二条汇编指令 mov %esp %ebp,把保存了ebp旧值的存储单元地址作为当前栈帧的起始地址,并保存于栈帧基址寄存器ebp中。执行完后,ebp中就存放了phase_0的栈真的起始地址。以后就可以用ebp的地址加偏移量来定位phase_0的各个成员以及其实参的存放位置。
下面两条sub语句分别从栈顶指针寄存器esp中减去了0x8,它们实际上完成了对栈帧空间的分配和。
接下来的三条语句分别是push、pushl和call语句。

这三条语句完成了对一个名为strings_not_equal的调用,且这个函数位于0x8049c61这个偏移量上。其中第一个push语句把函数的最后一个参数值为常量0x804a1e0的地址压入栈中,第二个pushl语句把函数的第一个参数(ebp寄存器+0x8地址对应的内容,实际上是传递给phase_0函数的第一个参数的值)压入栈中。
Call函数访问了strings_ not equal函数,分析该函数的汇编代码可知:该函数如果输入的两个字符串参数的内容相同, strings_ not equal函数将返回0。
接下来的test指令测试eax寄存器即strings_ not equal函数的返回值是否为0。

Test如果成立,则在示例汇编代码中, test指令测试时, 将使得je指令跳转到程序的正常结束位置。反之,如果两个字符串的内容不一致,将调用explode. bomb函数引爆炸弹。
故可知成功解开炸弹的关键是通过test,而test是判断strings_ not equal返回0,strings_ not equal返回0的条件是判断的两个字符串相等,这两个字符串一个是程序读入的钥匙,另一个是位于0x804a1e0的一个内置字符串

所以可以推断,位于0x804a1e0的字符串就是题目的解。
下面通过gdb调试的方法查看位于0x804a1e0的内置字符串的具体值。

结果分析与讨论

打开gdb调试程序,断点设置在phase_0里面调用strings_not_equal函数的额call指令的位置

由反汇编文件得知其位于0x8049465的位置,在这个位置设置断点然后开始运行。
运行后程序要求输入字符串,随便输入一个字符串后程序运行到断点的位置。
然后利用x/1s 0x804a1e0查看位于0x804a1e0位置的一个字符串。
输出的结果即为第一个阶段的答案。

运行程序,输入上述获得的第一个阶段的答案,可见成功解开了炸弹,顺利来到第二个关卡。

phase1:浮点数表示

实验结果记录
进入bomb.s找到phase_1函数的入口:
这里利用less打开文件,然后输入/phase_1搜索关键词,然后按N快捷键找到匹配的函数入口位置(这里是第二次出现的位置),这样就找到了phase_1的汇编代码,如下图所示:

其中三个指令为:

分别表示:
将一个整型数值传送到地址为-0xc(%ebp)的存储单元中
将其中的值加载到浮点寄存器栈顶
从浮点栈顶将值存储到地址为-0x18(%ebp)的存储单元
即可以理解为用一个整型常量0x97684a1对-0x18 (%ebp)中存储的浮点数进行初始化。

然后程序用一个push指令将一些数据压入栈中并进一步调用sscanf函数,此函数按照格式字符串参数的指示,从其第一个参数所对应的输入字符串中读出数据。

0x8(%ebp)中存储了传入本阶段phase 1主函数的第一个参数,即在本阶段输入的字符串的地址。
此阶段完成从输入字符串中读入本阶段所需要的整型数字对的过程。

对ssca nf函数返回时存储于eax寄存器中的返回值进行检查。该返回值是sscanf成功读入的数据单元的数量。
当读入的整数数量为两个时,将跳转到后续检查继续执行,否则将调用explode_ bomb引爆炸弹。
当确实读入两个整数时,程序将进一步对两对存储单元进行比较,不相等时也将引爆炸弹。
这个部分按照程序内置的常量对读入的数据进行检查。

结果分析与讨论
首先来查看程序内置的数值为多少:

将整型值0x97684a1通过浮点栈转为双精度浮点表示,并传送到本阶段函数栈帧中地址为-0x1 8(%ebp)处开始连续存放。

查看sscanf读入的格式字符串:
用gdb查看得到:

第二个整数的地址对应第四个函数调用参数,即第一个压栈的参数。-0x20(%ebp)
第一个整数的地址对应第三个函数调用参数,即第二个压栈的参数。-0x1c(%ebp)

-0x18(%ebp):浮点数
-0x1c(%ebp):第1个输入整数
-0x20(%ebp):第2个输入整数

下面分析两个输入数值与浮点数进行比较的指令处理逻辑。

前两个指令将存放于-0x18(%ebp)处的浮点数的低四个字节,传送到edx寄存器中。
第三条mov指令将存放于-0x1c(%ebp)处的第1个输入整数,传送到eax寄存器中。
最后比较两个寄存器中的内容,如果不相等则通过jne指令跳转到explode_ bomb函数
引爆炸弹,否则继续下阶段比较。

前三条指令将存放于-0x14(%ebp)处的浮点数的高四个字节,传送到edx寄存器中。
第四条mov指令将存放于-0x20(%ebp)处的第2个输入整数,传送到eax寄存器中。
比较两个寄存器中的内容,如果相等则通过je指令跳转到函数正常结束,否则调用explode bomb函数引爆炸弹。

基于以上分析可知,输入字符串中的一对整数,分别对于程序中浮点数的高32位和低32位,
前面我们看到该浮点数的值来自整型值0x97684a1,
对应的十进制:158762145
对应的二进制:1001011101101000010010100001
即1.001011101101000010010100001 *2^27
符号s为0,指数e为27,有效数字M为1.001011101101000010010100001
符号域sign = s,值为0,二进制位为0。
指数域exp = E + Bias,值为1050,11bit的二进制位为10000011010
小数域0.frac=M - 1,值为0.001011101101000010010100001
52bit的frac域二进制为001011101101000010010100001 加25个0
因为frac域截取了前52位,所以没有位不被精确表示,得到的是一个准确值
合并符号域sign、指数域exp、小数域frac得到浮点数的二进制位。
0100000110100010111011010000100101000010000000000000000000000000
其对应的双精度浮点数的IEEE 754表示为(十六进制字节序列,从高位到低位) :41a2ed0942000000
低32位(从高位到低位)转为十进制有符号整数:41a2ed09 =1101196553
高32位(从高位到低位)转为十进制有符号整数:42000000 =1107296256
因此,本实验阶段的拆解字节串应为:1101196553 1107296256

附:代码main函数部分

1.#include <stdio.h>
2.#include <stdlib.h>
3.#include "support.h"
4.#include "phases.h"
5.
6./*
7. * Note to self: Remember to erase this file so my victims will have no
8. * idea what is going on, and so they will all blow up in a
9. * spectaculary fiendish explosion. -- Dr. Evil
10. */
11.
12.FILE *infile;
13.
14.int main(int argc, char *argv[])
15.{16.    char *input;
17.
18.    /* Note to self: remember to port this bomb to Windows and put a
19.     * fantastic GUI on it. */
20.
21.    /* When run with no arguments, the bomb reads its input lines
22.     * from standard input. */
23.    if (argc == 1) {
24. infile = stdin;
25.    }
26.
27.    /* When run with one argument <file>, the bomb reads from <file>
28.     * until EOF, and then switches to standard input. Thus, as you
29.     * defuse each phase, you can add its defusing string to <file> and
30.     * avoid having to retype it. */
31.    else if (argc == 2) {32. if (!(infile = fopen(argv[1], "r"))) {33.     printf("%s: Error: Couldn't open %s\n", argv[0], argv[1]);
34.     exit(8);
35. }
36.    }
37.
38.    /* You can't call the bomb with more than 1 command line argument. */
39.    else {40. printf("Usage: %s [<input_file>]\n", argv[0]);
41. exit(8);
42.    }
43.
44.    /* Do all sorts of secret stuff that makes the bomb harder to defuse. */
45.    initialize_bomb();
46.
47.    printf("Welcome to my fiendish little bomb. You have 7 phases with\n");
48.    printf("which to blow yourself up. Have a nice day!\n");
49.
50.    /* Warm up phase! */
51.    input = read_line();             /* Get input                   */
52.    if( phase_0(input) ) {           /* Run the phase               */
53.        phase_defused();             /* Drat!  They figured it out! */
54.        printf("Well done! You seem to have warmed up!\n");
55. }
56.
57.    /* Hmm...  Six phases must be more secure than one phase! */
58.    input = read_line();             /* Get input                   */
59.    if( phase_1(input) ) {           /* Run the phase               */
60.        phase_defused();             /* Drat!  They figured it out! Let me know how they did it. */
61.        printf("Phase 1 defused. How about the next one?\n");
62. }
63.
64.    /* The second phase is harder.  No one will ever figure out
65.     * how to defuse this... */
66.    input = read_line();
67.    if( phase_2(input) ) {68.        phase_defused();
69.        printf("That's number 2.  Keep going!\n");
70. }
71.
72.    /* I guess this is too easy so far.  Some more complex code will
73.     * confuse people. */
74.    input = read_line();
75.    if( phase_3(input) ) {76.        phase_defused();
77.        printf("Halfway there!\n");
78. }
79.
80.    /* Oh yeah?  Well, how good is your math?  Try on this saucy problem! */
81.    input = read_line();
82.    if( phase_4(input) ) {83.        phase_defused();
84.        printf("So you got that one.  Try this one.\n");
85. }
86.
87.    /* Round and 'round in memory we go, where we stop, the bomb blows! */
88.    input = read_line();
89.    if( phase_5(input) ) {90.        phase_defused();
91.        printf("Good work!  On to the next...\n");
92. }
93.
94.    /* This phase will never be used, since no one will get past the
95.     * earlier ones.  But just in case, make this one extra hard. */
96.    input = read_line();
97.    if( phase_6(input) ) {98.        phase_defused();
99. }
100.
101.    /* Wow, they got it!  But isn't something... missing?  Perhaps
102.     * something they overlooked?  Mua ha ha ha ha! */
103.
104.    return 0;
105.}

计算机系统实验四:二进制程序逆向工程相关推荐

  1. 计算机系统实验六:程序的链接

    参考教材:计算机系统基础 第二版 袁春风 机械工业出版社 参考慕课:计算机系统基础(四):编程与调试实践 https://www.icourse163.org/learn/NJU-1449521162 ...

  2. 计算机系统实验:二进制炸弹+缓冲区炸弹 (自我学习笔记)

    本来没想写个博客,结果得知还要验收,发现自己全忘了,那就趁着复习的功夫再捋一遍吧>-< 一.使用工具:IDA-pro 简单使用方式: 1.打开IDA,open需要反汇编的exe. 选则wi ...

  3. 哈工大计算机系统实验四——链接

    链接这一块呢,先看了李春凤老师的慕课,然后看一遍课本,然后来做实验,感觉真的懂了一样 把火炬传下去! 实验报告 实 验(四 题     目 LinkLab 链接 专       业 xxxx 学    ...

  4. 计算机系统实验五:缓冲区溢出攻击

    参考教材:计算机系统基础 第二版 袁春风 机械工业出版社 参考慕课:计算机系统基础(四):编程与调试实践 https://www.icourse163.org/learn/NJU-1449521162 ...

  5. 《深入理解计算机系统》实验四Architecture Lab下载和官方文档机翻

    前言 <深入理解计算机系统>官网:http://csapp.cs.cmu.edu/3e/labs.html 该篇文章是是实验四Architecture Lab中的Writeup(archl ...

  6. 计算机系统(2) 实验四 缓冲区溢出攻击实验

    计算机系统(2) 实验四 缓冲区溢出攻击实验 一. 实验目标: 二.实验环境: 三.实验内容 四.实验步骤和结果 (一)返回到smoke (二)返回到fizz()并准备相应参数 (三)返回到bang( ...

  7. 计算机系统二进制炸弹实验报告,二进制拿炸弹实验报告完整版.doc

    课程名称:计算机系统原理实验 实验课时:32课时 实验项目名称:BombLab二进制炸弹 实验材料:可执行文件bomb.源代码bomb.c.说明README 实验环境:Linux操作系统(安装虚拟机和 ...

  8. 微信小程序实验四 —— 扫雷游戏

    实验小提醒,打开微信小程序模板时,一定要看清楚,要选js模板,不要选ts模板,因为ts中对数据类型检查更严格,同样的代码在ts中可能无法运行! 实验内容: 编写如下扫雷游戏,基本要求如下: (1)方块 ...

  9. 《深入理解计算机系统》Y86-64实验四Architecture Lab环境安装

    前言 第四章提到的Y86-64和实验四Architecture Lab的环境安装. 先从官网下载文件: <深入理解计算机系统>官网:http://csapp.cs.cmu.edu/3e/l ...

最新文章

  1. 顺序表-顺序表的基本操作(初始化+指定位置元素值 + 用元素值求下标)
  2. 竟有如此沙雕的代码注释!
  3. 基于OpenResty的弹性网关实践(二)
  4. 如何设置CentOS 7开机自动获取IP地址详解
  5. visio2013安装包及破解工具KMS
  6. axure element ui素材_web元件库 ElementUI元件库+后台模板页面+官网组件 pc元件库(兼容Axure9)...
  7. element-ui对话框fullscreen.lock使用
  8. 手把手教你使用QGIS制作地图
  9. 红外检测传感器的C语言,基于51单片机的红外反射式光电传感器测速机的简易设计...
  10. #CSDN软件工程师能力认证学习精选# NoSql是什么?
  11. python数据处理用什么软件_数据分析都会用到哪些工具?
  12. KVM虚拟化平台搭建、工作模式与原理
  13. 北斗通讯协议4.0 java_北斗4.0协议解析.doc
  14. 国内10个最佳PS教程网站
  15. bugly android 错误不上报,Bugly不上上报日志的解决办法
  16. buuctf-AWD-测试1
  17. python市场_大交易数据的python市场篮子分析
  18. 机器学习数据预处理----分类型文字数据的处理
  19. 华为2012实验室无线通信领域的首席专家朱佩英博士
  20. 东原地产首获“蓝筹地产” 千亿货值业绩增速成亮点

热门文章

  1. ❤️手把手教你配置服务器板载raid❤️
  2. iOS 多线程安全 与可变数组
  3. 7.1 求解矩阵的逆
  4. 如何将视频修改成html,如何利用h5将视频设置为背景
  5. Linux DNS服务详解——DNS实战配置
  6. 将轨迹对应到google earth(谷歌地球)上
  7. uniapp 小程序分享功能
  8. 让你的EXCEL表格每页都自动生成表头
  9. 图像dpi像素调整方法
  10. 动画指导在Excel中批量打印标签/送货单等等