计算机系统基础实训四-LinkLab实验

实验目的与要求

了解链接的基本概念和链接过程所要完成的任务。

理解ELF目标代码和目标代码文件的基本概念和基本构成

了解ELF可重定位目标文件和可执行目标文件的差别

理解符号表中包含的全局符号、外部符号和本地符号的定义。

理解符号解析的目的和功能以及进行符号解析的过程。

实验原理与内容

每个实验阶段(共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, …)提交供评分。 

实验设备与软件环境

Linux Ubuntu 18.04 64-bit

笔记本电脑

VMware虚拟机

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

Phase 1

先运行一遍

计算机系统基础实训四-LinkLab实验_第1张图片

为了方便生成phase1.s文件

计算机系统基础实训四-LinkLab实验_第2张图片

使用objdump -rd phase1.o查看elf文件内容,找到输出的.data 节中偏移量为32的位置。

计算机系统基础实训四-LinkLab实验_第3张图片

使用readelf -a phase1.o命令查看phase1.o的ELF数据,

计算机系统基础实训四-LinkLab实验_第4张图片

计算机系统基础实训四-LinkLab实验_第5张图片

即在0x60+c=0x6c处,用hexedit phase1.o命令修改phase1.o找到0x6c处,修改0x6c+1的值为学号十六进制ASCII码。然后以ASCII码”00”结束字符。

修改的十六进制是:32 33 32 31 35 31 35 30 35 34 31

计算机系统基础实训四-LinkLab实验_第6张图片

编译重新运行,正确输出学号

Phase2

反汇编phase2,发现有两部分构成

Func函数主要是对数组做一些处理,处理之后返回给phase2函数

计算机系统基础实训四-LinkLab实验_第7张图片计算机系统基础实训四-LinkLab实验_第8张图片

readelf -a phase2.o命令查看phase2.o的符号表

计算机系统基础实训四-LinkLab实验_第9张图片

有个COM未被赋初始值,是个弱符号,根据文档提示打个补丁phase2_patch.o。里面的内容应该是cahr类型的大小为256的g_myCharArray变量的初始化,

计算机系统基础实训四-LinkLab实验_第10张图片

得出偏移量为0xc

创建phase2_patch.c文件,创建一个g_myCharArray(弱符号),偏移量是0xb(12)所以前12个无用填0

计算机系统基础实训四-LinkLab实验_第11张图片

采用两种方法

方法一:随机输入两个数35 35,发现打印出来的是/0,于是一个个慢慢推出来

方法二:先在phase2_patch.c填充大小为256个0

依次输入 gcc -c phase2_patch.c、gcc -no-pie main.o phase2.o phase2_patch.c、./a.out

因为我的学号是11位数,所以取最前面的11位“<=>?@ABCDEF”根据ASCII得到16进制的值

计算机系统基础实训四-LinkLab实验_第12张图片

因此往phase2_patch.c填充偏移量12个0以及所得出来的字符:

\X26\X26\X24\X22\X25\X20\X23\X1D\X21\X1F\X1B

计算机系统基础实训四-LinkLab实验_第13张图片

计算机系统基础实训四-LinkLab实验_第14张图片

发现后面的框框不美观,于是在ASCII码找到null字符进行终止

计算机系统基础实训四-LinkLab实验_第15张图片

计算机系统基础实训四-LinkLab实验_第16张图片

Phase3

先进行反汇编

Fun1输出函数,fun2是获取data数据,因此要将他们做一个结合调用

计算机系统基础实训四-LinkLab实验_第17张图片

将所写的函数进行反汇编得到

计算机系统基础实训四-LinkLab实验_第18张图片计算机系统基础实训四-LinkLab实验_第19张图片计算机系统基础实训四-LinkLab实验_第20张图片

得到text的地址码为:e8 00 00 00 48 89 c7 e8 00 00 00 00

打印文件格式:readelf -a phase3.o

找到偏移字段

计算机系统基础实训四-LinkLab实验_第21张图片

查看反汇编

计算机系统基础实训四-LinkLab实验_第22张图片

因此,在第60+D的位置可以看到的地址55 48 89 e5,在后面添加test的地址码

计算机系统基础实训四-LinkLab实验_第23张图片

保存并退出,将其编译进.s文件

查看phase3.s,命令为:vim phase3.s

计算机系统基础实训四-LinkLab实验_第24张图片

写进func2里的偏移:1b(myfunc2头)-36(第一个callq)=FFE5

写进func1里的偏移:0(myfunc1头)-3E(第二个callq)=FFC2

将他写进 phase3.o中

计算机系统基础实训四-LinkLab实验_第25张图片

再次反汇编,命令

查看phase3.s文件

计算机系统基础实训四-LinkLab实验_第26张图片

尝试编译输出,发现全都是XXXXX....

进入字符集,命令:readelf -a phase3.o

找到data字段,位置是01a0

找到位置加上偏移量,后移一位就是我们要修改的值:01A0+C=01AC+1=01AD

