预备知识
一、相关实验
本实验要求您已经认真学习和完成了《IMAGE_DOS_HEADER解析》、《PE头之IMAGE_FILE_HEADER解析》、《PE头之IMAGE_OPTIONAL_HEADER解析》、《节表头解析以及RVA与文件偏移地址的转换》。
本实验相关的基础知识都分散在前面几个实验中,所以如果你对其中有些概念还不是很熟悉的话,建议去回顾一下前面的几个实验。
实验目的
1)了解重定位的原理;
2)了解PE文件的重定位表结构;
3)手工解析PE文件的重定位表。
实验环境
服务器:Windows XP,IP地址:随机分配
辅助工具:C32Asm、LordPE
实验步骤一
重定位原理以及重定位表结构解析。
本实验将介绍数据目录表的第六个成员——重定位表。
在介绍PE文件的OptionalHeader的时候,其中有一个成员ImageBase,它指定了程序的首选装载基地址,也就是说,如果条件允许的话,PE文件被加载到内存时将会被加载到这个基地址。而如果这个地址已经被其他模块所占用了的话,那么这个PE文件就不能再放到这个位置了,它需要在进程空间的其他地方找到一个合适的位置来装载,因为加载的基地址发生了变化,该PE文件引用的一些全局变量或者函数都需要进行重定位处理。
下面通过一个具体的例子来讲解需要进行重定位的场景。假设在EXE文件中存在下面这样一段代码,用于弹出一个MessageBox:
其中第三个参数为消息框的标题,这里引用了一个全局变量,地址为0x00402000。该EXE文件在OptionalHeader中ImageBase的值为0x00400000,那么可以算出这个字符串的RVA值为0x00402000-0x00400000=0x2000。
如果可执行文件的实际装载地址就是0x00400000,那么上述代码不需要进行任何修改就可以直接运行。但是如果实际的装载地址不是0x00400000(假设为0x00870000),那么0x00402000指向的位置就不再是原来的字符串了,那么原来的字符串现在去哪里了呢?这可以简单的计算出来:实际装载地址+RVA=0x00870000+0x2000=0x00872000。这里进行一下变形,因为有RVA=原始地址-首选装载地址,所以最后的地址为新地址=实际装载地址-首选装载地址+原始地址,进行重定位修改之后的代码如下:
在上述的例子中,重定位起到的作用就是将第二条指令从push 00402000修改为push 00872000,经过重定位修正之后,程序就能正常运行了。经过重定位操作之后,PE文件被加载到任意一个基地址都可以