PE重定位表
windows程序运行的时候,模块的一个加载问题。
每一个可执行文件都有一个默认基址。
情况1
EXE在以前的时候,一般都会被加载到默认基址上。但是dll模块默认基址一般都是0x10000000。不可能有两个模块加载到同一个位置,如果有两个模块加载位置相同,那么必然会有模块不加载到默认基址上。
情况2
现在的Exe模块,为了方式黑客的入侵,都会采用随机基址的策略,使得exe模块一般情况不会加载默认基址上。
这两种情况都会造成没有加载到默认基址上。
2.没有加载到默认基址上的,会怎么样?
多次加载程序,同一段代码的地址都是不一样的(基址进行了随机)
没有加载到默认基址上,有些地方对数据段的访问就会出现地址错误,程序为了保证程序能够正常运行,就需要修复这些位置,修复这些位置的过程,就称之为重定位。
3.重定位表中保存的是什么呢?
保存的是所有需要修复的位置(这个位置是一个已经加上基址的绝对地址)
4.找到重定位表,解析重定位表。
我们通过数据目录表的第五项,可以找重定位表的数据块:
在一个块中,这个结构体有两个字段,但是在结构体后面就直接跟着一个WORD类型的一个数组,这个数组是不定长的。
在这个数组中的每个元素加上virtualAddress就能找到需要重定位的位置
我们最终在重定位表中找到的是需要重定位数据的已经加上基址的地址(自己)
这样的块可能会有多个。0x1000字节是内存一页的大小
5.手工解析重定位表
NT头中的扩展头中的数据目录表中的第五项
重定位表的RVA:0x00119000 FOA:C8000
VirtualAddress:0x00052000
SizeOfBlock:60
struct TYPEOFFSET
{
WORD type:4
WORD offset:12
}
此数据块描述的重定位信息的起始位置:00052000 重定位的个数是(60-8)/2=0x2C个,他们所在的地址:
0x00052000+46F 原因:在红色方块括着的数据后面的数据中,两个字节里4个位中是一个标志位,若标志位为3,就是进行4字节重定位。
0x00052000+479
0x00052000+4CF
........................
系统是如何重定位的?
在以上的地址中,保存这个另一个地址(VA),这个地址是需要重定位的,是错误的
VA_原始-原始基址 = VA_新基址-新的基址 得到:
VA_新 = 新的机制-原始基址+VA_原始