《逆核》04-基址重定位表
基址重定位表
定义
PE重定位指如果PE文件加载时(一般是DLL,SYS动态加载)已经有别的DLL或SYS文件加载到它的ImageBase处,PE装载器会将其加载到其它未被占用的空间。PE装载器把它装载到其它位置的一系列行为就叫做PE重定位。(如果不进行这个操作,程序无法运行,内存地址引用错误)
要解决什么问题呢?
–即让DLL文件能加载到其它地方并可以被正确调用.
对于exe文件来说,exe每次都会加载到随机地址(ASLR机制)
操作原理
- 在程序中查找硬编码的地址位置(如指令指向的绝对地址)
- 读取值后,减去imagebase(VA->RVA)
- 加上实际加载的地址(RVA->VA)
- 注:这个是在加载时直接写入修改,而不是每次调用函数或指令时再计算
那么,该如何查找硬编码地址呢?
基址重定位表
基址重定位表记录了程序加载时需要修正的值的相关信息,包括修正地址的位置,需要修正的字节数,需要修正的地址类型等.在.reloc节中.位于PE头的DataDirectory数组的索引为5的元素指向了这个表.该表中每个记录都被称为一项(entry),每个项包含了需要修正的地址的详细信息.项以可变长度数组的形式存在重定位块中,每个重定位块是如下的IMAGE_BASE_RELOCATION结构体
1 | typedef struct _IMAGE_BASE_RELOCATION { |
1 | struct |
每个IMAGE_BASE_RELOCATION结构体都表示一个重定位块,每块记录了0x1000页,记录方法是VirtualAddress表明基地址,每个TypeOffset的低12位表示偏移,基地址加偏移即是那个需要修改的地址.
其中SizeOfBlock的大小(块的长度)指明该重定位块中重定位项的个数
TypeOffset原则上不属于结构中,且元素个数 = (SizeOfBlock - 8 )/ 2,其中前4位的部分含义:
- [
IMAGE_REL_BASED_ABSOLUTE (0)
:使块按照32位对齐,位置为0]- [
IMAGE_REL_BASED_HIGH (1)
:高16位必须应用于偏移量所指高字16位]- [
IMAGE_REL_BASED_LOW (2)
:低16位必须应用于偏移量所指低字16位]- [
IMAGE_REL_BASED_HIGHLOW (3)
:全部32位应用于所有32位]- [
IMAGE_REL_BASED_HIGHADJ (4)
:需要32位,高16位位于偏移量,低16位位于下一个偏移量数组元素,组合为一个带符号数,加上32位的一个数,然后加上8000然后把高16位保存在偏移量的16位域内]。
数组的最后一项以NULL填充结尾.
评论