Windows PE文件中跨节JMP指令目标地址计算方法问询
跨节JMP指令目标地址的计算方法
当你把PE文件通过VirtualAlloc+ReadFile加载到内存(文件镜像)后,要计算跨节JMP的目标地址,核心是理解PE的内存映射规则和x86/x64指令的相对寻址逻辑,以下是具体步骤:
一、基础概念铺垫
PE文件加载到内存时,每个节会被映射到ImageBase + 节的VirtualAddress位置;而磁盘文件里的节数据存储在节的PointerToRawData偏移处。IDA显示的loc_xxxx是内存虚拟地址(VA),对应加载后的内存位置。
二、直接相对JMP(最常见的跨节跳转类型,编码为E9开头)
这类JMP用相对于指令下一条地址的有符号偏移计算目标VA,公式和步骤如下:
- 确定JMP指令的基本信息
- 找到JMP指令在磁盘文件中的原始偏移,计算它在文件镜像内存中的地址:
文件镜像起始地址 + 原始偏移(记为JMP_VA) - 该指令长度固定为5字节(1字节操作码
E9+ 4字节有符号偏移),所以指令下一条地址为:JMP_VA + 5
- 找到JMP指令在磁盘文件中的原始偏移,计算它在文件镜像内存中的地址:
- 读取并转换偏移量
- 从指令中读取4字节的偏移数据(注意小端序),转换为有符号整数(记为
disp32)
- 从指令中读取4字节的偏移数据(注意小端序),转换为有符号整数(记为
- 计算目标VA
- 目标VA =
指令下一条地址 + disp32 - 这个结果就是IDA显示的
loc_xxxx,比如你示例中的0x140845BB8
- 目标VA =
结合你的示例验证
示例中JMP指令VA为0x14005D74E,目标VA为0x140845BB8:
- 指令下一条地址:
0x14005D74E + 5 = 0x14005D753 - 偏移量:
0x140845BB8 - 0x14005D753 = 0x7E84665 - 指令中存储的就是小端序的
0x65847E00,IDA通过反向计算得到目标VA,再匹配到seg007节的位置。
三、间接JMP(如FF 25开头的跳转)
这类JMP通过内存地址间接获取目标VA,步骤:
- 指令长度为6字节(2字节操作码
FF 25+ 4字节偏移),指令下一条地址 =JMP_VA + 6 - 读取4字节偏移量,计算出内存地址:
指令下一条地址 + disp32 - 从该内存地址读取8字节(x64)或4字节(x86)数据,即为目标VA
四、文件镜像到加载后内存的映射
如果需要从目标VA找到磁盘文件中的对应偏移:
- 计算目标VA相对于ImageBase的偏移:
目标VA - ImageBase = 节VirtualAddress + 节内偏移 - 找到对应节的
PointerToRawData,磁盘偏移 =PointerToRawData + 节内偏移(若节内偏移超过节的SizeOfRawData,超出部分为零填充,磁盘中无对应数据)
内容的提问来源于stack exchange,提问作者Ayyware
相关产品推荐
相关产品推荐

