基址重定位:
当向程序的虚拟内存加载PE文件时,文件会被加载到ImageBase所指向的地址。对EXE文件来说,EXE文件会首先加载到内存,每个文件总是使用独立的虚拟地址空间,这就意味着EXE文件不用考虑基址重定位问题;
对于DLL文件来说,多个DLL文件使用调用其本身的EXE文件的地址空间,不能保证ImageBase所指向的地址没有被其他DLL文件占用,所以DLL文件当中必须包含重定位信息,也就是说,本来A.DLL被加载到M.EXE进程的00100000地址处,但是此处加载了B.DLL文件,PE装载器将A.DLL文件加载到其他还未被占用的地址处(00850000)处。
对于系统的DLL来说实际上不会发生重定位,因为同一系统的kernel32.dll、user32.dll等会被加载到自身固有的ImageBase。
基址重定位结构体
typedef struct _IMAGE_BASE_RELOCATION
{
DWORD VirtualAddress; //基准地址(Base Address)
DWORD SizeOfBlock; //重定位块大小(一个IMAGE_BASE_RELOCATION结构的大小)
WORD TypeOffset[1];
}IMAGE_BASE_RELOCATION;
重定位表是一个数组,这个数组的大小记载在 _IMAGE_OPTIONAL_HEADER 的 .DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size 成员中
我们打开工具,查看一个dll文件
通过工具可以找到该dll文件的基址重定位表
由图片可以看出
结构数组为8
在二进制编辑器中
参考文章:
https://www.cnblogs.com/night-ride-depart/p/5779043.html