Address of Static Variables Changing at Runtime


I'm trying to figure out why the address of a static uint64_t arr[] changes when it's defined in the global scope inside the main executable. It changes from 0x201060 (defined by the linker?) to 0x555555755060 at runtime, and I have no idea why.

Why does this happen, and is there a way I can prevent this behavior?

I have a precompiled binary that does not exhibit this behavior, and I am trying to emulate it.

$ 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 was compiled with the following options: -g -fno-stack-protector -z execstack.

I compiled and ran test.c without ASLR (sudo bash -c 'echo 0 > /proc/sys/kernel/randomize_va_space'), but the result was the same.

The relevant parts of test.c are:

#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) {
     return 0;
asked on Stack Overflow Jan 28, 2018 by James Houghton • edited Jan 28, 2018 by James Houghton

1 Answer


I figured it out :)

It turns out my gcc was outputting PIE executables by default, and passing -no-pie did what I needed. I made the array static in an attempt to keep the address the same, but I suppose that static only keeps the address the same during runtime.

Thank you to Mark Plotnick for your suggestion in the comments!

answered on Stack Overflow Jan 28, 2018 by James Houghton

User contributions licensed under CC BY-SA 3.0