为什么每次运行程序时argc的地址都不同?

Mar*_*ian 7 c linux gcc elf

今天我遇到了以下情况.我运行了几次以下程序:

#include <stdio.h>
int main(int argc, char **argv) {
  printf("%p\n", &argc);
}
Run Code Online (Sandbox Code Playgroud)

在带有linux和gcc编译器的Intel i7上,该程序在每次运行时提供不同的输出:

i7:~/tmp$ gcc t.c 
i7:~/tmp$ ./a.out 
0x7fffc127636c
i7:~/tmp$ ./a.out 
0x7fffdefed97c
i7:~/tmp$ ./a.out 
0x7fff7f32454c
Run Code Online (Sandbox Code Playgroud)

我希望linux,elf,gcc或其他任何相关的开发人员都会尝试确保在每次调用程序时堆栈都位于同一地址上.它将有助于跟踪和修复在处理指针和变量地址时可能发生的奇怪错误(类似于虚拟地址更适合修复与物理地址相比的错误).

我想知道为什么在每次调用程序时堆栈都映射到不同的地址?

Jea*_*nès 14

这是出于安全原因,因此攻击者无法对变量,函数的确切内存布局做出太多假设......

让我鼓励您阅读有关"缓冲区溢出攻击"(可能的原因之一)和"ASLR"(地址空间布局随机化)的可能预防性部分策划之一.

所以编译器生成固定地址的情况就是如此,但运行时改变了一些事情......

如果要更改该行为,请参阅在Linux中禁用ASLR.