Problem: I program in C/C++ main()? Where is main()?
Solution: In Windows XP (and its ancestors), programs written in C/C++ using Microsoft Visual C++ don’t actually start executing from the main() function. Instead, after the image is loaded into memory, control is passed to the Startup()23 function located in crt0.c (or in crtexe.c for dynamic linking or in
wincmdln.c for console applications). This function initializes the global variables argv, argc, _osver, _winmajor, _winminor, _winver, and environ; initializes the heap for the process; calls main(); and exits when main() returns.
The important thing to remember is that the Start()function always passes some (3 or 4) arguments(argc, argv, and environ) to the main() function:
#ifdef WPRFLAG
lpszCommandLine = _wwincmdln();
mainret = wWinMain(
#else /* WPRFLAG */
lpszCommandLine = _wincmdln();
mainret = WinMain(
#endif /* WPRFLAG */
GetModuleHandleA(NULL),
NULL,
lpszCommandLine,
StartupInfo.dwFlags & STARTF_USESHOWWINDOW
? StartupInfo.wShowWindow
: SW_SHOWDEFAULT
);
#else /* _WINMAIN_ */
#ifdef WPRFLAG
__winitenv = _wenviron;
mainret = wmain(__argc, __wargv, _wenviron);
#else /* WPRFLAG */
__initenv = _environ;
mainret = main(__argc, __argv, _environ);
#endif /* WPRFLAG */
Looking at the disassembled start() function of Bagle, from IDA Pro:
.text:00401120;*************** SU B R O U T I N E ***************************************
.text:00401120
.text:00401120 ; Attributes: library function bp-based frame
.text:00401120
.text:00401120 public mainCRTStartup
.text:00401120 mainCRTStartup proc near
.text:00401120
.text:00401120 var_1C = dword ptr -1Ch
.text:00401120 var_18 = dword ptr -18h
.text:00401120 var_4 = dword ptr -4
.text:00401120
.text:00401120 push ebp
.text:00401121 mov ebp, esp
.text:00401123 push 0FFFFFFFFh
.text:00401125 push offset stru_422138
.text:0040112A push offset __except_handler3
.text:0040112F mov eax, large fs:0
.text:00401135 push eax
.text:00401136 mov large fs:0, esp
.text:0040113D add esp, 0FFFFFFF0h
.text:00401140 push ebx
.text:00401141 push esi
.text:00401142 push edi
.text:00401143 mov [ebp+var_18], esp
.text:00401146 call ds:GetVersion() ; Get current version number of Windows
.text:00401146 ; and information about the operating system platform
.text:0040114C mov _osver, eax
.text:00401218;*************** SU B R O U T I N E ***************************************
A quick skim through the subroutine, and we see that IDA Pro didn’t find a call to the main() function. How could this be? The answer lies with the fact that the developer can change the start up code of his compiler and set the entry-point symbol (the function called by the start-up code) manually. So this requires us to inspect the start-up code more closely.
The address 00401120 is where the executaility begins to run once it’s loaded.This address can also be found by using the dumpbin utility:
dumpbin /headers hello.exe
and adding RVA (Relative Virtual Address) to the base address:
Microsoft (R) COFF Binary File Dumper Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
Dump of file hello.exe
PE signature found
...
OPTIONAL HEADER VALUES
…
1120 RVA of entry point
1000 base of code
1000 base of data
400000 image base