为什么 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);
}
我认为既然程序只处理虚拟内存,那么在程序看来它应该是机器上唯一的进程运行ning。我也看了反汇编代码,看起来很有确定性。因此,如果我多次 运行 程序,结果应该是相同的。然而,实验表明情况并非如此。为什么实验与我的预期不同?是什么导致我每次 运行 程序的结果都不同?
如果您有兴趣,这里有几个关于 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)...). Details are given (for Linux notably) in your ABI spec & in execve(2) syscall. Your (and mine) ABI is often AMD64 ABI.
出于安全目的,当前系统具有 ASLR - 地址 space 布局随机化 -(您可以禁用系统范围 echo 0 > /proc/sys/kernel/randomize_va_space
为 运行 作为根;这会打开一个安全漏洞)。因此 main
入口处的堆栈指针有点随机。
提示:如果您使用 gdb
个观察点,您可能希望禁用 ASLR。
这是由于地址 space 布局随机化。
来自维基:
*
Address space layout randomization (ASLR) is a computer security
method which involves randomly arranging the positions of key data
areas, usually including the base of the executable and position of
libraries, heap, and stack, in a process's address space.
好处
Address space randomization hinders some types of security attacks by
making it more difficult for an attacker to predict target addresses.
For example, attackers trying to execute return-to-libc attacks must
locate the code to be executed, while other attackers trying to
execute shellcode injected on the stack have to find the stack first.
In both cases, the related memory addresses are obscured from the
attackers. These values have to be guessed, and a mistaken guess is
not usually recoverable due to the application crashing.
*
我是一名刚刚了解虚拟内存的本科 CS 学生。我用以下程序做了一个实验。
#include<stdio.h>
int ready0;
int main(void) {
int ready;
printf("ready0 at %p, ready at %p. \n", (void*)&ready0, (void*)&ready);
}
我认为既然程序只处理虚拟内存,那么在程序看来它应该是机器上唯一的进程运行ning。我也看了反汇编代码,看起来很有确定性。因此,如果我多次 运行 程序,结果应该是相同的。然而,实验表明情况并非如此。为什么实验与我的预期不同?是什么导致我每次 运行 程序的结果都不同?
如果您有兴趣,这里有几个关于 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)...). Details are given (for Linux notably) in your ABI spec & in execve(2) syscall. Your (and mine) ABI is often AMD64 ABI.
出于安全目的,当前系统具有 ASLR - 地址 space 布局随机化 -(您可以禁用系统范围 echo 0 > /proc/sys/kernel/randomize_va_space
为 运行 作为根;这会打开一个安全漏洞)。因此 main
入口处的堆栈指针有点随机。
提示:如果您使用 gdb
个观察点,您可能希望禁用 ASLR。
这是由于地址 space 布局随机化。
来自维基:
*
Address space layout randomization (ASLR) is a computer security method which involves randomly arranging the positions of key data areas, usually including the base of the executable and position of libraries, heap, and stack, in a process's address space.
好处
Address space randomization hinders some types of security attacks by making it more difficult for an attacker to predict target addresses. For example, attackers trying to execute return-to-libc attacks must locate the code to be executed, while other attackers trying to execute shellcode injected on the stack have to find the stack first. In both cases, the related memory addresses are obscured from the attackers. These values have to be guessed, and a mistaken guess is not usually recoverable due to the application crashing.
*