计算机系统基础实验四
LinkLab实验
实验目的与要求
- 了解链接的基本概念和链接过程所要完成的任务。
- 理解ELF目标代码和目标代码文件的基本概念和基本构成
- 了解ELF可重定位目标文件和可执行目标文件的差别。
- 理解符号表中包含的全局符号、外部符号和本地符号的定义。
- 理解符号解析的目的和功能以及进行符号解析的过程。
- 了解静态库的概念和静态链接时的符号解析过程。
每个实验阶段(共6个)考察ELF文件组成与程序链接过程的不同方面知识
阶段1:全局变量ó数据节
阶段2:指令ó代码节
阶段3:符号解析
阶段4:switch语句与重定位
阶段5:重定位
阶段6:重定位( PIC)
在实验中的每一阶段n(n=1,2,3,4,5…),按照阶段的目标要求修改相应可重定位二进制目标模块phase[n].o后,使用如下命令生成可执行程序linkbomb:
$ gcc -o linkbomb main.o phase[n].o [其他附加模块——见具体阶段说明]
正确性验证:如下运行可执行程序linkbomb,应输出符合各阶段期望的字符串:
$ ./linkbomb
$ 07 [仅供示例,具体目标字符串见每阶段说明]
实验结果:将修改后正确完成相应功能的各阶段模块(phase1.o, phase2.o, …)提交供评分。
实验过程与结果
学号:07
阶段1:
要求:修改二进制可重定位目标文件“phase1.o”的数据节内容(不允许修改其它节的内容),使其与main.o链接后能够运行输出(且仅输出)自己的学号:
直接gcc -no-pie -o linkbom1 main.o phase1.o然后./linkbomb1得到
然后hex2raw phase1.o进入编辑二进制,找到这串字符串,即获得printf输出函数的调用参数的(数据节中)地址,然后把字符串的内容修改成你的学号,即你要输出的内容
结果截图:
阶段2:
要求:修改二进制可重定位目标文件“phase2.o”的代码节内容(不允许修改其它节的内容),使其与main.o链接后能够运行输出(且仅输出)自己的学号:
这阶段的解题思路就是修改do_phase的返回地址,让它不返回到main函数里的下一条指令,设法让do_phase函数返回到main函数的call puts部分
查看节头表:
即我们能找到do_phase在phase2.o的位置0x34+0x82=0xb6
然后编写汇编代码和得出的结果:
然后把结果覆盖到do_phase的位置
结果截图
阶段3:
要求:创建生成一个名为“phase3_patch.o”的二进制可重定位目标文件(不允许修改其它.o模块),使其与main.o、phase3.o链接后能够运行和输出(且仅输出)自己的学号:
首先我们看一下节头表:
得出的结果是TvtJOsLzfs的大小是256
定义强符号:
查看结果
把对应字母的位置改成自己的学号就行了
结果截图:
阶段4:
要求:修改二进制可重定位目标文件“phase4.o”中相应节中的数据内容(不允许修改.text节的内容),使其与main.o链接后能够运行输出(且仅输出)自己的学号:
找出要修改的地方
把对应的位置改成自己的学号:
结果截图:
接下来的就不做了。。。。
实验总结
经过本次实验,让我知道链接的作用就是合并多个可重定位目标文件与静态/动态库,就是分为两个步骤即符号解析与重定位,符号解析后会得到要合并的.o文件的集合还有就是需要确定地址的符号集合,而重定位就是分为三个部分:同节合并、确定地址、修改引用。
这次实验让我更加了解到符号解析和重定位的过程,这是对我上课内容的一次温习,还增加了我对于他们更深一层的了解,不过要学好这门课程,需要学习的地方还有很多,很多。。。。。