计算机系统基础实训四-LinkLab实验_第27张图片

保存并退出ctrl+x,重新运行

计算机系统基础实训四-LinkLab实验_第28张图片

Phase4

查看phase4.o文件ELF数据,命令:readelf -a phase4.o

计算机系统基础实训四-LinkLab实验_第29张图片

要修改上面全为0的偏移量

从↓可以看出

计算机系统基础实训四-LinkLab实验_第30张图片

一个是变量:g_myCharArray

一个是变量:temp

还有一个:puts函数

且g_myCharArray是位于.data节中偏移量为0(即value值)处

temp是位于.data节中偏移量为0x14(即value值)处编译查看汇编代码

编译查看汇编代码:

计算机系统基础实训四-LinkLab实验_第31张图片计算机系统基础实训四-LinkLab实验_第32张图片

截图避免待会需要,用objdump -d phase4.o查看汇编代码

计算机系统基础实训四-LinkLab实验_第33张图片

观察可得
偏移量是要使变量和函数到这里

计算机系统基础实训四-LinkLab实验_第34张图片

即0x6、0x11、0x19
0x18是call指令,所以它对应的是call puts函数。
要把这里的值设置为19

计算机系统基础实训四-LinkLab实验_第35张图片

输入命令:Hexedit phase4.0,查看一下.rela.text段的开始是250

计算机系统基础实训四-LinkLab实验_第36张图片

经过我的分析
偏移量、信息、是符号名称+加数的加数

计算机系统基础实训四-LinkLab实验_第37张图片

这个是“第一组”的,以此类推可以找到”puts组”的位置,”FC FF FF FF FF FF FF”是-4的补码也验证了我们的计算

计算机系统基础实训四-LinkLab实验_第38张图片计算机系统基础实训四-LinkLab实验_第39张图片

修改此处的偏移量为19

重新查看phase4.o文件的ELF数据

计算机系统基础实训四-LinkLab实验_第40张图片

可以发现改对了
重新编译查看汇编代码

会发现变成了

计算机系统基础实训四-LinkLab实验_第41张图片

现在还有两个偏移量要修改

计算机系统基础实训四-LinkLab实验_第42张图片

这两个是数据,看下面是这两个变量的值

计算机系统基础实训四-LinkLab实验_第43张图片

.data段在

计算机系统基础实训四-LinkLab实验_第44张图片

一个在.data+0处,一个在.data+0x10处

前面有提到.data+0是g_myCharArray,那.data+0x10是temp

修改为学号

计算机系统基础实训四-LinkLab实验_第45张图片

现在就要改对应的偏移量
可以看出0x6和0x11处

计算机系统基础实训四-LinkLab实验_第46张图片

根据思考,0x11应该放学号数组,因为要赋值给%rdi传递给puts函数打印,0x6应该放temp
回到上面已经发现”.data+10”(temp)组偏移量是这里,修改为6

“.data+0”组偏移量是这里,修改为11

计算机系统基础实训四-LinkLab实验_第47张图片

readelf -a phase4.o查看,修改正确

但是值有点错误

计算机系统基础实训四-LinkLab实验_第48张图片

还有一个值没有修改

这里可以看出temp是一个位于.data节中偏移量为0x14处的。

从这里可以看出上面的.data+10并不是真的temp的值,而是.symtab里的value才是它的偏移量。

这里就是.data节偏移量为0x14处,改为”00”

计算机系统基础实训四-LinkLab实验_第49张图片

保存退出重新运行,结果正确

Phase 5

编译查看汇编代码

计算机系统基础实训四-LinkLab实验_第50张图片

查看一下ELF数据,命令:readelf -a phase5.o

计算机系统基础实训四-LinkLab实验_第51张图片

这两个换换就好

找到偏移量,互换即可

计算机系统基础实训四-LinkLab实验_第52张图片

这里可以看出g_myCharArray是一个位于.data节中偏移量为0x10处的。
.data在0x90处

计算机系统基础实训四-LinkLab实验_第53张图片

计算机系统基础实训四-LinkLab实验_第54张图片

g_myCharArray在0x90+0x10=0xA0处,修改为学号

计算机系统基础实训四-LinkLab实验_第55张图片

编译运行,结果正确

实验总结

通过此实验,我掌握了符号解析、符号定义分类、静态链接解析过程、符号表条目、重定位、动态链接、静态库的缺点、位置无关代码、数据和代码调用,还有的是关于地址的计算。基于ELF文件格式和程序链接过程的理解,修改给定二进制可重定位目标文件的数据内容、机器指令、重定位记录等部分。实验过程中,我遇到了一些困难和bug,但通过查询资料、搜索和自己思考,最后独立解决了问题。通过完成此次实验,不仅收获了许多知识,而且还锻炼了动手能力和解决问题的能力。解决问题,完成实验,感觉收获很多,也有一定的成就感。

你可能感兴趣的:(汇编,linux,网络,c语言)