繁体   English   中英

为什么C变量的内存地址不固定?

[英]Why aren't memory addresses of C variables fixed?

我是一名CS本科生,刚刚了解虚拟内存。 我对以下程序进行了实验。

#include<stdio.h>
int ready0; 
int main(void) {
  int ready;
  printf("ready0 at %p, ready at %p. \n", (void*)&ready0, (void*)&ready); 
} 

我认为,由于该程序仅处理虚拟内存,因此在程序看来,它是计算机上唯一运行的进程。 我还看了看反汇编的代码,它看起来很确定。 因此,如果我多次运行该程序,结果应该是相同的。 但是,实验表明事实并非如此。 为什么实验与我预期的不同? 是什么导致每次我运行该程序时结果都不同?

如果您有兴趣,这里是Mac OS X Yosemite上的一些实验结果。

$ ./sp
ready0 at 0x102b18018, ready at 0x7fff5d0e876c. 
$ ./sp
ready0 at 0x107c09018, ready at 0x7fff57ff776c. 
$ ./sp
ready0 at 0x10aa9c018, ready at 0x7fff5516476c. 
$ ./sp
ready0 at 0x10d56d018, ready at 0x7fff5269376c. 
$ ./sp
ready0 at 0x10da1c018, ready at 0x7fff521e476c. 
$ ./sp
ready0 at 0x109aff018, ready at 0x7fff5610176c. 
$ ./sp
ready0 at 0x107c31018, ready at 0x7fff57fcf76c. 
$ ./sp
ready0 at 0x10fab1018, ready at 0x7fff5014f76c. 

在过去,您通常是对的。 指向main入口的堆栈指针通常是相同的(但它也取决于您的环境,请参见environ(7) ...)。 在您的ABI规范和execve(2) syscall中提供了详细信息(尤其是Linux 您(和我的)ABI通常是AMD64 ABI

为了安全起见,当前系统具有ASLR (地址空间布局随机化)((您可以通过echo 0 > /proc/sys/kernel/randomize_va_space禁用系统范围的root用户运行权限;这会打开一个安全漏洞)。 因此,进入main的堆栈指针有点随机。

提示:如果使用gdb监视点,则可能要禁用ASLR。

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

从Wiki:

*

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

好处

地址空间随机化使攻击者更难预测目标地址,从而阻碍了某些类型的安全攻击。 例如,尝试执行返回libc攻击的攻击者必须找到要执行的代码,而其他尝试执行注入到堆栈中的shellcode的其他攻击者则必须先找到堆栈。 在这两种情况下,相关的内存地址都会被攻击者遮盖。 必须猜测这些值,并且由于应用程序崩溃,通常无法恢复错误的猜测。

*

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM