【CSAPP】-linklab实验

目录

实验目的与要求

实验原理与内容

实验步骤

实验设备与软件环境

实验过程与结果(可贴图)

实验总结


实验目的与要求


1.了解链接的基本概念和链接过程所要完成的任务。
2.理解ELF目标代码和目标代码文件的基本概念和基本构成
3.了解ELF可重定位目标文件和可执行目标文件的差别。
4.理解符号表中包含的全局符号、外部符号和本地符号的定义。
5.理解符号解析的目的和功能以及进行符号解析的过程。


实验原理与内容


每个实验阶段(共5个)考察ELF文件组成与程序链接过程的不同方面知识
阶段1:全局变量数据节
阶段2:强符号与弱符号数据节
阶段3:代码节修改
阶段4:代码与重定位位置
阶段5:代码与重定位类型

在实验中的每一阶段n(n=1,2,3,4,5…),按照阶段的目标要求修改相应可重定位二进制目标模块phase[n].o后,使用如下命令生成可执行程序linkbomb:
$ gcc -o linkbomb main.o phase[n].o [其他附加模块——见具体阶段说明]
正确性验证:如下运行可执行程序linkbomb,应输出符合各阶段期望的字符串:
$ ./linkbomb
$ 19210320303        [仅供示例,具体目标字符为每位学生学号]
实验结果:将修改后正确完成相应功能的各阶段模块(phase1.o, phase2.o, …)提交供评分。


实验步骤


1. 实验数据
学生实验数据包: linklab学号.tar
数据包中包含下面文件:
main.o:主程序的二进制可重定位目标模块(实验中无需修改)
phase1.o, phase2.o, phase3.o, phase4.o, phase5.o:各阶段实验所针对的二进制可重定位目标模块,需在相应实验阶段中予以修改。
解压命令:tar xvf linklab学号.tar
2. 实验工具
readelf:读取ELF格式的各.o二进制模块文件中的各类信息,如节(节名、偏移量及其中数据等)、符号表、字符串表、重定位记录等
objdump:反汇编代码节中指令并提供上述部分类似功能
hexedit:编辑二进制文件内容


实验阶段1
要求:修改二进制可重定位目标文件“phase1.o”的数据节内容,使其与main.o链接后能够运行输出(且仅输出)自己的学号:

$ gcc -o linkbomb main.o phase1.o -no-pie

$ ./linkbomb

学号

实验提示:
检查反汇编代码,获得printf(根据情况有可能被编译时转换为puts)输出函数的参数的(数据节中)地址 。
使用hexedit工具(或自己编写实现二进制ELF文件编辑程序),对phase1.o数据节中相应字节进行修改。

实验阶段2
要求:根据强符号与弱符号的原则,判断符号表中的符号以及其所对应的数据区域。利用符号解析规则,创建生成一个名为“phase2_patch.o”的二进制可重定位目标文件(可以不修改phase2.o模块),使其与main.o、phase2.o链接后能够运行和输出(且仅输出)自己的学号:

$ gcc -o linkbomb main.o phase2.o phase2_patch.o  -no-pie

$ ./linkbomb

学号

实验提示:
Phase2.o模块的符号表中,包含了类型为COM的符号。此类符号的特点是:未被赋初值。所以,其在ELF的数据节中并不真实存在。所以需要另寻解决办法,创造出真实存在的数据并对其进行二进制编辑,以达到输出自己学号的目的。
解题需要运用的主要知识为强弱符号的解析规则。另外,层序中包含了一个数值转换过程,学生需要根据反汇编代码确定其修改规则,并根据修改规则进行“反制”。

实验阶段3
要求:修改二进制可重定位目标文件“phase3.o”的代码节内容,使其与main.o链接后能够运行输出(且仅输出)自己的学号:

$ gcc -o linkbomb main.o phase3.o -no-pie

$ ./linkbomb

学号


实验提示:
检查反汇编代码,定位模块中的各组成函数并推断其功能作用。 根据反汇编程序的执行逻辑,修改函数中的机器指令(用自己指令替换函数体中的nop指令)以实现期望的输出。
为了实现输出功能,自行编写获得的二进制程序(可以通过编写汇编代码然后使用gcc -c命令的方式实现)可以“借用”其他函数中的“有用代码或数据”,比如输出函数和数据引用等具体部分。

