Why is "_main" symbol not found when .exe file is loaded in x64dbg?


Writing a simple hello_world.c program, and compile with 32-bit MinGW, the objdump can show symbol table using:

objdump -t hello_world.exe

And the symbol table then have an entry for _main as:

[ 32](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 1) 0x00000460 _main

However, when loading the hello_world.exe file in x64dbg debugger, the _main symbol is not shown, as can be seen from the symbol list below when hello_world module is selected.

enter image description here

enter image description here

This is annoying, since I would like to create a breakpoint at start of user code in hello_world, and using the symbols to jump to the start location would be very convenient.

Any idea on how to get the _main symbols included in the symbol list?

asked on Stack Overflow Aug 13, 2018 by EquipDev • edited Aug 13, 2018 by EquipDev

1 Answer


While PE has support for storing debug information, the symbol table is mostly an ELF concept.

If you look at the PE sections (use objdump -h) you'll see a lot of extra sections not referenced in the PE directories.
These are used by the binutils to extract the DWARF information and show you, for example, the symbol table.

x64dbg is a pure Windows/PE tool and doesn't understand DWARF.
However, it will show you the address of the PE entry-point (rarely the address of the "main" itself though) and will put a breakpoint there for you automatically.
The Entry-point is shown under the export symbols of the binary under inspection.

Entry-point of the PE with an automatic breakpoint, shown in the exported symbols of the binary

Furthermore, x64dbg will break on 'ntdll` allowing you to reach the entry-point with a ninja use of CTRL+F9 (beware of TLS initialization callbacks).

To get to main you can step through the code until you find a call to an address in the .text section or simply a call followed by two calls to cexit and ExitProcess.

Also, given the offset of _main retrieved with objdumpt -t the VA of _main is is BASE ADDRESS + .text RVA + __main OFFSET.
In my case, this was 4010460h

The call to the <code>main</code> is followed by a call to <code>cexit</code> and <code>ExitProcess</code>

answered on Stack Overflow Aug 14, 2018 by Margaret Bloom

User contributions licensed under CC BY-SA 3.0