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

Hol*_*c21 11 c c++

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

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

示例输出 #1:

0x563ac3667139
Run Code Online (Sandbox Code Playgroud)

示例输出 #2:

0x55e3903a9139
Run Code Online (Sandbox Code Playgroud)

Fir*_*cer 19

在许多现代系统上,在链接时它将确定函数相对于基地址模块的地址。加载模块(exe、dll 等)时,地址空间布局随机化 (ASLR)会为其提供不同的基地址。

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

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

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

另见重定位(计算)


Lig*_*ica 9

这是一种称为地址空间布局随机化的安全技术。

它会在每次执行时故意移动内容,使攻击者更难知道您的进程中的数据位并对其进行黑客攻击。

  • @TruthSeeker此方法仅在引入̵C̵h̵e̵e̵s̵e̵c̵a̵k̵e̵ PIE(位置无关的可执行文件)后才有效。使用标志“-no-pie”,这将在固定位置加载主二进制文件,并且“main()”的地址将不再变化。 (2认同)