c++ - 为什么每次执行时函数的地址都不同?

标签 c++ c

这个问题在这里已经有了答案:





Does the address of a function change per runtime [duplicate]

(3 个回答)



Why does the address of a function change with every run?

(4 个回答)


2年前关闭。




可执行代码的地址是在链接时决定的,不是吗?

#include <stdio.h>
int main ()
{
     printf("%p", (void*)&main);
     return 0;
}

示例输出#1:
0x563ac3667139

示例输出#2:
0x55e3903a9139

最佳答案

在许多现代系统上,在链接时它将确定函数相对于基地址模块的地址。加载模块(exe、dll 等)时,Address Space Layout Randomization (ASLR)给它一个不同的基地址。

这是为了安全,这意味着函数的地址是不可预测的。这意味着某些攻击可能例如溢出堆栈变量以覆盖返回地址或使用其他函数(出于恶意目的)的函数指针,无法轻松预测用哪个地址覆盖它,它会因运行而异.

重定位基地址的能力也解决了冲突的实际问题,如果你加载为同一个基地址独立编译的a.dll和b.dll,那将不起作用,所以能够重定位一个解决了冲突。

在机器代码级别,这很好,因为大多数跳转和调用使用相对指令偏移,而不是绝对。尽管某些结构在加载模块时会被动态修补,或者使用某种形式的“表格”来填充正确的地址。

另见 Relocation (computing)

关于c++ - 为什么每次执行时函数的地址都不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59683246/

相关文章:

c - 使用指向c中指针变量的指针将二维数组传递给函数

c - 为什么第一个 gets() 输入在此 C 程序中丢失?

c - 当传递函数时我们什么时候需要&?

c++ - 为什么我的数组只接受它们中的第一个数字?

c++ - 如何查看可执行文件中的宏定义值

C++:为什么这个 constexpr 模板函数会在 VS2017 中导致内部错误?(在 gcc 中是可以的)

c - 菜单驱动程序以无限循环结束

c++ - 成员变量默认初始化模板

c++ - 如何使用值获取结构的索引

c - C中的Malloc和数组索引混淆