为何重定位表元素存在额外偏移?x86平台0x3000偏移来源求解
x86 PE重定位计算中多出0x3000偏移的原因
这个0x3000的偏移来源很明确——你没正确处理PE重定位表里TypeOffset字段的高4位类型标识。
先讲清楚x86 PE重定位项的结构:重定位块(IMAGE_BASE_RELOCATION)里的TypeOffset数组是一组16位的WORD值,每一位的分工是固定的:
- 高4位:表示重定位类型,比如最常见的32位地址重定位(
IMAGE_REL_BASED_HIGHLOW)对应的类型值就是3 - 低12位:才是这个重定位项相对于当前块
VirtualAddress的实际偏移量
你计算时直接把整个TypeOffset值(比如你例子里的0x3E15)加到了VirtualAddress上,但实际上应该只取低12位(0xE15)。高4位的3对应十六进制的0x3000,这就是你计算结果多出的那部分。
拿你的场景验证:
- 错误计算方式:
0x75A00000(加载基址) + 0x10000(重定位块VirtualAddress) + 0x3E15(完整TypeOffset) = 0x75A13E15 - 正确计算方式:
0x75A00000 + 0x10000 + (0x3E15 & 0xFFF) = 0x75A00000 + 0x10000 + 0xE15 = 0x75A10E15
两者的差值正好是0x3000,和你遇到的情况完全吻合。
说白了就是你把重定位类型标识当成了偏移的一部分来计算,才导致结果多了0x3000。处理这类重定位项时,必须先通过& 0xFFF屏蔽高4位的类型位,只保留低12位的实际偏移再参与计算。
内容的提问来源于stack exchange,提问作者Ofdrykkja
相关产品推荐
相关产品推荐

