HIT 计统实验2 二进制炸弹(gdb破解版) 拆弹过程

news2024/9/22 3:37:45

CSAPP 实验2是一个很好玩的实验,网上有很多参考资源写的都很好,本文增加了一些具体细节。

想要我的炸弹可以私信我。 还得看形式语言 , 炸弹6 7 有时间再拆

第1章 实验基本信息

1.1 实验目的

  • 熟练掌握计算机系统的ISA指令系统与寻址方式
  • 熟练掌握Linux下调试器的反汇编调试跟踪分析机器语言的方法
  • 增强对程序机器级表示、汇编语言、调试器和逆向工程等的理解

1.2 实验环境与工具

1.2.1 硬件环境

Intel 10850H x86_64

1.2.2 软件环境

Ubuntu 20.04

1.2.3 开发工具

Vim、gdb、visual studio

1.3 实验预习

认真学习gdb的用法与汇编语言相关知识

了解一些cmd指令,比如看计算器 cmd+calc

cmd命令以及用法大全_cmd命令操作_qq_38196334的博客-CSDN博客

第2章 实验环境建立

2.1 Ubuntu下CodeBlocks反汇编(10分)

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

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

注意:如果想调试的话必须建立工程,血的教训!!!!

测试代码:

#include<stdio.h>
int m = 0;

int r = 3;

int sum(int x1,int x2,int x3,int x4, int x5,int x6,int x7,int x8){
    return x1+x2+x3+x4+x5+x6+x7+x8;
}

int main(){
    m = m/r;
    m = sum(1,2,3,4,5,6,7,8);
    printf("%d\n",m);
    const char* a= "Hello-2021112114-lyx";
    printf("Hello-202111-xiaoyu");
}

进行调试:

 查看变量m的值:

如图所示(橙色荧光标注),由于数据在计算机中采用小端存储,所以是0000000..24(十六进制)
转换成十进制就是36

查看字符串2021112114-lyx:

方法1:字符串在字符串表里,你这个是字符串常量,它的值是个const char*,你如果想看可以用一个const char*指向它然后查一下这个地址

 方法2:通过rip查找,也就是查看PC的值,然后去访问那个地址,把字节开到最大就能找到字符串。

将rip的地址输入,把字节调到最大就能找到,这里显示的是printf中的参数,不是const char *的参数,一个是字符库一个是位于数据区和代码区 

本来想拿edb看虚拟地址,但是有保护机制,每次运行的虚拟地址不一样。

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

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

gcc hello.c
edb --run a.out

 点完run 以后一直step into 不要问为什么QWQ

第3章 各阶段炸弹破解与分析

前几阶段的密码:防止笔误

I was trying to give Tina Fey more material.
0 1 1 2 3 5
3 g 207
14 7
5 115

每阶段30分,密码10分,分析20分,总分不超过80分

汇编器将汇编代码翻译成二进制指令

cd 到所在文件夹
gdb bomb
b phase_1 #设置断点
run
ni 单步运行一句 ni 2单步运行两句
layout asm 调试查看方便一些
objdump -d ./bomb > bomb.s
翻译成汇编代码

3.1 阶段1的破解与分析

密码如下:I was trying to give Tina Fey more material.(注意标点).

