实验前的准备:下载相关tar包并解压

image.png

链接和ELF实验:静态数据与ELF数据节

实验内容:

image.png
image.png
本实验的内容:
image.png
image.png
image.png

实验要求:

image.png
更改每个阶段可执行文件的输出。

事例:

image.png(第一次编译报错的原因是Linux架构和main.o和phasel.o不一样,后者是i386,需要使用-m32选项指定使用 i386 架构编译目标文件)
运行:
image.png

相关知识点:

image.pngimage.pngimage.png
链接的本质是合并相同的节。
链接的过程:
image.pngimage.pngimage.pngimage.pngimage.pngimage.pngimage.pngimage.png
可重定位目标文件:
image.pngimage.pngimage.png
可重定位目标格式:
ELF文件:
image.png
image.pngimage.pngimage.png
image.pngimage.pngimage.pngimage.png
可执行目标文件:
image.png
image.pngimage.pngimage.pngimage.png
image.png
可重定位文件和可执行文件的区别:
image.pngimage.pngimage.png
可执行文件存储器映像:
image.png
每个重定位的结构:
image.png
image.png
image.png
image.png
image.png

实验工具:

readelf:
image.pngimage.png
常用选项:
image.pngimage.pngimage.pngimage.pngimage.png
image.png

readelf使用案例:

image.png
-S选项打印各个节(节头表)的信息。
image.png
image.pngNdx可以对应节头表的Nr确定改符合位于哪个节当中。Bind是访问属性。
r选项显示重定位信息:
-image.png
x选项显示指定模块的指定节内容:
image.png(每一行显示了该节的16字节的内容, 最左边的4字节是指定节的偏移量。最右边是把数据内容中每一字节的值ASCLL码解释出来。

hexedit工具的使用:

使用hexedit main.o后:
image.png
image.png
左边的4字节是便宜量,中间是显示二进制的内容,最右边是把中间显示的文件内容每一字节可用ascll码的就解释出来,不可的用.代替。
光标停留的位置直接输入想修改的的内容。修改结束后用ctrl+x保存修改内容。ctrl+c不保存退出。

实验过程:

image.png

1.获取phase1.o的汇编代码:

image.pngimage.png

2.获取phase1.o目标模块中的重定位记录:

image.png

3.分析phase1.o汇编代码:

image.png
image.png
image.png(call指令)
要确定call指令调用的是哪个函数要结合phase1.o的重定位记录。
call常采用的是绝对地址重定位,call后面的10就是偏移量,由于call的重定位信息存在.rel.text中,可以知道call重定位信息为:image.png
可以看出puts函数采用的是PC相对地址重定位方式。
image.png

确定data节在phase节中的位置:

获取节头表:
image.png(可以看出data节的偏移地址是0x60,结合前面重定位的分析输出字符串的地址相对与data节起始地址的偏移量是:0x79;输出字符串的起始地址:0x60+0x79=0xd9;

使用hexedit工具对该位置开始的内容修改:

查看data节数据:
image.png
对比输出:对比偏向量0x79发现输出没有问题image.png
image.png(选中的内容就是输出的字符串,输出的字符串以00接着说一看到0x00就可以判断此处为字符串的结束位置。(0x00对应的字符串不打印)
image.png
修改:data节的起始地址是0x60,其中输出字符串相对于data节的偏移量是0x79,那么输出字节地址为0x60+0x79=0xd9;
image.png(上图中黄色的部分就是输出字符串的起始地址)从起始位置修改字符串最后以0x00结尾,实现swpu-202131061114的输出;注意修改的ascll码用16进制
image.png

重新链接输出:

image.png

指令和ELF代码节:

实验内容:

image.png

实验过程:

1.获取phase2.o的汇编代码:

image.png
部分汇编代码:
image.png

2.获取phase2.o的重定位记录:

image.png

3.在phase2,o的代码节中中找到类似put的输出函数:(结合call的偏移地址和重定位信息表)

image.png(可以看出这个call的偏移量是c4,按照重定位信息发现偏移量c4中是puts函数,也即后面的AFPQyocF处)
可以在do_phase中修改nop指令实现对AFPQyocF函数的调用,从而实现对目标字符串的输出。

4.查找输出函数AFPQyocF在.text节中的的偏移量:

image.png
image.png(AFPQy0cF的Ndx为1,在节头表中查找到Nr为1的是.text,所有此函数位于,.text节中)
结合上面2图可以得出该函数位于.text节中偏移量为0xa0处。同时该函数image.pngimage.png利用objdump反汇编的汇编代码中函数前也给出了该函数在所在节的偏移量。

5.构造调用上面函数的指令代码:

分析函数执行逻辑:(结合汇编代码和重定位信息表分析)

image.png
该函数先利用strcmp函数比较2个字符串的长度,然后将返回值(相同返回0,不同返回非0)送到eax寄存器中,
如果eax的值不为0就执行jne指令,为0就执行puts要输出的参数入栈执行put函数。
查看重定位表可以看出strcmp的其中一个参数位于.rodata节中,其相对与.rodata节的偏移地址分别为:0x2;
**查找该参数的内容: **
image.png也即这个参数和第一个参数比较。
image.png(是AFP…的第一个参数)分析上面可知:如果要输出学号,那么传递给AFP…的第一关参数是yksPHJa,第二个参数是学号。
构造指令代码:
sub $0x28,esp
mov1 $0x50736b79,-0x10(ebp)
mov1 $0x614a48,-0xc(%ebp)
mov1 $0x31323032,-0x1a(8ebp)
mov1 $0x36303133,-0x16(%ebp)
movw $0x34313131,-0x12(%ebp)
sub $0x8,esp
lea -0x1a(ebp),%eax
push %eax
lea -0x10(%ebp),%eax
push %eax
call 0x00
add $0x10,%esp
nop
leave
ret
将上述代码写入ins.s中并把其编译为可重定位目标文件
image.png(注意这里要在头文件出加.code32,统一格式)
image.png(这里的格式是x86-64需要转换格式)
image.pngimage.png
inst.s的汇编内容:
image.png(中间的指令就是要插入到phase2.o中do_phase函数体中替换nop的内容也就是0x90,)

6.获取目标模块机器码的插入位置:

image.png(.text节在phase.o中的偏移量为0x34)
image.png(首个nop指令在.text节中的偏移量是0xd3)插入机器码在文件中的起始偏移量为:0xd3+0x34=0x 107

7.使用hexedit工具修改:

image.png
注意在填写call指令的二进制的时候其后的二进制要修改使其可以相对pc寻址。修改为:
oxa0-(0xd3+0x36)=ffffff97
修改后的:
image.png

8.链接编译:

image.png

总结:

test指令:test 是一种汇编指令,它用于对两个操作数进行按位 AND 运算,并设置相应的标志位。test 指令的语法通常为:test dest, src;
less查看文件时输入:”/'起到查找的内容。
image.png