为什么variables的地址在运行之间不断变化

我做了两个相互精确拷贝的C程序。使用gcc编译器在Linux平台(Ubuntu 10.04)上编译了它们,并获得了两个单独的可执行文件。然后使用objdump获得了两个可执行文件的汇编代码,发现汇编代码为完全相同甚至两个汇编文件中相应指令的地址是一致的。程序是在其中打印一个variables的地址。运行的程序产生不同的地址,而且每次运行时同一个程序产生一个不同的地址。为什么在两个程序中代码行的地址是相同的,但是即使对于同一个程序,variables的地址每次运行都会改变。我认为在屏幕上显示variables的地址是虚拟地址,但是如果虚拟地址为虚拟地址每次都一样。objdump获得的汇编代码中显示的地址也是虚拟的吗?

这是由于地址空间布局随机化 。

引用维基百科:

地址空间布局随机化(ASLR)是一种计算机安全方法,它包括在进程的地址空间中随机排列关键数据区域的位置,通常包括可执行文件的基础,库,堆和堆栈的位置。

优点

地址空间随机化通过使攻击者更难预测目标地址来阻碍某些类型的安全攻击。 例如,试图执行return-to-libc攻击的攻击者必须找到要执行的代码,而尝试执行注入堆栈的shellcode的其他攻击者必须首先找到堆栈。 在这两种情况下,相关的内存地址都被黑客掩盖了。 这些值必须被猜测,并且由于应用程序崩溃,错误的猜测通常是不可恢复的。

例如,当我在我的Ubuntu 10.10盒子上反复运行由以下C代码生成的相同的可执行文件时:

#include <stdio.h> int g = 0; int main() { int x = 0; printf("%p %p\n", &x, &g); } 

局部变量( x )的地址保持不变,但全局变量( g )的地址保持不变。

是的,您将始终在地址变量中更改值。 这是因为,当程序进入运行模式时,当它执行变量声明语句时,每次控制器都会根据可用的内存位置创建变量。 这是唯一的原因,每次它返回不同的地址值。