函数的地址是否在每次运行时更改
Does the address of a function change per runtime
我正在用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);
- CMake-按正确顺序将项目与C运行时对象文件链接
- 我在c++代码中生成了一个运行时#3异常
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- 删除指向指针的指针是运行时错误吗
- 如何用参数值调用函数(仅在运行时已知)
- 为什么即使使用-cudart-static进行编译,库用户仍然需要链接到cuda运行时
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- c++中的指针和运行时错误
- 运行时错误:引用绑定到类型"int"的未对齐地址0xbebebebebebebec6,这需要 4 个字节对齐 (stl_vector.h)
- 运行时错误地址清理器:LEETCODE 中的致命信号
- 在每个运行时将函数保存到相同的地址
- 是否可以在运行时为宏分配地址
- 如何在-fsanitize=地址下运行时抑制泄漏清理器报告?
- 地址清理器和运行时加载动态库 ->(<未知模块>)
- getPeername()在客户端在虚拟机上运行时返回我的本地主机地址
- 当应用在 Android 设备上运行时,具有 new 的 c++ 对象的内存分配将获得相同的地址
- 如何修改运行时加载DLL的导入地址表
- 为什么每次运行时函数的地址都会改变?
- 函数的地址是否在每次运行时更改
- CUDA 运行时错误:未指定的启动失败 & 超出范围的共享或本地地址