承接上篇「編譯器選項與 CRT」,本文聚焦 Windows 下進程建立後、主線程啟動、CRT 初始化至 main/WinMain 入口的完整調用鏈。
CreateProcess 成功僅意味著:
進程本身是「惰性」容器,不主動執行代碼。必須建立主線程才能開始指令流。
CreateThread / CreateRemoteThread
↓
ntdll!NtCreateThreadEx (syscall 0x58, sysenter)
↓
內核:建立 ETHREAD、KTHREAD、TEB
↓
設置線程初始 EIP = ntdll!RtlUserThreadStart
NtCreateThreadEx 為非文檔 API,參數原型網上版本不一,微軟不保證穩定性。
Fs:[0])。kernel32!BaseThreadInitThunk。注意:這兩個參數非由用戶代碼壓棧,而是內核在建立線程上下文時硬寫入的。
main,而是 PE 標頭指定的 AddressOfEntryPoint)。VC 編譯的可執行檔,PE 入口點為 mainCRTStartup(或 wmainCRTStartup/WinMainCRTStartup),其職責:
_initterm 執行 _XI_* 區段構造函數)。__getmainargs 填充 argc/argv/envp。main/wmain/WinMain。_onexit/atexit 登記函數。ExitProcess 終止進程。CreateProcess
→ 內核建立進程對象
→ 內核建立主線程 (EIP=RtlUserThreadStart)
→ RtlUserThreadStart (建立 SEH)
→ BaseThreadInitThunk (整理參數)
→ mainCRTStartup (PE 入口點)
→ CRT 初始化 (_initterm)
→ __getmainargs (解析命令行)
→ main() ← 使用者代碼從這裡開始
→ 退出處理 (_onexit)
→ ExitProcess
main 之前 執行(_initterm 階段),異常將導致進程啟動失敗。下一篇將深入 CRT 初始化細節與 __getmainargs 實現。