【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.mzph.cn/pingmian/40823.shtml

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

相关文章

STM32F1+HAL库+FreeTOTS学习2——STM32移植FreeRTOS

STM32F1HAL库FreeTOTS学习2——STM32移植FreeRTOS 获取FreeRTOS源码创建工程窥探源码移植 上期我们认识了FreeRTOS&#xff0c;对FreeRTOS有了个初步的认识&#xff0c;这一期我们来上手移植FreeRTOS到STM32上。 获取FreeRTOS源码 进入官网&#xff1a;https://www.freertos.o…

Frrouting快速入门——OSPF组网(一)

FRR简介 FRR是FRRouting的简称&#xff0c;是一个开源的路由交换软件套件。其作者源自老牌项目quaga的成员&#xff0c;也可以算是quaga的新版本。 使用时一般查看此文档&#xff1a;https://docs.frrouting.org/projects/dev-guide/en/latest/index.html FRR支持的协议众多…

网络爬虫(一)深度优先爬虫与广度优先爬虫

1. 深度优先爬虫&#xff1a;深度优先爬虫是一种以深度为优先的爬虫算法。它从一个起始点开始&#xff0c;先访问一个链接&#xff0c;然后再访问该链接下的链接&#xff0c;一直深入地访问直到无法再继续深入为止。然后回溯到上一个链接&#xff0c;再继续深入访问下一个未被访…

HarmonyOS APP应用开发项目- MCA助手(Day02持续更新中~)

简言&#xff1a; gitee地址&#xff1a;https://gitee.com/whltaoin_admin/money-controller-app.git端云一体化开发在线文档&#xff1a;https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/agc-harmonyos-clouddev-view-0000001700053733-V5注&#xff1a;…

【Sping Boot2】笔记

Spring Boot 2入门 如何创建一个Spring Boot的Web例子&#xff1f;1.如何创建一个Spring Boot项目1.1 使用Maven构建一个Spring Boot 2项目1.1.1创建Maven工程注&#xff1a;Maven项目结构&#xff1a; 1.1.2引入SpingBoot相关依赖依赖注意事项&#xff1a; 1.1.3创建主类1.1.4…

VIM介绍

VIM&#xff08;Vi IMproved&#xff09;是一种高度可配置的文本编辑器&#xff0c;用于有效地创建和更改任何类型的文本。它是从 vi 编辑器发展而来的&#xff0c;后者最初是 UNIX 系统上的一个文本编辑器。VIM 以其键盘驱动的界面和强大的文本处理能力而闻名&#xff0c;是许…

Python学习之小游戏--坦克大作战

今天跟视频学习了Python实现坦克大作战小游戏&#xff0c;挺有意思的&#xff0c;一起来玩吧~ 按空格发射子弹&#xff0c;上下左右键实现移动&#xff0c;ESC键无限复活。 import pygame,time,random from pygame.sprite import Sprite SCREEN_WIDTH800 SCREEN_HEIGHT500 BG…

Vue3中为Ant Design Vue中Modal.confirm自定义内容

在一次业务开发时代码时&#xff0c;碰到了一种既想要Modal.confirm样式&#xff0c;又想要定制其content内容的情况。 大部分情况下&#xff0c;使用Modal.method()这种方式时&#xff0c;可能content内容固定都是字符串&#xff0c;那如果想要做更高级的交互怎么办&#xff…

【Git-驯化】一文学会git配置用户信息,git config用法细节

【Git-驯化】一文学会git配置用户信息&#xff0c;git config用法细节 本次修炼方法请往下查看 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我工作、学习、实践 IT领域、真诚分享 踩坑集合&#xff0c;智慧小天地&#xff01; &#x1f387; 免费获取相关内容文档…

Sourcecodester Fantastic Blog CMS v1.0 SQL 注入漏洞(CVE-2022-28512)

前言 CVE-2022-28512 是一个存在于 Sourcecodester Fantastic Blog CMS v1.0 中的 SQL 注入漏洞。攻击者可以通过 "/fantasticblog/single.php" 中的 id 参数注入恶意 SQL 查询&#xff0c;从而获得对数据库的未经授权的访问和控制。 漏洞详细信息 漏洞描述: 该漏…

