I am diving into Reverse Engineering, which is really fun.
I have a question however: why the addresses of instructions I get from GDB and Objdump are the same?
Shouldn't the binary be loaded at a different address every time?
Thank you. Julien
GDB disables ASLR by default. If you set disable-randomization off
, then a PIE executable (Position Indepdent) will load at a randomized address even when you run
it from inside GDB.
See 32-bit absolute addresses no longer allowed in x86-64 Linux? for more about PIE.
Position-dependent executables are always loaded at the same address, and only their stack address can be randomized. The code+data can hard-code addresses as 32-bit absolute, and they don't contain relocation info for every place where that was done. (e.g. like mov $string, %edi
; call puts
).
Look at gcc's code-gen for Hello World with/without -fPIE
on the Godbolt compiler explorer.
.LC0:
.string "Hello World!"
main:
lea rdi, .LC0[rip] # RIP-relative with -fPIE
sub rsp, 8
call puts@PLT
xor eax, eax
add rsp, 8
ret
but with -fno-PIE
(the default on Godbolt, often not the default on modern Linux distros), you get mov edi, OFFSET FLAT:.LC0
, a 32-bit absolute address.
(The rest of the code is the same, except it emits call puts
and lets the linker convert that to call puts@PLT
. Use -fno-plt
to inline an indirect call
through the GOT address.)