实验阶段4
要求:修改二进制可重定位目标文件“phase4.o”中重定位节和数据节中的内容,使其与main.o链接后能够运行输出(且仅输出)自己的学号:

$ gcc -o linkbomb main.o phase4.o -no-pie

$ ./linkbomb

学号


实验提示:
本阶段学生所拿到的.o文件中的“重定位位置”信息已经被抹除,学生需要根据实际情况确认冲重定位的发生位置,并根据重定位类型对位置信息进行恢复。若程序未能够正确修改重定位位置,则典型问题表现为段错误segmentation fault。此外,还需要学生根据程序所用到的数据情况进行数据部分的二进制修改。

实验阶段5
要求:修改二进制可重定位目标文件“phase5.o”中重定位节和数据节的内容,使其与main.o链接后能够正确输出(且仅输出)自己学号:

$ gcc -o linkbomb main.o phase5.o -no-pie

$ ./linkbomb

学号 

You called touch2。若不完全满足题目要求,则会提示“Misfire” 和FAIL相关字段。
阶段5:使用ROP方式对rtarget进行攻击,调用touch3,且成功输出Touch3!: You called touch3。若不完全满足题目要求,则会提示“Misfire” 和FAIL相关字段。

实验设备与软件环境


1.Linux操作系统—64位Ubuntu 18.04
2. gdb调试器和objdump反汇编指令
3. 笔记本

实验过程与结果(可贴图)

实验工具
readelf:读取ELF格式的各.o二进制模块文件中的各类信息,如节(节名、偏移量及其中数据等)、符号表、字符串表、重定位记录等
objdump:反汇编代码节中指令并提供上述部分类似功能
hexedit:编辑二进制文件内容
阶段一
使用如下命令生成可执行程序linkbomb:
$ gcc -o linkbomb main.o phase1.o -no-pie
正确性验证:如下运行可执行程序linkbomb
$ ./linkbomb
应输出符合各阶段期望的字符串:
$ 232151503xx (已修改的情况下)


先执行一遍linkbomb 保证程序不会出现乱码
这里我们还没有修改,所以不会有结果

输入readelf -a phase1.o 查看elf文件内容


其中我们完成学号字符串的输出,找到对应参数g_data,其重定向类型是绝对地址(R_X86_64_32),且+了0x18,同时也是一个OBJECT-全局变量。因此我们需要找到对应的.data节在全文中的偏移量,从而将g_data的内容修改为学号字符串,完成phase1。

(R_X86_64_32)那里是5c,加上我们data中的60就是
5c+60=bc
从而确定在0xbc处插入我们需要插入的数据-学号字符串。

Ascii码的0-9是0x30-0x39
我的学号是23215150318
也就是32 33 32 31 35 31 35 30 33 31 38
接着输入hexedit phase1.o命令来修改phase1.o,并对phase1.o数据节中相应字节进行修改

修改完记得00结尾加保存ctrl+w,ctrl+x退出编辑

00结尾才能知道修改到的值

这是一个比较大的空间
我们找到0xbc的地方
这里显示的是b4,我们就挨个去算,4567,8 9 10 11
11位就是bb,12就是bc
我们就把32 33 32 31 35 31 35 30 33 31 38放进去,再00结尾保存
退出即可。

再验证一下有没有保存到
$ gcc -o linkbomb main.o phase1.o -no-pie
$ ./linkbomb


这样就过关了。

阶段二
使用readelf查看phase2.o并查找有关输出函数的内容。
输入readelf -a phase2.o 查看elf文件内容


可以发现COM未被赋初始值,COM表示g_myCharArray是一个未初始化的弱符号数组,大小Size为256,所以我们需要创建一个已初始化强符号的g_myCharArray来覆盖弱符号。需要打补丁phase2_patch.o

从中可以看到put函数的参数是g_myCharArray,其+0x5c,重定向类型也为绝对地址。

创建phase2_patch.c文件并写入0x5c个字节的“0”以及学号ASCII码。


