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

Why is the address of a function different on each execution?

本文关键字:地址 函数 执行 为什么      更新时间:2023-10-16

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

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

示例输出 #1:

0x563ac3667139

示例输出 #2:

0x55e3903a9139

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

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

重新定位基址的能力也解决了冲突的实际问题,如果你加载a.dll和b.dll,它们是为同一个基址独立编译的,这是行不通的,所以能够重新定位一个可以解决冲突。

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

另请参阅重新定位(计算(

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

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