【问题标题】:Function offsets in the executable file可执行文件中的函数偏移量
【发布时间】:2021-08-04 14:48:52
【问题描述】:

有一个编译文件(exe),例如对于这样一个简单的 c++ 程序:

#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;
    }

函数偏移量始终是固定的并写入PE 对吗?我之所以这么问,是因为我有一些 3-rd 方程序可以在一些 exe 文件上运行,并将函数偏移量用作常量、固定值。

谢谢帮助。

【问题讨论】:

    标签: windows exe executable portable-executable


    【解决方案1】:

    函数偏移量始终是固定的并写入 PE 是否正确?

    是的,一旦编译可执行二进制文件就不会改变,因此偏移量、RVA(相对虚拟地址)和 VA(虚拟地址)始终保持不变。 (注意,Sourena 建议:VA 受制于ASLR,这是在 Windows 上每次启动的;所以只要您不重新启动,基本上就保持不变。

    请注意,如果您重新编译代码,生成的二进制文件可能会因相同的源代码而完全不同(即函数、全局变量以及几乎所有内容都可能位于完全不同的地址)。

    对于完全不同的源代码,生成的二进制文件将完全不同。

    总而言之,如果您的工具针对特定版本,则可以使用硬编码偏移量,但一旦重新编译(或更改)程序,那么工具肯定会失败。

    【讨论】:

    • 如果my_int_func在模块外部(比如一个导入的函数),那么它的偏移量会在运行时改变。
    • @Neitsa,VA 并不总是相同的。 VA 基于 ImageBase 值,它在 PE 文件中始终相同,但不能保证操作系统将 PE 文件加载到与 ImageBase 中指定的完全相同的地址(因为 ASLR)。因此,您只能指望 RVA 而不是 VA。
    • @Sourena 是的,你是对的,这是我应该做到的;在我看来,VA 保持不变“每次启动”,但如果您不知道 Windows 的 ASLR 是每次启动,这显然会产生误导。
    猜你喜欢
    • 2019-08-13
    • 2014-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多