我正在用c ++编写一些东西,我希望从文件中读取文本,该文件指示我在程序中声明的字符串和函数之间的相关性。例如,文件可以是:
sin:sin
PI:getPi
+:add
我想让代码接受它并创建一个字符串或字符串和函数指针数据结构的向量。不幸的是,我意识到代码在运行时无法找到函数的名称,所以我希望能够将这些函数的地址放在文件中。但是,如果每次程序运行或编译时函数的地址都不同,那么这个系统当然不会起作用。启蒙,或任何这些问题的替代解决方案都会很棒。
答案 0 :(得分:2)
可能?
您的系统是否使用ASLR?
地址空间布局随机化,它是现代系统用来防止攻击执行私有或私有函数执行ROP攻击的技术。
基本上它随机化了内存中函数的位置。如果你知道基本图像的位置,这是可以解决的,因为一切都是相对的。你会经常看到像0xDEADBEEF + 13这样的符号。
有关详细信息,请参阅ASLR。
答案 1 :(得分:2)
您可以在编译时安全地获取函数地址(函数指针)。启动程序时重定位功能地址是图像加载器的任务。您不必担心功能更改的地址。
当然,您不能将函数的地址打印到stdout,并将此地址作为数值放入程序中。那会受到你描述的问题的困扰。
要获取C ++函数sin()
的地址,只需在代码中使用&sin
。
要通过字符串获取C ++函数的地址,您必须具有以下代码:
if (function_name == "sin") return &sin;
else if (function_name == "add") return &add;
else ...
或具有字符串/函数指针对的合适数据结构。
重点是:不要将数字函数地址存储在文件中。直接在程序中获取和使用函数地址。数字函数地址对您的程序无关紧要。
答案 2 :(得分:1)
您不能依赖固定的地址,因为操作系统可能会使用address space layout randomization来降低漏洞利用的效率。
你可能能够依赖函数的相对地址,如果它们都在同一个链接二进制文件中。选择一个作为基础,然后从其他所有中减去它。
当然,如果你重新编译和/或重新链接,这将全部关闭。我试着找到一种不同的方法。
一种这样的方法是对每个函数使用整数索引,并保持一个表对应哪个函数的索引。它引入了另一层间接,但会更加健壮。
编辑:如果您不想创建静态表,可以使用静态对象和构造函数让代码在程序初始化时构建一个。
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);