I’m trying to debug this simple C program:
#include <stdio.h> int main(int argc, char *argv[]) { printf("Hellon"); }
But when I disassemble the main function I get this:
(gdb) disas main Dump of assembler code for function main: 0x000000000000063a <+0>: push rbp 0x000000000000063b <+1>: mov rbp,rsp 0x000000000000063e <+4>: sub rsp,0x10 0x0000000000000642 <+8>: mov DWORD PTR [rbp-0x4],edi 0x0000000000000645 <+11>: mov QWORD PTR [rbp-0x10],rsi 0x0000000000000649 <+15>: lea rdi,[rip+0x94] # 0x6e4 0x0000000000000650 <+22>: call 0x510 <puts@plt> 0x0000000000000655 <+27>: mov eax,0x0 0x000000000000065a <+32>: leave 0x000000000000065b <+33>: ret End of assembler dump.
And this is already pretty strange because addresses starts with a prefix of 4… for 32 bit executables and 8… for 64 bit executables I think.
But going on I then put a breakpoint:
(gdb) b *0x0000000000000650 Breakpoint 1 at 0x650
I run it and I get this error message:
Warning: Cannot insert breakpoint 1. Cannot access memory at address 0x650
Advertisement
Answer
Your code was most probably compiled as Position-Independent Executable (PIE) to allow Address Space Layout Randomization (ASLR). On some systems, gcc is configured to create PIEs by default (that implies the options -pie -fPIE
being passed to gcc).
When you start GDB to debug a PIE, it starts reading addresses from 0
, since your executable was not started yet, and therefore not relocated (in PIEs, all addresses including the .text
section are relocatable and they start at 0
, similar to a dynamic shared object). This is a sample output:
$ gcc -o prog main.c -pie -fPIE $ gdb -q prog Reading symbols from prog...(no debugging symbols found)...done. gdb-peda$ disassemble main Dump of assembler code for function main: 0x000000000000071a <+0>: push rbp 0x000000000000071b <+1>: mov rbp,rsp 0x000000000000071e <+4>: sub rsp,0x10 0x0000000000000722 <+8>: mov DWORD PTR [rbp-0x4],edi 0x0000000000000725 <+11>: mov QWORD PTR [rbp-0x10],rsi 0x0000000000000729 <+15>: lea rdi,[rip+0x94] # 0x7c4 0x0000000000000730 <+22>: call 0x5d0 <puts@plt> 0x0000000000000735 <+27>: mov eax,0x0 0x000000000000073a <+32>: leave 0x000000000000073b <+33>: ret End of assembler dump.
As you can see, this shows a similar output to yours, with .text
adresses starting at low values.
Relocation takes place once you start your executable, so after that, your code will be placed at some random address in your process memory:
gdb-peda$ start ... gdb-peda$ disassemble main Dump of assembler code for function main: 0x00002b1c8f17271a <+0>: push rbp 0x00002b1c8f17271b <+1>: mov rbp,rsp => 0x00002b1c8f17271e <+4>: sub rsp,0x10 0x00002b1c8f172722 <+8>: mov DWORD PTR [rbp-0x4],edi 0x00002b1c8f172725 <+11>: mov QWORD PTR [rbp-0x10],rsi 0x00002b1c8f172729 <+15>: lea rdi,[rip+0x94] # 0x2b1c8f1727c4 0x00002b1c8f172730 <+22>: call 0x2b1c8f1725d0 <puts@plt> 0x00002b1c8f172735 <+27>: mov eax,0x0 0x00002b1c8f17273a <+32>: leave 0x00002b1c8f17273b <+33>: ret End of assembler dump.
As you can see, the addresses now take “real” values that you can set breakpoints to. Note that usually you will still not see the effect of ASLR in GDB though, since it disables randomization by default (debugging a program with randomized location would be cumbersome). You can check this with show disable-randomization
. If you really want to see the effects of ASLR in your PIE, set disable-randomization off
. Then every run will relocate your code to random addresses.
So the bottom line is: When debugging PIE code, start
your program in GDB first and then figure out the addresses.
Alternatively, you can explicitly disable the creation of PIE code and compile your application using gcc filename.c -o filename -no-pie -fno-PIE
.
My system does not enforce PIE creation by default, so unfortunately I don’t know about the implications of disabling PIE on such a system (would be glad to see comments on that).
For a more comprehensive explanation of position-independent code (PIC) in general (which is of utmost importance for shared libraries), have a look at Ulrich Drepper’s paper “How to Write Shared Libraries”.