【收集】啟動函數
阿新 • • 發佈:2018-04-29
源碼 ffffff 編寫 IT 變量初始化 size 一個 ble star
在編寫Win32應用程序時,都必須在源碼裏實現一個WinMain函數。但Windows程序執行並不是從WinMain函數開始的,首先被執行的是啟動函數相關代碼,這段代碼是編譯器生成的。啟動代碼完成初始化進程,再調用WinMain函數。
對於Visual C++程序來說,它調用的是C/C++運行時啟動函數,該函數負責對C/C++運行庫進行初始化。Visual C++配有C運行庫的源代碼,可以在crtsrccrt0.c文件中找到啟動函數的源代碼(安裝時Visual C++必須選取安裝源代碼選項);而用於控制臺程序的啟動代碼存放在crtsrcwincmdln.c文件中。
所有的C/C++運行時啟動函數的作用基本都是相同的:檢索指向新進程的命令行指針,檢索指向新進程的環境變量指針,全局變量初始化,內存堆棧初始化等。當所有的初始化操作完畢後,啟動函數就調用應用程序的進入點函數。調用WinMain函數如下所示:
1 2 3 |
<span style = "font-size: 13.86px;" >GetStartupInfo (&StartupInfo);
Int nMainRetVal = WinMain(GetModuleHandle(NULL),NULL,pszCommandLineAnsi,(StartupInfo.dwFlags&STARTF_USESHOWWINDOW)?StartupInfo.wShowWindow:SW__SHOWDEFAULT);
< / span>
|
當進入點返回時,啟動函數便調用C運行庫的exit函數,將返回值(nMainRetVal)傳遞給它,進行一些必要處理,最後調用系統函數ExitProcess退出。 下面是一個Visual C++編譯的程序,程序啟動代碼的匯編代碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<span style = "font-size: 13.86px;" > 00401180 push ebp
00401181 mov ebp, esp
00401183 push FFFFFFFF
00401185 push 004040D0
0040118A push 00401CB4
0040118F mov eax, dword ptr fs:[ 00000000 ]
00401195 push eax
00401196 mov dword ptr fs:[ 00000000 ], esp
0040119D sub esp, 00000058
004011A0 push ebx
004011A1 push esi
004011A2 push edi
004011A3 mov dword ptr [ebp - 18 ], esp
004011A6 Call KERNEL32.GetVersion ; 確定Windows系統版本
……
004011F4 Call KERNEL32.GetCommandLineA ; 指向進程的完整命令行的指針
……
0040121E push eax
0040121F Call KERNEL32.GetStartupInfoA ; 獲取一個進程的啟動信息
……
00401241 push esi
00401242 Call KERNEL32.GetModuleHandleA ; 返回進程地址空間執行文件基地址
00401248 push eax
00401249 call 00401000 ; 調用用戶編寫的進入點函數WinMain
; 分析程序時,直接跳到 401000 即可
0040124E mov dword ptr [ebp - 60 ], eax
00401251 push eax
00401252 call 004012EC ; 退出程序
……
0040126A ret
< / span>
|
【收集】啟動函數