使用“gcc -c phase2_patch.c”编译生成phase2_patch.o文件并链接:“gcc -o linkbomb2 main.o phase2.o phase2_patch.o -no-pie”,最后运行程序

每个字符都发生了偏移。为了得到偏移量来反偏移得到字符串,实现学号的插入,为了方便计算输入的结果,我们编写一个程序来手动计算偏移量得出的结果,最终通过编辑好学号key,来计算be=%d输出计算结果,即正确的反偏移答案。
hack.c

使用“gcc -c hack.c”编译生成hack.o文件并链接
   运行:gcc hack.c -o hack
gcc -o linkbomb2 main.o phase2.o phase2_patch.o -no-pie
./linkbomb2 > out
./hack < out

最终通过编辑好学号key,来计算be=%d输出计算结果,即正确的反偏移答案。
编译计算文件并链接上linkbomb2,将结果导出为out并使用out运行计算文件,得到的be值即为学号对应的反偏移量,修改patch文件中的字符串。


得到结果文件后再次编译链接运行linkbomb2

成功输出学号,这样就算过关了。


阶段三


链接 linkbomb3 执行:gcc -o linkbomb3 main.o phase3.o -no-pie
使用 objdump -d linkbomb3 反汇编查看汇编代码:

如果想要成功打印学号,应该是打印在后,所以包含puts语句的myFunc1方法在后面,并且接收一个参数,这个参数应该是学号;而myFunc2则是获取一个地址的值给到%rax寄存器。

可以看出,就是先调用myFunc2函数获取学号赋值给%rax,然后mov %rax,%rdi设置参数在调用myFunc1

所以我们注入的命令顺序为:

    1、call myFunc2
    2、Mov %rax,%rdi
    3、Call myFunc1

使用 readelf -a phase3.o 查看 .text 节的偏移量:为0x40

使用 objdump -d phase3.o 查看 do_phase 填充代码地址

填充的起始地址是 0x40 + 0x31 = 0x71。
其中 call 指令是相对寻址,myFunc 函数的地址为

第一条指令call指令对应的机器码是e8 xx xx xx xx ,占 5 个字节,结束地址为 0x31 + 0x5 = 0x36,所以距离 myFunc2 函数地址的相对距离为 0x1b - 0x36 =-1b,也就是 e5 ff ff ff,

所以第一条 call 指令为 e8 e5 ff ff ff。

第二条指令mov %rax,%rdi,mov %rax,%rdi的机器码是为 48 89 c7

第三条指令为call指令对应的机器码是e8 xx xx xx xx ,占 5 个字节,加上第二条指令的 3 个字节,所以结束地址为 0x36 + 0x3 + 0x5 = 0x3e ,所以距离 myFunc1 函数地址的相对距离为 0x0 - 0x3e = c2 ff ff ff ,所以第三条指令为 e8 c2 ff ff ff 。

修改 phase3.o 的二进制,将构造的代码注入

然后执行 hexedit phase3.o 从 0x71 开始写入我们构造的代码


接着来查看是否修改
执行 objdump -d phase3.o查看 do_phase3 函数


可以看到修改成功


完成代码插入,现在需要完成学号赋值。回看myFunc2函数汇编,发现学号赋值处函数获取数据的内存地址,即为.data节。因此我们需要找到节头以及加数。图13中显示.data节节头为0x1a0,重新查看ELF发现.data加数是为0x5c,从而确定学号应当位于phase3.o的0x1a0+0x5c=0x1fc处,并且以“00”结尾进行插入。

 readelf -a phase3.o

执行 hexedit phase3.o 从0x1fc修改成我们的学号


gcc -o linkbomb3 main.o phase3.o -no-pie
./linkbomb3

通过查阅之前讲过的第三章的知识,也算恶补了一下。
至此,阶段三结束。

实验总结

  通过此实验,我掌握了符号解析、符号定义分类 、静态链接解析过程、符号表条目、重定位,还有的是关于地址的计算。基于ELF文件格式和程序链接过程的理解,修改给定二进制可重定位目标文件的数据内容、机器指令等部分。实验过程中,我有遇到了bug,但通过了查询资料(书都要翻烂了)、上百度搜问,最后自己独立解决了bug。通过完成此次实验,不仅收获了很多知识,而且还锻炼了我的动手能力。解决了问题,完成了实验,感觉收获满满的,也有一定的成就感。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