破解过程:

 调用了string not equal函数,如果不相等,就跳转到炸弹爆炸函数,推测比较的字符串在寄存器里,此外可以看到两个push将参数入栈,是为strings_not_equal()准备的。根据函数名,可以知道这个函数是在比较两个字符串是否相等,所以push的很有可能就是一个答案字符串所在地址(如果是程序自带的变量包括字符串等都会在.rodata部分,所以压栈时会直接压入对应地址,另一个来自标准输入的字符串地址。所以利用gdb查看输入和比较的字符串。

3.2 阶段2的破解与分析

密码如下:0 1 1 2 3 5 

破解过程:光看汇编代码就能破解。

 根据汇编代码推测,第一个参数的位置在$rbp-0x30(位置) 第二个参数在$rbp-0x2c(44)的位置根据规律依次减少四,存入参数地址。首先判断第一个和第二个数是不是0和1,ebx相当于计数器i记录循环的标志,-0x30(%rbp,%rax,4)相当于数组是输入的参数以偏移量的形式展示。$rdx和$ebx是相等的,ecx比eax少1,显示不同顺序的参数,由add    -0x30(%rbp,%rcx,4),%eax相当于一个斐波那契数列,递归的起点是0 1,递推式是fib(n) = fib(n-1)+fib(n-2)

0000000000401414 <phase_2>:
  401414:	55                   	push   %rbp
  401415:	48 89 e5             	mov    %rsp,%rbp
  401418:	53                   	push   %rbx
  401419:	48 83 ec 28          	sub    $0x28,%rsp
  40141d:	48 8d 75 d0          	lea    -0x30(%rbp),%rsi
  401421:	e8 c8 05 00 00       	call   4019ee <read_six_numbers>
  401426:	83 7d d0 00          	cmpl   $0x0,-0x30(%rbp)	        //第一个数是不是0
  40142a:	75 06                	jne    401432 <phase_2+0x1e>    //不相等或者不为0
  40142c:	83 7d d4 01          	cmpl   $0x1,-0x2c(%rbp)		//同理
  401430:	74 05                	je     401437 <phase_2+0x23>	//如果第二个参数不是1引爆炸弹
  401432:	e8 95 05 00 00       	call   4019cc <explode_bomb>
  401437:	bb 02 00 00 00       	mov    $0x2,%ebx		// i = 2
  40143c:	eb 08                	jmp    401446 <phase_2+0x32>
  40143e:	e8 89 05 00 00       	call   4019cc <explode_bomb>
  401443:	83 c3 01             	add    $0x1,%ebx	//i = i+1=3  i=4 i = 5
  401446:	83 fb 05             	cmp    $0x5,%ebx	if(i!=5)
  401449:	7f 1e                	jg     401469 <phase_2+0x55>	//我们的目标是安全循环出来
  40144b:	48 63 d3             	movslq %ebx,%rdx//rdx = 2 rdx = 3
  40144e:	8d 4b fe             	lea    -0x2(%rbx),%ecx//ecx = 0 ecx = 1 ecx = 2 ecx = 3
  401451:	48 63 c9             	movslq %ecx,%rcx
  401454:	8d 43 ff             	lea    -0x1(%rbx),%eax//eax = 1	eax = 2 eax = 3 ecx = 4
  401457:	48 98                	cltq   
  401459:	8b 44 85 d0          	mov    -0x30(%rbp,%rax,4),%eax//传入第二个参数 传入第三个参数
  40145d:	03 44 8d d0          	add    -0x30(%rbp,%rcx,4),%eax//a2'=a1+a2=1	a3'=a2+a3=1+a3  a4'=a3+a4 a5=a4+a5
  401461:	39 44 95 d0          	cmp    %eax,-0x30(%rbp,%rdx,4)//a3=a2'=1?		a4=a3'=a3+1?  a5 = a4'? a6=a5'=a4'+a5=2(a3+1)+a5?
  401465:	74 dc                	je     401443 <phase_2+0x2f>
  401467:	eb d5                	jmp    40143e <phase_2+0x2a>
  401469:	48 83 c4 28          	add    $0x28,%rsp
  40146d:	5b                   	pop    %rbx
  40146e:	5d                   	pop    %rbp
  40146f:	c3                   	ret    

3.3 阶段3的破解与分析

密码如下:3 g 207(答案不唯一)

破解过程:

gdb bomb
b phase_
run sol.txt
  •  首先当然还是先观察phase_3的汇编代码,看是不是调用了有关输入的参数的函数:在sscanf函数调用后检查$eax,因为sscanf在参数匹配成功后会将匹配成功的参数的个数放入eax中返回,所以检查eax是否大于2,即至少应匹配三个参数才能过第一个爆炸点.

  • 确定输入字符串的格式: %d %c %d 

  •  

                        推断出$ rbp - 0x4存的是第一参数,并且必须小于7,这里就以3为例

x/x 地址 #查看地址存的数据第一个x代表查看内存内容 第二个x代表以十六进制的形式显示

                                         猜测:判断第三个参数和0xcf也就是207是否相等

                  猜测rbp-0x9位置存放的是字符,再根据acii码对比可知103--g,第二个是比较ACII码

 3.4 阶段4的破解与分析

密码如下:14 7

破解过程:

gdb bomb 
b phase_4
r sol.txt #推荐把前几关的密码写入文件中
ni
layout asm
x/s 地址  #查看字符串形式的输入格式

破解过程相信大家已经轻车熟路了,首先查看输入的形式,输入两个数字,如果输入的数字个数不是2,就会引爆炸弹。

 根据寄存器的使用规则,arg1作为函数的第三个输入参数,他的存放地址由寄存器rdx来确定,对于第四个参数他的寄存地址由rcx确定,接下来我们要根据代码确定arg1和arg2的具体数值。

1.测试数据 99 88; 通过测试发现$rbp-0x4储存的是第一参数,下方的test是判断是不是等于0的操作。

2.接着单步运行发现不仅要大于0,而且还不能大于0xe也就是15 

3.紧接着,执行了三条赋值语句,可以推测三条mov指令是为fun4准备参数 

4.关于fun4如何执行我们之后再看,我们先看fun4执行完之后的代码

根据寄存器的使用规则,函数返回值必须放在rax中,所以返回值必须为7,否则会引爆炸弹。

第二个cmpl函数cmpl -x08(rbp),用来比较agr2和7的大小,所以可以确定第二个输入参数为7,我们进一步缩小范围,第一个数小于等于14第二个数是7

5.下面我们来分析一下函数fun4的代码:

                                                                 测试数据

(gdb) i r

         在调用函数之前查看寄存器 rax 存放第一个值 rdx =14 rsi = 0 rdi存放函数的第一个参数,如果相等那么mov    $0x0,%eax返回值是0不是7,就不符合要求,所以一定是在函数中跳转结束的。

看代码:

00000000004015be <func4>:            (edx=14 ecx =7 esi=0)
  4015be:	55                   	push   %rbp
  4015bf:	48 89 e5             	mov    %rsp,%rbp
  4015c2:	89 d1                	mov    %edx,%ecx    #此时ecx = edx=14
  4015c4:	29 f1                	sub    %esi,%ecx    #ecx = ecx = 14
  4015c6:	89 c8                	mov    %ecx,%eax    #eax = ecx = 14
  4015c8:	c1 e8 1f             	shr    $0x1f,%eax   #逻辑右移eax >> 0x1f(31)逻辑移位 相当于左移一位 此时eax应该是0 因为不能保证精度
  4015cb:	01 c8                	add    %ecx,%eax   #eax = eax+ecx =14
  4015cd:	d1 f8                	sar    %eax	   #移位的位数等于1时,可以省略 	对eax进行算数算数右移一位的操作,可以看成这个数除以2 eax = 7
  4015cf:	01 f0                	add    %esi,%eax   #eax = 0+eax = 7	
  4015d1:	39 f8                	cmp    %edi,%eax   #7和第一个参数对比	
  4015d3:	7f 09                	jg     4015de <func4+0x20>#如果比第二个参数大话,edi[7,14]
  4015d5:	7c 13                	jl     4015ea <func4+0x2c>#如果小的话
  4015d7:	b8 00 00 00 00       	mov    $0x0,%eax
  4015dc:	5d                   	pop    %rbp
  4015dd:	c3                   	ret    
  4015de:	8d 50 ff             	lea    -0x1(%rax),%edx
  4015e1:	e8 d8 ff ff ff       	call   4015be <func4>
  4015e6:	01 c0                	add    %eax,%eax
  4015e8:	eb f2                	jmp    4015dc <func4+0x1e>
  4015ea:	8d 70 01             	lea    0x1(%rax),%esi
  4015ed:	e8 cc ff ff ff       	call   4015be <func4>
  4015f2:	8d 44 00 01          	lea    0x1(%rax,%rax,1),%eax
  4015f6:	eb e4                	jmp    4015dc <func4+0x1e>

第一轮调用:如果是jg eax = 7 ecx = 14 edx = 14  让rax+1

 4015ea:	8d 70 01             	lea    0x1(%rax),%esi
  4015ed:	e8 cc ff ff ff       	call   4015be <func4>

 只有函数返回值为1的时候递归才结束,此时返回值一定是eax = 2*0+1 = 1

要想让eax= 7只有调用7次,也就是eax增加七次所以7+7 = 14或者7-7=0;又因为前面的限制条件所以第一个参数不能为0,所以密码只能是14 7;

ecx = edx = 6 eax = edx = 6 eax = 0 eax = 6  eax = 3 eax = 3

3.5 阶段5的破解与分析

密码如下:5 115

破解过程:

老规矩我们先分析一下汇编代码

 确定参数地址和输入形式

 and一个都是1的数字,没有啥作用,作用主要是生成标志位判断是不是0。指令and    $0xf, %eax取得第一个参数的后四位,且要求第一个参数不能是15,edx为计数器,ecx为累加,根据当次循环eax的值去寻址mov    0x403200(,%rax,4),%eax取到数组中的下一个不连续的元素,结束循环的条件是eax取到15时edx计数到15次,第二个参数与ecx相等。查看地址    0x4031e0(,%rax,4)的元素,观察数组有唯一确定的跳转表将这些值累加得115 其实直接最后看看ecx就行

     3-12-7-11-4-13-6-9-4-8-0-10-1-2-14-6-15

                                         3-12-7-11-4-13-6-9-4-8-0-10-1-2-14-6-15

                                        最后和ecx比较是不是相等 

 参考:

CSAPP第二次实验 bomb二进制炸弹的破解_FatFat-Whale的博客-CSDN博客

汇编学习记录-两种架构汇编指令简单总结_此号已废20的博客-CSDN博客

B站九曲阑干 

哈工大各位大佬

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/416719.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ChatGPT/InstructGPT论文(一)

文章目录一. GPT系列1. in-context learning&#xff08;情景学习&#xff09;二. ChatGPT背景介绍&#xff08;Instruct? Align? 社会化?&#xff09;三. InstructGPT的方法四. InstructGPT工作的主要结论五. 总结六. 参考链接一. GPT系列 基于文本预训练的GPT-1&#xff…

LeetCode 218. 天际线问题

城市的 天际线 是从远处观看该城市中所有建筑物形成的轮廓的外部轮廓。给你所有建筑物的位置和高度&#xff0c;请返回 由这些建筑物形成的 天际线 。 每个建筑物的几何信息由数组 buildings 表示&#xff0c;其中三元组 buildings[i] [lefti, righti, heighti] 表示&#xf…

76-TCP协议,UDP协议以及区别

TCP协议,UDP协议,SCTP协议一.TCP协议1.什么是TCP协议2.TCP协议的特点3.TCP头部结构4.TCP状态转移5.TCP超时重传二.UDP协议1.什么是UDP协议2.UDP协议的特点三.TCP和UDP的区别一.TCP协议 1.什么是TCP协议 TCP(Transmission Control Protocol)协议即为传输控制协议,是一种面向连…

4.12~(小组成员对话预习)

注意我们这里观察的是XP的kernel32.dll&#xff0c;到win10是有变化的 看了这个函数&#xff0c;似乎是让BasepExeLdrEntry不存在的时候初始化一遍&#xff0c;然后进行对比是否已经加载过这个dll&#xff0c;那么如果加载下一个dll的时候&#xff0c;BasepExeLdrEntry是不是还…

05-vue3的生命周期

文章目录1.生命周期定义钩子函数2.vue3中的生命周期1.普通写法2.setup中写生命周期区别1.生命周期定义 每个 Vue 实例在被创建时都要经过一系列的初始化过程。 例如&#xff1a;从开始创建、初始化数据、编译模板、挂载Dom、数据变化时更新DOM、卸载等一系列过程。 我们称 这一…

【MyBatis】你还不会使用MyBatis逆向工程来提高你的开发效率吗?

文章目录MyBatis逆向工程1、快速入门2、逆向工程配置文件参数详解3、QBC查询MyBatis逆向工程 正向工程&#xff1a;先创建Java实体类&#xff0c;由框架负责根据实体类生成数据库表&#xff08;Hibernate是支持正向工程的&#xff09;逆向工程&#xff1a;先创建数据库表&#…

Vue3技术2之ref函数、reactive函数、Vue3中的响应式原理

Vue3技术2ref函数处理基本类型App.vue处理对象类型App.vue总结&#xff1a;ref函数reactive函数只能修改对象类型App.vue完善代码App.vue总结&#xff1a;reactive函数Vue3.0中的响应式原理回顾Vue2的响应式原理Vue3响应式原理模拟Vue2中实现响应式index.html模拟Vue3中实现响应…

二分搜索树

一、概念及其介绍 二分搜索树&#xff08;英语&#xff1a;Binary Search Tree&#xff09;&#xff0c;也称为 二叉查找树 、二叉搜索树 、有序二叉树或排序二叉树。满足以下几个条件&#xff1a; 若它的左子树不为空&#xff0c;左子树上所有节点的值都小于它的根节点。若它…

程序环境和预处理(上)——“C”

各位CSDN的uu们你们好呀&#xff0c;今天小雅兰的内容是C语言中的程序环境和预处理这个知识点&#xff0c;这块知识点是小雅兰地C语言的最后一块知识点了&#xff0c;以后可能会更新一些C语言的书籍的阅读&#xff0c;比如&#xff1a;《C Primer Plus》和《C语言深度剖析》。…

腾讯云快直播低延时播放质量的优化实践

直播已经潜移默化成为许多人日常生活密不可分的一部分。无论是紧张刺激的比赛直播&#xff0c;还是垂涎欲滴的美食直播&#xff0c;亦或者自卖自夸的购物直播&#xff0c;大家都不希望在观看时出现长时间的加载和卡顿&#xff0c;对一些需要观众及时反馈的直播场景&#xff0c;…

【vue】Vue 全局API 详细介绍(nextTick、set、delete、......)

文章目录一、Vue.extend(options)二、 Vue.component三、Vue.nextTick([callback,context])/this.nextTick([callback,context])四、Vue.set(target,propertyName/index,value)/this.set(target,propertyName/index,value)五、Vue.delete(target,propertyName/index)六、Vue.fi…

算法:链表和数组哪个实现队列更快

背景 对于这个问题&#xff0c;我们先来思考一下数组和链表各有什么特点。 数组&#xff1a;连续存储&#xff0c;push 很快&#xff0c;shift 很慢。 链表&#xff1a;非连续存储&#xff0c;add、delete 都很快&#xff0c;但是查找很慢。 所以&#xff0c;我们可以得出结论…

QT 安装 及环境变量配置及出现的错误的解决方法

文章目录QT安装教程(win版)下载链接点击 产品 Qt开发工具点击 下载Qt下滑点击 开源用户下载下滑点击 下载Qt在线安装程序点击 win版本下载打开程序这一步可能遇到的问题1.在自己有Qt账号的情况下&#xff0c;下一步无法点击2.弹出一句话You need to verify your Qt account eai…

基础排序算法【快速排序+优化版本+非递归版本】

基础排序算法【快速排序优化版本非递归版本】&#x1f4af;&#x1f4af;&#x1f4af;⏰【快速排序】◽1.hoare法◽2.挖坑法◽3.前后指针法◽4.特性总结⏰【优化版本】◽1.随机选key◽2.三路取中◽3.小区间优化⏰【非递归版本】⏰【测试效率】排序OJ(可使用各种排序跑这个OJ)⏰…

CDH 6.3.2集群安装部署

文章目录CDH 6.3.2集群安装部署一 CDH概要1.1 CDH的背景1.2 CDH介绍二 环境准备2.1 安装部署环境2.2 部署规划2.3 服务器主机映射2.4 服务器免登录配置2.5 防火墙关闭2.6 关闭Selinux2.7 设置最大打开文件2.8 关闭最大透明页面压缩2.9 设置Swappiness空间2.10 安装JDK2.11 MySQ…

mysql中增删改成的练习

文章目录一、表的创建1.student表的数据2、课程表的数据course3、学生成绩表的数据二、操作序列1、查询计算机系cs的全体学生学号、姓名和性别2、检索选修了课程号为2的学生号和姓名3、检索至少选修了三门课以上的学生号4、检索选修了全部课程的学生5、在原表的基础上创建一个视…

java并发-线程池

java并发-线程池 线程池的介绍 Java线程池表示一组等待工作并多次重用的工作线程。在线程池的情况下&#xff0c;创建了一组固定大小的线程。服务提供者从线程池中拉出一个线程并分配一个作业。完成作业后&#xff0c;线程再次包含在线程池中。 使用线程池可以节省多线程应用…

Revit中如何绘制四面倾斜的屋顶?

一、Revit中如何绘制四面倾斜的屋顶&#xff1f; 如下图所示&#xff0c;像这种坡屋顶有两种方法进行绘制。具体操作如下。 第一种&#xff1a;定义坡度。 1、点击建筑选项卡中的屋顶按钮。 2、选择使用矩形工具。将偏移值修改为500。将屋顶迹线绘制出来。 3、选中全部屋顶迹…

信号浪涌保护器SPD选型方案

1.最大连续工作电压&#xff08;Uc&#xff09;&#xff1a;信号电路的最大电压必须小于Uc 最大连续工作电压Uc是最大工作信号电压&#xff0c;是电涌保护装置长期运行的信号电压或直流电压的最大有效值。这也是在额定漏电流条件下线与线之间或线与地之间的最大电压&#xff0…

UFT常用检查点的使用

录制时Flight自动打开。创建三个Action,分别命名为01_Login/02_New Order/03_Logout&#xff0c; 在Action里录制对应的Login/New Order/Logout操作。用飞机票预定系统订票&#xff0c;在02_New Order中设置起飞和到达城市参数化&#xff0c;用本地表数据&#xff08;至少2组数…