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) {
func(arr);
return 0;
}
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!
User contributions licensed under CC BY-SA 3.0