Stopping at the first machine code instruction in GDB

After loading an executable into gdb, how do I break at the entry point, before the first instruction is executed?

The executable I'm analyzing is a piece of malware that's encrypted so break main does absolutely nothing.


Solution 1:

Starting with GDB 8.1, there's a special command for this: starti. Example GDB session:

$ gdb /bin/true
Reading symbols from /bin/true...(no debugging symbols found)...done.
(gdb) starti
Starting program: /bin/true 

Program stopped.
0xf7fdd800 in _start () from /lib/ld-linux.so.2
(gdb) x/5i $pc
=> 0xf7fdd800 <_start>: mov    eax,esp
   0xf7fdd802 <_start+2>:       call   0xf7fe2160 <_dl_start>
   0xf7fdd807 <_dl_start_user>: mov    edi,eax
   0xf7fdd809 <_dl_start_user+2>:       call   0xf7fdd7f0
   0xf7fdd80e <_dl_start_user+7>:       add    ebx,0x1f7e6

Solution 2:

The info files command might give you an address you can break on:

(gdb) info files
    ...
    Entry point: 0x80000000
    ...
(gdb) break *0x80000000
(gdb) run

Solution 3:

This hack was obsoleted by starti, but useful if you're stuck with older GDB.

The no-brainer solution is to use the side-effect of failure to set a breakpoint:

$ gdb /bin/true
Reading symbols from /bin/true...(no debugging symbols found)...done.
(gdb) b *0
Breakpoint 1 at 0x0
(gdb) r
Starting program: /bin/true 
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x0

(gdb) disas
Dump of assembler code for function _start:
=> 0xf7fdd800 <+0>:     mov    eax,esp
   0xf7fdd802 <+2>:     call   0xf7fe2160 <_dl_start>
End of assembler dump.

(gdb) d 1       # delete the faulty breakpoint

(You need to delete the invalid breakpoint before you can continue or single-step.)

Idea taken from this answer at RE.SE.

Solution 4:

"b _start" or "b start" might or might not work. If not, find out the entrypoint address with readelf/objdump and use "b *0x<hex address>".