-
-
[原创]自学PE详解(3)重定位表完结
-
发表于:
2020-2-7 22:22
4356
-
今天我们说一下PE结构中重定位表。
在说之前我们先来想一个问题
假设你的程序有一个全局变量(记住不限于变量),全局变量就不用我解释了把,这是被写死的数据是根据Image Base 再加上 全局变量所在的地址。 什么意思呢看下图就知道了
成员
Image Base 是 00400000
就是字符串所在的地址 00403000
仔细看压入的字符串地址,这是一个被写死的地址,那么这个时候如果 程序没有被载入指定的地址空间会发生什么呢?
肯定访问不到正确的数据然后程序就会崩溃但是实际上来说重定位表主要还是在sys/dll 类的PE文件中大量使用。
换个思路说,打个比方 两个dll或者sys 的载入地址都是 00400000 那么 如果第一个载入到了00400000 那么第二会加载到哪里呢?肯定不能和已经加载了的抢位置啊是吧,所以就会换个没有占用的加载,然后重新定位 向上图所示的那种写死了的数据这样就可以解决问题了。
下面开始查找
数据目录数组 的第5个成员就是 重定位表的信息
然后我们查看节区的信息,发现节区的起始RVA和重定位表的RVA是一样的那么就可以直接根据 Pointer to Raw Data成员的值来直接访问重定位表
这里我们要说一下重定位表的结构。
重定位表也是一个结构体数组,每一个数组元素描述了一页(4KB)内的重定位信息。
这里说一下重定位表 不止一个 那么我们如何知道有多少个重定位表呢
很简单 通过 VirtualAddress + SizeOfBlock 就可以访问到下一个重定位表,然后判断是否为NULL或者0x00000000
然后说一下如果计算 重定位表中的TypeOffset成员的数量 (
SizeOfBlock - 8(VirtualAddress 和 SizeOfBlock的大小))/ 2(这是Typeoffset成员的大小) 就等于多少个成员。
然后仔细说一下TypeOffset成员
这个成员的高4位是状态码 然后低12位是具体的RVA
状态码的具体含义如下
下面我们查看重定位表内具体的值
下面就开始根据上面的信息开始实战
VirtualAddress +
Typeoffset(低十二位) = RVA
1000 + 000 = 1000
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!