可执行文件中的函数偏移是否为固定值且写入PE文件?
PE文件函数偏移固定性相关解答
针对你给出的如下示例C++代码编译生成的exe:
#include <stdio.h> void my_int_func(int x) { printf("%d\n", x); } int main() { void (*foo)(int); foo = &my_int_func; foo(78); return 0; }
关于函数偏移的相关特性说明如下:
核心结论
- 只要exe文件未被加壳、篡改、重新编译,两类偏移都是固定值:
- 相对虚拟地址(RVA):即函数相对于PE文件内存加载基址的偏移,该值固定,可通过PE结构的段表、导出表(若函数被导出)等信息查询得到
- 文件偏移:即函数数据相对于磁盘上exe文件起始位置的偏移,该值也固定,可通过RVA结合段表的
VirtualAddress和PointerToRawData字段换算得到
- 仅函数的绝对内存地址可能发生变化:如果编译时开启了地址空间布局随机化(ASLR,VS等编译器Release版本默认开启),系统加载exe时会随机分配基址,此时绝对地址 = 运行时实际加载基址 + 固定RVA,仅基址动态变化,RVA仍然固定。
第三方工具使用建议
- 若工具是静态解析磁盘上的exe文件,可直接将函数的RVA或文件偏移作为固定常量使用
- 若工具是运行时读取内存中的exe数据,只需先获取exe的实际加载基址,加上固定RVA即可得到正确的函数地址,无需每次重新识别函数偏移
内容的提问来源于stack exchange,提问作者Daros7
相关产品推荐
相关产品推荐

