Search code examples
winapiassemblymingwportable-executableida

How mingw32-g++ compiler know where to inject system calls in the WIN32 machine executable?


Today, only for the testing purposes, I came with the following idea, to create and compile a naive source code in CodeBlocks, using Release target to remove the unnecessary debugging code, a main function with three nop operations only to find faster where the entry point for the main function is.

CodeBlocks sample naive program:

CodeBlocks code

Using IDA disassembler, I have seen something strange, OS actually can add aditional machine code calls in the main function (added implicitly), a call to system function which reside in kernel32.dll what is used for OS thread handling.

IDA program view:

IDA View Sample

In the machine code only for test reason the three "nop" (90) was replaced by "and esp, 0FFFFFFF0h", program was re-pached again, this is why "no operation" opcodes are not disponible in the view.

Observed behaviour:

It is logic to create a new thread for each process is opened, as we can explore it in the TaskManager, a process run in it's own thread, that is a reason why compiler add this code (the implicit default thread).

My questions:

How compiler know where to "inject" this call code automatically?

Why this call is not made before in the upper function (sub_401B8C) which will route to main function entry point?


Solution

  • To quote the gcc manual:

    If no init section is available, when GCC compiles any function called main (or more accurately, any function designated as a program entry point by the language front end calling expand_main_function), it inserts a procedure call to __main as the first executable code after the function prologue. The __main function is defined in libgcc2.c and runs the global constructors.