【问题标题】:Address of Static Variables Changing at Runtime运行时更改的静态变量地址
【发布时间】:2018-07-07 00:11:21
【问题描述】:

我试图弄清楚为什么 static uint64_t arr[] 的地址在主可执行文件内的全局范围内定义时会发生变化。 它在运行时从0x201060(由链接器定义?)变为0x555555755060,我不知道为什么。

为什么会发生这种情况,有什么方法可以防止这种行为吗?

我有一个没有表现出这种行为的预编译二进制文件,我正在尝试模拟它。

$ gdb a.out   # compiled from test.c
GNU gdb (GDB) 8.0.1...
Reading symbols from a.out...done.
(gdb) x/x arr
0x201060 <arr>: 0x00000024
(gdb) b main
Breakpoint 1 at 0x6e9: file test.c, line 116.
(gdb) run
Starting program: ... 
Breakpoint 1, main (argc=1, argv=0x7fffffffdb28) at test.c:116
116     if(argc != 2) {
(gdb) x/x arr
0x555555755060 <arr>:   0x00000024

test.c 使用以下选项编译:-g -fno-stack-protector -z execstack。

我在没有 ASLR (sudo bash -c 'echo 0 &gt; /proc/sys/kernel/randomize_va_space') 的情况下编译并运行了 test.c,但结果是一样的。

test.c的相关部分是:

#include <stdint.h>

extern int func(uint64_t[]);

static uint64_t arr[] = {
    0x00000024, 0x00201060,
    0x00201080, 0x00000000,
    0x00000008, 0x002010e0,
    0x002010a0, 0x00000000,
    0x00000032, 0x002010c0,
    ...
    0x00201100, 0x00000000
};


int main(int argc, char** argv) {
     func(arr);
     return 0;
}

【问题讨论】:

  • 为什么要阻止这种行为?
  • 这可能是地址空间布局随机化。也可能是在运行时映射到虚拟内存空间
  • @chux 是的。虚拟内存会通过将每个进程的地址映射到物理内存中的两个不同区域来处理内存冲突。
  • 当您无法理解某些代码的工作原理时,请始终创建Minimal, Complete, and Verifiable Example 向我们展示。例如,是 arr?
  • 请发布gcc -###的输出。默认情况下,您的编译器可能是为生成 PIE 可执行文件而构建的。

标签: c linux memory gdb


【解决方案1】:

我想通了:)

事实证明,我的gcc 默认输出 PIE 可执行文件,而传递 -no-pie 可以满足我的需要。我创建了数组static 以尝试保持地址相同,但我认为static 仅在运行时期间 保持地址相同。

感谢 Mark Plotnick 在 cmets 中提出的建议!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-25
    • 1970-01-01
    • 2016-03-27
    相关资源
    最近更新 更多