安全和加密常识(6)Base64编码方式

文章目录 什么是 Base64编码原理编解码示例应用什么是 Base64 Base64 是一种用于将二进制数据编码为仅包含64种ASCII字符的文本格式的编码方法,注意,它不是加密算法。它设计的目的主要是使二进制数据能够通过只支持文本的传输层(如电子邮件)进行传输。Base64常用于在需要处…

Python | 基于支持向量机(SVM)的图像分类案例

支持向量机&#xff08;SVM&#xff09;是一种监督机器学习算法&#xff0c;可用于分类和回归任务。在本文中&#xff0c;我们将重点关注使用SVM进行图像分类。 当计算机处理图像时&#xff0c;它将其视为二维像素阵列。数组的大小对应于图像的分辨率&#xff0c;例如&#xf…

三菱PLC标签使用(I/O的映射)与内容

今天&#xff0c;小编继续开始三菱PLC的学习&#xff0c;今天的内容是标签及其标签的内容说明&#xff0c;如果对你有帮助&#xff0c;欢迎评论收藏。 标签的种类&#xff0c;等级&#xff0c;定义 种类 三菱3U的PLC的种类分别为二种&#xff1a;全局标签与局部标签 全局标签…

RabbitMQ-交换机的类型以及流程图练习-01

自己的飞书文档:‌‍‬‍‬‍​‍‬​⁠‍​​​‌⁠​​‬‍​​​‬‬‌​‌‌​​&#xfeff;​​​​&#xfeff;‍​‍​‌&#xfeff;⁠‬&#xfeff;&#xfeff;&#xfeff;​RabbitMQ的流程图和作业 - 飞书云文档 (feishu.cn) 作业 图片一张 画rabbit-mq 消息发…

【HDC.2024】探索无限可能:华为云区块链+X,创新融合新篇章

6月23日&#xff0c;华为开发者大会2024&#xff08;HDC 2024&#xff09;期间&#xff0c; “「区块链X」多元行业场景下的创新应用”分论坛在东莞松山湖举行&#xff0c;区块链技术再次成为焦点。本次论坛以"区块链X"为主题&#xff0c;集结了行业专家、技术领袖、…

深入解读:如何解决微调扩散模型时微调数据集和训练数据集之间的差距过大问题?

Diffusion Models专栏文章汇总&#xff1a;入门与实战 前言&#xff1a;在微调扩散模型的时候经常会遇到微调数据集和训练数据集之间的差距过大&#xff0c;导致训练效果很差。在图像生成任务中并不明显&#xff0c;但是在视频生成任务中这个问题非常突出。这篇博客深入解读如何…

android应用的持续构建CI(一)-- 总体设计

一、背景 接下里我希望通过一系列的文章&#xff0c;把android应用的构建梳理一遍&#xff0c;从总体设计到逐个环节的实现。 总体设计jenkins集成手动签名依赖环境应用管理 二、构建流程图 三、技术组件 jenkinsjdkgradle360加固 既然是android应用的持续构建&#xff0c…

实验七 SQL数据更新和视图

题目 &#xff08;1&#xff09;向商品类别表category中插入一条记录&#xff08;801&#xff0c;‘座椅套’&#xff0c;‘各种品牌的汽车座套’&#xff09; &#xff08;2&#xff09;向商品表product中插入一条记录&#xff1a;商品编号80101&#xff0c;商品名称“四季通…

64.函数参数和指针变量

目录 一.函数参数 二.函数参数和指针变量 三.视频教程 一.函数参数 函数定义格式&#xff1a; 类型名 函数名(函数参数1,函数参数2...) {代码段 } 如&#xff1a; int sum(int x&#xff0c;int y) {return xy; } 函数参数的类型可以是普通类型&#xff0c;也可以是指针类…

文心一言 VS 讯飞星火 VS chatgpt (295)-- 算法导论21.4 4题

