Chapter 13: Advanced Static Analysis with IDA Pro
311
PART IV
You will seldom desire to reverse-engineer all of the startup code added by the compiler,
so locating main is a handy thing to be able to do. Fortunately, each compiler
tends to have its own style of initialization code, so with practice you will be able to recognize
the compiler that was used based simply on the startup sequence. Since the last
thing that the startup sequence does is transfer control to main, you should be able to
locate main easily regardless of whether a binary has been stripped. Listing 13-1 shows
the _start function for a gcc compiled binary that has not been stripped.
Listing 13-1
_start proc near
xor ebp, ebp
pop esi
mov ecx, esp
and esp, 0FFFFFFF0h
push eax
push esp
push edx
push offset __libc_csu_fini
push offset __libc_csu_init
push ecx
push esi
push offset main
call ___libc_start_main
hlt
_start endp
Notice that main is not called directly; rather it is passed as a parameter to the library
function __libc_start_main. The __libc_start_main function takes care of libc initialization,
pushing the proper arguments to main, and finally transferring control to main.
Note that main is the last parameter pushed before the call to __libc_start_main.
Pages:
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559