1

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

sin:sin
PI:getPi
+:add

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

4

3 回答 3

2

也许?

您的系统是否使用 ASLR?

地址空间布局随机化,它是现代系统用来防止漏洞利用执行私有或特权函数执行 ROP 攻击的一种技术。

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

有关详细信息,请参阅ASLR

于 2013-03-26T22:28:40.850 回答
2

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

您当然不能做的是将函数的地址打印到标准输出并将该地址作为数值放入您的程序中。那会受到您描述的问题的影响。

要获取 C++ 函数的地址,sin()只需&sin在您的代码中使用。

要通过字符串获取 C++ 函数的地址,您必须具有如下代码:

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

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

要点是:不要将数字函数地址存储在文件中。直接在你的程序中获取和使用函数地址。数字函数地址对您的程序应该无关紧要。

于 2013-03-26T22:29:12.247 回答
1

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

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

如果您重新编译和/或重新链接,这自然会全部关闭。我会尝试寻找不同的方法。

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

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

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);
于 2013-03-26T22:33:13.860 回答