工具发送formdata请求 Multipartfile 接收

1.需求&#xff1a; 接收到 (Multipartfile file 文件 》使用工具转发到别的请求&#xff0c;将文件传到别的接口 主要代码&#xff1a; InputStreamResource inputstreamResource new InputstreamResource(file.getInputstream(), file.getoriginalfilename());MultiReso…

全网都在疯传的最新蓝海风口项目!

最近全网都在疯传这种视频&#xff0c;想必兄弟们都见到过了&#xff01; 大家看这个号&#xff0c;1天的时间&#xff0c;2个作品&#xff0c;第2个直接就爆了&#xff0c;昨天看点赞还是3.8w&#xff0c;今天已经10w了&#xff0c;这是妥妥的风口啊&#xff01; 大家有没有想…

应用在灯带Type-C接口上的PD SINK协议芯片ECP5701/ECP5702获取充电器的5V、9V、12V、15V、20V供电

方案背景 近日&#xff0c;欧盟就统一充电器接口的提案达成了一项政治协议&#xff0c;其中规定了在欧盟地区销售的所有手机或其他便携式中小型电子设备必须采用统一的USB Type-C接口。这项决定意味着未来将会有更多的产品强制性地使用TYPE-C充电接口。 在这个背景下&#xf…

wordpress 付费主题modown分享,可实现资源付费

该主题下载地址 下载地址 简介 Modown是基于Erphpdown 会员下载插件开发的付费下载资源、付费下载源码、收费附件下载、付费阅读查看隐藏内容、团购下载的WordPress主题&#xff0c;一款针对收费付费下载资源/付费查看内容/付费阅读/付费视频/VIP会员免费下载查看/虚拟资源售…

在Linux上查找文件的2个好用的命令

1. locate xx &#xff08;查找带xx字符的所有文件或目录&#xff09; 在终端输入命令 locate lua&#xff0c;可以看到&#xff0c;所有带lua字符的文件或目录都会被搜索出来。 2. find / -name xx &#xff08;查找名为xx的文件或目录&#xff09; 在终端输入命令 find …

SpringBoot集成beetl模板快速入门

在pom文件引入maven依赖 <dependency><groupId>com.ibeetl</groupId><artifactId>beetl-framework-starter</artifactId><version>1.1.81.RELEASE</version></dependency>写一个controller /*** author * create * descripti…

SecureCRT--使用sftp上传和下载文件

原文网址&#xff1a;SecureCRT--使用sftp上传和下载文件_IT利刃出鞘的博客-CSDN博客 简介 本文介绍SecureCRT如何在软件内直接上传和下载文件。 SecureCRT可以用如下两种方法上传和下载文件&#xff1a; 自带的sftp插件服务器安装rz/sz命令 本文介绍第一种方法&#xff0…

【Android面试八股文】Android性能优化面试题:怎样检测函数执行是否卡顿?

文章目录 卡顿一、可重现的卡顿二、不可重现的卡顿第一种方案: 基于 Looper 的监控方法第二种方案:基于 Choreographer 的监控方法第三种方案:字节码插桩方式第四种方案: 使用 JVMTI 监听函数进入与退出总结相关大厂的方案ArgusAPMBlockCanaryQQ空间卡慢组件Matrix微信广研参…

vue目录说明

vue目录说明 主要目录说明 .vscode - - -vscode工具的配置文件夹 node_modules - - - vue项目的运行依赖文件夹 public - - -资源文件夹&#xff08;浏览器图标&#xff09; src- - -源码文件夹 .gitignore - - -git忽略文件 index.html - - -入口html文件 package.json - - -…

系统架构设计师教程(清华第2版)<第1章 绪论>解读

系统架构设计师教程 第一章 绪论 1.1 系统架构概述1.1.1 系统架构的定义及发展历程1.1.2 软件架构的常用分类及建模方法1.1.3 软件架构的应用场景1.1.4 软件架构的发展未来1.2 系统架构设计师概述1.2.1 架构设计师的定义、职责和任务1.2.2 架构设计师应具备的专业素质1.3 如何成…