You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

全局静态uint64_t数组运行时地址变更原因及解决方法问询

Why Your Static Global Array's Address Shifts Despite Disabling ASLR

Let's break down why your static uint64_t arr[] shows a different address at runtime compared to the linker's assigned value, even after you disabled ASLR.

Key Cause: Position-Independent Executable (PIE) Compilation

The most likely culprit here is that your binary is being compiled as a Position-Independent Executable (PIE). Modern GCC/clang defaults to enabling PIE for security purposes, even if you don't explicitly specify it. Here's how this leads to the address shift:

  • When compiling with PIE, the linker assigns relative virtual addresses (offsets from a base load address) instead of fixed absolute addresses.
  • Even with ASLR disabled (sudo bash -c 'echo 0 > /proc/sys/kernel/randomize_va_space'), PIE binaries load at a fixed default base address (typically 0x555555554000 on x86_64 systems).
  • Your linker-assigned address 0x201060 is the offset from this base. Adding them together: 0x555555554000 + 0x201060 = 0x555555755060—which exactly matches the runtime address you observed in GDB.

In contrast, your precompiled binary was likely built with the -no-pie flag, generating a traditional non-PIE executable. These binaries load at the exact absolute address the linker specifies, so no address shift occurs.

How to Verify This

To confirm PIE is the issue:

  • Check your binary type with this command:
    file a.out
    
    If the output includes "Position-Independent Executable", PIE is enabled.
  • Or inspect the ELF header with readelf:
    readelf -h a.out
    
    Look for the Type field—DYN means it's a PIE binary, while EXEC indicates a non-PIE executable.

Fix: Disable PIE During Compilation

Add the -no-pie flag to your compile command to generate a non-PIE executable, which will use the linker's absolute address at runtime:

gcc -g -fno-stack-protector -z execstack -no-pie test.c -o a.out

After recompiling, when you debug in GDB:

  • The static view (x/x arr before running the program) and runtime view (x/x arr after hitting the breakpoint) will show the same address: 0x201060.

Additional Notes

  • Disabling ASLR only prevents randomization of the load address—it doesn't remove PIE's base address offset. PIE and ASLR are separate features: PIE enables loading at any address, while ASLR chooses that address randomly.
  • The static qualifier on your array only restricts its visibility to the current translation unit; it doesn't affect its memory layout or load address.

内容的提问来源于stack exchange,提问作者James Houghton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:49:09