0

When i type:

gdb mybinary

mybinary is a PIE executatable (Position indépendant Code).

i get a gdb prompt. The binary is not fully loaded in memory. Why do i say that ? This is because we do not know at this step what is the address of main entry point.

It is sometimes possible to type disassemble main, but i my case, the binary do not contains debugging informations.

If a type "run", the loader loads the program in memory and the program runs.

What should i do to force gdb to just run the loader and break on the first instruction in main. Is it possible ?

Thanks

Bob5421
  • 7,757
  • 14
  • 81
  • 175
  • Possible duplicate of [Stopping at the first machine code instruction in GDB](https://stackoverflow.com/questions/10483544/stopping-at-the-first-machine-code-instruction-in-gdb) – ks1322 Mar 27 '18 at 09:00

2 Answers2

2

Is it possible

Sure. Here is one way to do it:

$ echo "int main() { return 0; }" | gcc -xc -
$ gdb -q ./a.out
Reading symbols from ./a.out...(no debugging symbols found)...done.
(gdb) x/i &main
   0x5fa <main>:    push   %rbp

Note that this is a PIE binary, and it has not been relocated yet (no code will ever execute at address 0x5fa on a Linux system).

(gdb) set stop-on-solib-events 1
(gdb) run
Starting program: /tmp/a.out
Stopped due to shared library event (no libraries added or removed)
(gdb) x/i &main
   0x5555555545fa <main>:   push   %rbp

You can now see that the binary has been relocated, and can set a breakpoint on main.

(gdb) b main
Breakpoint 1 at 0x5555555545fe
(gdb) c
Continuing.
Stopped due to shared library event:
  Inferior loaded /lib/x86_64-linux-gnu/libc.so.6
(gdb) c
Continuing.

Breakpoint 1, 0x00005555555545fe in main ()

Voilà.

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
1

In modern GDB, start sets a temporary breakpoint in main (after ASLR) and runs. That command was added in the past couple years, and certainly streamlines things.

Setting a breakpoint on main does also work (at least in recent GDB) even in a PIE executable where main's true address not known until after run. This depends on main existing in the symbol table, but so does start.

b main before run shows it being set at address 0x111d for example, but then after run it's hit at address 0x000055555555511d. Modern GDB apparently knows that ASLR will happen and updates breakpoints that you set symbolically, not via b *0x111d


If there isn't even a main symbol:

You can only use starti to stop before running any user-space instructions at all, like your question title indicates.

Or perhaps @Employed Russian's suggestion of set stop-on-solib-events 1 can help you stop somewhere somewhat interesting even in a stripped binary.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847