以下是根據 Windows Internals 重畫的圖,Process Creation 流程上可以分成 7 個 Stage:
Process Creation 的實作主要會是在 ntoskrnl.exe 的 NtCreateUserProcess 中實現。
以下是 NtCreateUserProcess 的 prototype:
NTSTATUS
NTAPI
NtCreateUserProcess(
_Out_ PHANDLE ProcessHandle,
_Out_ PHANDLE ThreadHandle,
_In_ ACCESS_MASK ProcessDesiredAccess,
_In_ ACCESS_MASK ThreadDesiredAccess,
_In_opt_ POBJECT_ATTRIBUTES ProcessObjectAttributes,
_In_opt_ POBJECT_ATTRIBUTES ThreadObjectAttributes,
_In_ ULONG ProcessFlags,
_In_ ULONG ThreadFlags,
_In_ PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
_Inout_ PPS_CREATE_INFO CreateInfo,
_In_ PPS_ATTRIBUTE_LIST AttributeList
);
基本上就是將 process 和 thread 的參數初始化,並且完成在 kernel 中建立 process 需要的操作。
以下非常粗略的介紹各個 Stages:
這個部分會是在 Kernel32.dll 的 CreateProcessInternalW 中處理,之後便會調用 NtCreateUserProcess
NtCreateUserProcess 在這階段會做到以下幾件事:
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
有可執行的 image file
(ref: https://www.microsoftpressstore.com/articles/article.aspx?p=2233328&seqNum=3)
NtCreateUserProcess 在這階段主要透過 PspAllocateProcess 和 PspInsertProcess 完成
PspAllocateProcess:
PspInsertProcess:
NtCreateUserProcess 在這階段主要透過 PspAllocateThread 和 PspInsertThread 完成,然而在 ntoskrnl.exe 版本 10.0.19041.804 中執行順序其實是 PspAllocateProcess ⇒ PspAllocateThread ⇒ PspInsertProcess ⇒ PspInsertThread ,所以有可能是因為版本而產生的差異
PspAllocateThread:
PspInsertThread:
從 NtCreateUserProcess 返回 kernel32.dll 的 CreateProcess 後,將執行與 Windows Subsystem (csrss.exe) 相關的SxS information 操作,像是 manifest 檔案或 DLL redirection 等。
在這個階段,process 已經具備可以執行的環境,除非當初 CreateProcess 有給 CREATE_SUSPENDED 的 flag,否則會直接執行第一條 thread。
新建立的 thread 一開始會執行 KiThreadStartup,KiThreadStartup 會調用 PspUserThreadStartup,而 PspUserThreadStartup 會設置 APC routine ntdll!LdrInitializeThunk,直到返回 user mode 前才觸發 APC routine。(APC 全名為 Alertable Procedure Call,我的理解是這種非同步機制可以讓 kernel 變得更 preemptible)
最終,返回 user mode 後執行 kernel32!BaseThreadStartThunk
PEB 是 process 在 user mode 的結構,在 Windbg 下 dt nt!_PEB
可以看到完整的結構,以下選了幾個重要的 elements:
EPROCESS 是 process 在 kernel mode 的結構,在 Windbg 下 dt nt!_EPROCESS
可以看到完整的結構,以下選了幾個重要的 elements:
dt nt!_KPROCESS
看完整的結構先前提到的 kernel callbacks,簡單來說,就是 Windows 提供了一系列的 callback API,讓 driver 開發者可以註冊這些 callback 在某些 kernel function 中被調用,以下是 kernel 有提供的 callbacks
本篇的內容都相當粗略,像是我完全沒講到 Windows Subsystem (csrss.exe) 的部分,只能先記錄一些大重點方便之後可以快速查找相關內容,想更深入了解內容的讀者可以閱讀 Windows Internals 同時搭配 ntoskrnl.exe 的 decompiled code,這樣會比較好理解 Process Creation。
接下來的五天,我將會每天分享一種關於 Process 的 Defense Evasion 攻擊手法