【问题标题】:address randomization: print address of a static var in c地址随机化:在 c 中打印静态 var 的地址
【发布时间】:2016-12-08 10:17:20
【问题描述】:

我正在阅读一本操作系统教科书,有一个示例验证系统是否支持虚拟地址,并说以下程序每次都应打印相同的结果。我在我的 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 中运行它有什么不同呢?为什么直接运行看到地址不一样?

【问题讨论】:

  • 书已经过时了,没想到Address space layout randomization
  • 它确实提到了 ASLR,所以我的系统甚至随机化了静态变量的位置?
  • 在实现 ASLR 的级别上,我认为操作系统并不真正关心它正在为其创建映射的特定内存页面中的内容。基本上,“静态变量”只是“可写内存中的东西”。
  • @user2018791 静态变量与操作系统加载可执行文件的地址相关,因此如果操作系统在随机地址加载可执行文件,它也会影响静态变量。
  • 我相信 ASLR 被应用为虚拟内存映射的一部分。物理地址(bss、数据等)将保持不变,但您将获得随机的虚拟地址。

标签: c static virtual-memory


【解决方案1】:

你的书很旧。今天的许多操作系统都在随机化程序和库的加载位置,以使事情更安全地抵御某些攻击。

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

【讨论】:

    【解决方案2】:

    GDB中,我们总是得到相同的地址,即使在不同的进程中运行,但如果直接在Linux中运行,正常行为应该如下所示

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

    因为这是因为在 GDB 中,disable-randomizationdefaulton 开启>。如果我们期望有规律的输出,它应该被关闭

    set disable-randomization off
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-07
      • 2017-10-02
      • 2020-03-22
      相关资源
      最近更新 更多