函数的地址是否在每次运行时更改

Does the address of a function change per runtime

本文关键字:运行时 地址 是否 函数      更新时间:2023-10-16

我正在用c++写一些东西,我想从一个文件中读取文本,该文件表明我在程序中声明的字符串和函数之间的相关性。例如,文件可以这样读:

sin:sin
PI:getPi
+:add

我希望代码接受这个并创建一个字符串和函数指针数据结构的哈希表或向量。不幸的是,我意识到代码无法在运行时找到函数的名称,所以我希望能够将这些函数的地址放在文件中。但是,如果每次程序运行或编译时函数的地址都不同,那么这个系统当然就不能工作了。对这些问题的启发或替代解决方案将是伟大的。

可以在编译时安全地获取函数的地址(函数指针)。在启动程序时重新定位函数地址是图像加载器的任务。你不必担心函数地址的改变。

当然不能将函数的地址打印到标准输出中,并将该地址作为数值放入程序中。那就会出现你所描述的问题。

要获得c++函数sin()的地址,只需在代码中使用&sin

要通过字符串获取c++函数的地址,您必须编写如下代码:

if (function_name == "sin") return &sin;
else if (function_name == "add") return &add;
else ...

或具有字符串/函数指针对的合适数据结构。

关键是:不要在文件中存储数字函数地址。直接在程序中获取和使用函数地址。在任何情况下,数值函数地址都不应该对程序产生影响。

也许?

您的系统是否使用ASLR?

地址空间布局随机化,这是现代系统使用的一种技术,用于防止利用执行私有或特权功能执行ROP攻击。

基本上它随机化了函数在内存中的位置。如果您知道基础图像的位置,这是可以克服的,因为一切仍然是相对的。您经常会看到像0xDEADBEEF+13这样的符号。

你不能依赖地址保持固定,因为操作系统可能会采用地址空间布局随机化来降低漏洞利用的有效性。

可能能够依赖函数的相对地址,如果它们都在相同的链接二进制中。选择一个作为底数,然后从所有其他数中减去它。

如果您重新编译和/或重新链接,这些自然都将关闭。我想找一个不同的方法。

其中一种方法是为每个函数使用整数索引,并保留一个表,其中索引对应于哪个函数。它引入了另一个间接层,但会更加健壮。

Edit:如果您不想创建一个静态表,您可以让代码在程序初始化时使用静态对象和构造函数来构建一个。

struct FunctionTable
{
    typedef std::unordered_map<std::string, void *> table;
    static table& get()
    {
        static table the_table;
        return the_table;
    }
    FunctionTable(std::string name, void * func)
    {
        get().insert(name, func);
    }
};
double getPi()
{
    return 3.14159;
}
static FunctionTable ft_getPi = FunctionTable("getPi", getPi);