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

时间:2012-01-23 08:48:26

标签: linux

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

2 个答案:

答案 0 :(得分:5)

归功于address space layout randomization

引用维基百科:

  

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

<强>优势

     

地址空间随机化通过使攻击者更难以预测目标地址来阻碍某些类型的安全攻击。例如,试图执行返回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)的地址保持不变。

答案 1 :(得分:0)

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