计算机系统基础实验-LinkLab实验
这是大三时的实验课,很久以前的东西,应要求放出来,做的不是很好。linux永远都是很重要的,希望我和大家都记得这个。实际上做到第五阶段我就不会了。实验课程名称:计算机系统基础实验项目名称:LinkLab实验实验目的与要求在实验中的每一阶段n(n=1,2,3,4,5…),按照阶段的目标要求修改相应可重定位二进制目标模块phase[n].o后,使用如下命令生成可执行程序linkbomb:$ gcc -
这是大三时的实验课,很久以前的东西,应要求放出来,做的不是很好。linux永远都是很重要的,希望我和大家都记得这个。实际上做到第五阶段我就不会了。
实验课程名称:计算机系统基础
实验项目名称:LinkLab实验
在实验中的每一阶段n(n=1,2,3,4,5…),按照阶段的目标要求修改相应可重定位二进制目标模块phase[n].o后,使用如下命令生成可执行程序linkbomb: $ gcc -o linkbomb main.o phase[n].o [其他附加模块——见具体阶段说明] 正确性验证:如下运行可执行程序linkbomb,应输出符合各阶段期望的字符串: $ ./linkbomb $ 123456789 [仅供示例,具体目标字符串见每阶段说明] 实验结果:将修改后正确完成相应功能的各阶段模块(phase1.o, phase2.o, …)提交供评分。 |
实验原理与内容 实验内容 每个实验阶段(共6个)考察ELF文件组成与程序链接过程的不同方面知识 阶段1:全局变量ó数据节 阶段2:指令ó代码节 阶段3:符号解析 阶段4:switch语句与重定位 阶段5:重定位 阶段6:重定位( PIC)
实验步骤 1. 实验数据 学生实验数据包: linklab-学号.tar 数据包中包含下面文件: main.o:主程序的二进制可重定位目标模块(实验中无需修改) phase1.o, phase2.o, phase3.o, phase4.o, phase5.o, phase6.o:各阶段实验所针对的二进制可重定位目标模块,需在相应实验阶段中予以修改。 解压命令:tar xvf linklab-学号.tar 2. 实验工具 readelf:读取ELF格式的各.o二进制模块文件中的各类信息,如节(节名、偏移量及其中数据等)、符号表、字符串表、重定位记录等 objdump:反汇编代码节中指令并提供上述部分类似功能 (可选)hexedit:编辑二进制文件内容
实验阶段1 要求:修改二进制可重定位目标文件“phase1.o”的数据节内容(不允许修改其它节的内容),使其与main.o链接后能够运行输出(且仅输出)自己的学号:
实验提示: 检查反汇编代码,获得printf输出函数的调用参数的(数据节中)地址 使用hexedit工具(或自己编写实现二进制ELF文件编辑程序),对phase1.o数据节中相应字节进行修改
实验阶段2 要求:修改二进制可重定位目标文件“phase2.o”的代码节内容(不允许修改其它节的内容),使其与main.o链接后能够运行输出(且仅输出)自己的学号:
实验提示: 检查反汇编代码,定位模块中的各组成函数并推断其功能作用 修改入口函数do_phase()中的机器指令(用自己指令替换函数体中的nop指令)以实现期望的输出
实验阶段3 要求:创建生成一个名为“phase3_patch.o”的二进制可重定位目标文件(不允许修改其它.o模块),使其与main.o、phase3.o链接后能够运行和输出(且仅输出)自己的学号:
实验提示: phase3.o模块入口函数do_phase()依次遍历一个COOKIE字符串(由一组互不相同的英文字母组成,且总长度与学号字符串相同)中的每一字符,并将其不同可能ASCII编码取值映射为特定输出字符 了解并利用符号解析规则
实验阶段4 要求:修改二进制可重定位目标文件“phase4.o”中相应节中的数据内容(不允许修改.text节的内容),使其与main.o链接后能够运行输出(且仅输出)自己的学号:
实验提示: 模块入口函数do_phase()依次遍历一个COOKIE字符串(由一组互不相同的大写英文字母组成,且总长度与学号字符串相同)中的每一字符,并将其不同可能ASCII编码取值映射为特定输出字符 了解掌握switch语句的机器表示的各组成部分及其重定位信息 实验阶段5 要求:修改二进制可重定位目标文件“phase5.o”的相关重定位节中的数据内容(不允许修改其它节的内容),补充完成其中被清零的一些重定位记录(分别对应于本模块中需要重定位的符号引用),使其与main.o链接后能够正确输出(且仅输出)自己学号的编码结果:
实验提示:如果实验中对缺失重定位信息的恢复不完整或不正确的话,链接生成linkbomb程序时可能不报错,但运行程序可能得到以下结果之一: 出现“Segmentation fault”出错信息——原因?“如果未对相关引用进行必要的重定位会发生什么?” 输出“Welcome to this small lab of linking. To begin lab, please link the relevant object module(s) with the main module. ”——提示模块未链接。可能原因:虽然按上述步骤在生成linkbomb程序时实际已链接进phase4.o模块,但某个重要的重定位记录未正确设置。 输出不正确的编码结果 实验第六阶段不做强制性要求
实验阶段6 要求:修改二进制可重定位目标文件“phase6.o”的相关重定位节中的数据内容(不允许修改其它节的内容),补充完成其中被清零的一些重定位记录(分别对应于本模块中需要重定位的符号引用),使其与main.o链接后能够正确输出(且仅输出)自己学号的编码结果:
实验提示: 本阶段的程序框架与阶段5相同,唯一区别是phase6.o采用了Position Independent Code (PIC)的编译方式(即编译生成可重定位目标模块时使用了GCC的“-fPIC”选项),因此模块中对数据和函数的引用方式及其重定位信息发生变化 了解、熟悉PIC的基本实现技术 可编写样例程序并分别加上或省略“-fPIC”选项进行编译,再通过比较各自反汇编的结果,了解相同C源代码的PIC与Non-PIC机器级实现之间的差异。
学生实验结果提交 将修改完成的各阶段模块(phase1.o, phase2.o, phase3_patch.o, phase4.o, phase5.o, phase6.o)和未改动的main.o、phase3.o模块一起用tar工具打包并命名为“学号.tar”: linux> tar cvf 学号尾数(与拿到的tar包相同).tar main.o phase1.o phase2.o phase3.o phase3_patch.o phase4.o phase5.o phase6.o |
实验设备与软件环境 Linux 32-bit,C/汇编语言
|
实验过程与结果(可贴图) 实验阶段1要求:修改二进制可重定位目标文件“phase1.o”的数据节内容(不允许修改其它节的内容),使其与main.o链接后能够运行输出(且仅输出)自己的学号:
实验提示: 检查反汇编代码,获得printf输出函数的调用参数的(数据节中)地址 使用hexedit工具(或自己编写实现二进制ELF文件编辑程序),对phase1.o数据节中相应字节进行修改 输入mydebian@Mydebian:~/23$ readelf -a phase1.o 查看elf文件内容 找到输出的.data 节中偏移量为32的位置。 如下图:
然后输入 mydebian@Mydebian:~/23$ gcc -m32 -o linkbomb1 main.o phase1.o mydebian@Mydebian:~/23$ ./linkbomb1 Y On5TXwyRqWFIARrElCC3uFZ1XpL8WYFNgr2hRgaTvpwppI6UmbGZEizWx6JSTu5jfamz0LqFXDoHti9J9T1 Sn1FXeRxBm143PaIosUOhgNDjjClFjbQwoIUGG1BsTVVlFINsjooMWwgkHu7 青色的字体为输处的文字,然后输入hexedit phase1.o 再运行linkbomb程序,得到如下图所示:
找到了刚刚青色背景标记的字符串。 从y开始哪个字符串开始修改,对比ASCII码,我的学号为是多少,就对应的ASCII码。
直接修改对应的字符串:
删除前一个linkbomb,生成新的linkbomb,最后重新输出得到我们要的结果: 阶段一完成
实验阶段2要求:修改二进制可重定位目标文件“phase2.o”的代码节内容(不允许修改其它节的内容),使其与main.o链接后能够运行输出(且仅输出)自己的学号:
实验提示: 检查反汇编代码,定位模块中的各组成函数并推断其功能作用 修改入口函数do_phase()中的机器指令(用自己指令替换函数体中的nop指令)以实现期望的输出 创建文件phase2_linkbomb2.s 输入如下文本: movl %eax,%ebx subl $0x8,%ebx movl -0xc(%eax),%eax addl %ebx, %eax pushl $0x00003332 //我的学号为23号,ASCII码为32 33小端存放 pushl %esp call *%eax addl $0x8,%esp 输入gcc -m32 -c phase2_linkbomb2.s生成phase2_linkbomb2.o文件 再输入objdump -d phase2_linkbomb2.o读取文件 mydebian@Mydebian:~/23$ objdump -d phase2_linkbomb2.o phase2_linkbomb2.o: file format elf32-i386 Disassembly of section .text: 00000000 <.text>: 0: 89 c3 mov %eax,%ebx 2: 83 eb 08 sub $0x8,%ebx 5: 8b 40 f4 mov -0xc(%eax),%eax 8: 01 d8 add %ebx,%eax a: 68 32 33 00 00 push $0x3332 f: 54 push %esp 10: ff d0 call *%eax 12: 83 c4 08 add $0x8,%esp 输入hexedit phase2.o将上面的内容填补进nop中。
相当于修改上面的反汇编代码。
CTRL+W保存 再输入: mydebian@Mydebian:~/23$ gcc -m32 -c phase2_linkbomb2.s ./linkbomb2 可以得到需要的结果。 阶段二完成。
实验阶段3要求:创建生成一个名为“phase3_patch.o”的二进制可重定位目标文件(不允许修改其它.o模块),使其与main.o、phase3.o链接后能够运行和输出(且仅输出)自己的学号:
实验提示: phase3.o模块入口函数do_phase()依次遍历一个COOKIE字符串(由一组互不相同的英文字母组成,且总长度与学号字符串相同)中的每一字符,并将其不同可能ASCII编码取值映射为特定输出字符 了解并利用符号解
首先输入命令objdump -d -r phase3.o查询:
然后用命令readelf -s phase3.o读取字符串长度:
创建文本phase03_take.c 可以知道这个函数中存放着256个可查询的字符,编写代码如下: #include<stdio.h> int main(){ for(int i=0, p=0; i<=256; ++i ){ char ch='A'+p; printf("'%c',", ch); if(!(i%16)) printf("\n"); if('A'+(++p)>'Z') p=0;//注意带小写 } return 0; } 输入 gcc phase03_take.c -std=gnu99&& ./a.out查看。 (-std=gnu99->C99标准)
这些字符用于填充zcbGMMwCmU()函数中可存放的区域。 复制建立新文本phase03_patch.c,将截图中的字符放入文本中
连续输入指令 mydebian@Mydebian:~/23$ gcc -c phase03_patch.c -m32 mydebian@Mydebian:~/23$ gcc main.o phase3.o phase03_patch.o -m32 mydebian@Mydebian:~/23$ ./a.out IU//这个字符为phase03输出的字符, 也就是说将I,U字符改为2,3(这里的I,U不是说所有的字符,而是所有字符中被输出的某个字符’I’和字符’U’,为了不需要逐个寻找被输出的那两位字符)即可,如下图(可以改用其他字符,例如数字字符由’1’-’9’,但这样需要修改的位置更多)。
修改后重新输出: mydebian@Mydebian:~/23$ gcc -c phase03_patch.c -m32 mydebian@Mydebian:~/23$ gcc main.o phase3.o phase03_patch.o -m32 mydebian@Mydebian:~/23$ ./a.out 23 阶段3完成。
实验阶段4要求:修改二进制可重定位目标文件“phase4.o”中相应节中的数据内容(不允许修改.text节的内容),使其与main.o链接后能够运行输出(且仅输出)自己的学号:
实验提示: 模块入口函数do_phase()依次遍历一个COOKIE字符串(由一组互不相同的大写英文字母组成,且总长度与学号字符串相同)中的每一字符,并将其不同可能ASCII编码取值映射为特定输出字符 了解掌握switch语句的机器表示的各组成部分及其重定位信息 连续输入指令
查看可得输出放入字符为这两个。那么直接用阶段一的方法, 输入hexedit phase4.o进入程序内查看 S|对应ASCII码分别为53 7C,修改为学号23对应ASCII码为32,33
输入命令查看结果正确:
实验阶段5 要求:修改二进制可重定位目标文件“phase5.o”的相关重定位节中的数据内容(不允许修改其它节的内容),补充完成其中被清零的一些重定位记录(分别对应于本模块中需要重定位的符号引用),使其与main.o链接后能够正确输出(且仅输出)自己学号的编码结果: 实验提示:如果实验中对缺失重定位信息的恢复不完整或不正确的话,链接生成linkbomb程序时可能不报错,但运行程序可能得到以下结果之一: 出现“Segmentation fault”出错信息——原因?“如果未对相关引用进行必要的重定位会发生什么?” 输出“Welcome to this small lab of linking. To begin lab, please link the relevant object module(s) with the main module. ”——提示模块未链接。可能原因:虽然按上述步骤在生成linkbomb程序时实际已链接进phase4.o模块,但某个重要的重定位记录未正确设置。 输出不正确的编码结果 首先输入命令objdump phase5.o -d >phase5.txt转化成文本: 打开文本phase5.txt寻找偏移量:
|
更多推荐
所有评论(0)