1、每个DLL模块和可执行文件都有一个首选基地址。
它表示该模块被映射到进程地址空间时最佳的内存地址。在构建可执行文件时,默认情况下链接器会将它的首选基地址设为0x400000。对于DLL,链接器会将它的首选基地址设为0x10000000,然后将该地址以及代码、数据的相关地址都写入它们的PE文件中。
当它们被加载时,加载程序读取首选基地址的值,并试图把它们加载到相应位置。
2、对于可执行文件和DLL中的代码,它们运行的时候所引用的的数据的地址,在链接的时候就已经确定。并且这些都是当exe文件或是DLL被加载到它们的首选基地址处时才是有效的。
例如:
对于汇编代码:MOV [0x00414540], 5
它是将5赋值给0x00414540处的内存地址。此地址已经固定。它说明当EXE或是DLL被加载到0x400000处时,0x00414540才是正确的。
然而并不是所有模块都会被载入到首选基地址处。一旦模块没有被加载到首选基地址处,在该模块中对于地址的引用都是错误的,这时候基址重定位就是必须的。
3、重定位
就是当某模块未被载入到首选基地址时,加载器会计算模块实际载入的地址跟首选基地址的差值,将这个差值加到机器指令所引用的原来的地址,得到的就是模块中各指令所引用的数据在本进程地址空间的正确地址,随后加载器会修正模块中对每个内存地址的引用。
4、为了便于系统有能力对各数据的地址进行修正,wind