四、利用练习 21.4-2 &#xff0c;请给出一个简单的证明&#xff0c;证明在一个不相交集合森林上使用按秩合并策略而不使用路径压缩策略的运行时间为 O(m lgn) 。21.4-2 的内容是&#xff1a;“证明&#xff1a;每个结点的秩最多为 ⌊lgn⌋ 。”。如果要写代码&#xff0c;请用…

【C语言】auto 关键字

在C语言中&#xff0c;auto关键字用于声明局部变量&#xff0c;但它的使用已经变得很少见。事实上&#xff0c;从C99标准开始&#xff0c;auto关键字的默认行为就是隐含的&#xff0c;因此在大多数情况下无需显式使用它。 基本用法 在C语言中&#xff0c;auto关键字用于指定变…

CVPR 2024最佳论文:“神兵”的组合器 Generative Image Dynamics

CVPR 2024的最佳论文来自谷歌、美国加州大学圣迭戈分校。两篇都来至于视频生成领域&#xff0c;可见今年外界对视频生成领域关注度很高。今天的这篇是“Generative Image Dynamics”&#xff0c;Google Research发布的。它的研究成果令人震惊&#xff0c;从单张RGB图像生成连续…

DIY智能音箱:基于STM32的低成本解决方案 (附详细教程)

摘要: 本文详细介绍了基于STM32的智能音箱的设计与实现过程&#xff0c;包括硬件设计、软件架构、语音识别、音乐播放等关键技术。通过图文并茂的方式&#xff0c;结合Mermaid流程图和代码示例&#xff0c;帮助读者深入理解智能音箱的工作原理&#xff0c;并提供实际操作指导。…

一分钟教你设置代理服务器的IP地址

许多人购买完代理IP却不会使用&#xff0c;我们来学习一下如何手把手地设置代理服务器的IP地址。无论是为了访问受限网站还是保护隐私&#xff0c;设置代理IP都是一个非常实用的技能。让我们一起来看看怎么做吧&#xff01; 设置代理服务器的IP地址步骤 1. 选择代理服务提供商…

PyCharm左侧项目区域出现淡黄色背景如何解决

PyCharm左侧项目区域出现淡黄色背景如何解决 解决方法&#xff1a; 1、打开pycharm 文件 - > Setting-> 项目 -> 项目结构 2、添加内容根 为 你的项目根目录即可恢复

sql server启动、连接 与 navicat连接sql server

一、sql server 启动 1.搜索cmd->以管理员身份运行 2.输入以下命令 net start mssqlserver 3.服务器启动成功 二、sql server连接 1.打开ssms&#xff0c;输入&#xff0c;连接 2.右键&#xff0c;属性 3.连接&#xff0c;勾选允许远程连接到此服务器 三、navicat连接sq…

自然语言处理领域介绍及其发展历史

自然语言处理领域介绍及其发展历史 1 NLP2 主要任务3 主要的方法1 基于规则的方法&#xff08;1950-1980&#xff09;2 基于统计的方法&#xff08;传统的机器学习的方法&#xff09;3 Connectionist approach&#xff08;Neural networks&#xff09; 1 NLP 自动的理解人类语…

Labview_Occurrencel(事件发生)

PS&#xff1a;这里遇到 一个很Low的事情&#xff1a; 在停止第二个while循环的时候出现了停止不了的情况。因为等待事件发生设置的超时时间为:-1。所以等事件发生后出现了条件接线端已经执行的情况&#xff0c;所以当下次事件发生时未能及时停止。初版的停止设置如下图&#x…

暑假学习DevEco Studio第2天

学习目标&#xff1a; 掌握页面跳转 学习内容&#xff1a; 跳转页面 创建页面&#xff1a; 在“project”窗口。打开“entry>src>main>ets”,右击“pages”&#xff0c;选择“New>ArkTS File”,命名“Second”&#xff0c;点击回车键。 在页面的路由&#xff0…

详解flink sql, calcite logical转flink logical

文章目录 背景示例FlinkLogicalCalcConverterBatchPhysicalCalcRuleStreamPhysicalCalcRule其它算子FlinkLogicalAggregateFlinkLogicalCorrelateFlinkLogicalDataStreamTableScanFlinkLogicalDistributionFlinkLogicalExpandFlinkLogicalIntermediateTableScanFlinkLogicalInt…