地址随机化:c中静态变量的打印地址

时间:2016-12-08 10:17:20

标签: c static virtual-memory

我正在阅读操作系统教科书,有一个示例验证系统是否支持虚拟地址,并说下面的程序每次都应该打印相同的结果。我在macbook pro上看到了一些不同。

#include <stdio.h>

int var = 0;
int main(void)
{
  var += 1;
  printf("Address: %x, value: %d\n", &var, var);
  return 0;
}

运行时,我看到地址在某些字节中发生了变化(但不是全部):

./main
Address: e8c6018, value: 1
./main
Address: 9032018, value: 1
./main
Address: 1bc7018, value: 1

当我在GDB中运行时,我总是看到1018:

(gdb) r
Starting program: /Users/xilan/temp/main
Address: 1018, value: 1
[Inferior 1 (process 19631) exited normally]
(gdb) r
Starting program: /Users/xilan/temp/main
Address: 1018, value: 1
[Inferior 1 (process 19636) exited normally]
(gdb) r
Starting program: /Users/xilan/temp/main
Address: 1018, value: 1
[Inferior 1 (process 19654) exited normally]

那么在GDB中直接运行它有什么不同?为什么我直接运行时会看到地址变化?

2 个答案:

答案 0 :(得分:2)

你的书太旧了。今天的许多操作系统都是随机编写的,其中加载了程序和库,以使某些攻击更加安全。

MacOS随机编写程序加载到内存中的位置。它确实禁用了gdb的随机化,这就是为什么地址在gdb中始终看起来相同的原因。

答案 1 :(得分:2)

GDB 中,我们总是获得相同的地址,甚至可以使用不同的进程运行,但正常行为应如下所示,如果直接在Linux中运行

./main
Address: e8c6018, value: 1
./main
Address: 9032018, value: 1
./main
Address: 1bc7018, value: 1

因为这是因为在 GDB 中,禁用随机化默认 >。如果我们期望定期输出,则应将其设置为关闭

set disable-randomization off

参考链接:http://visualgdb.com/gdbreference/commands/set_disable-randomization