如圖,建立一個程序主要分為兩部分,使用者態部分和核心部分。
既然我們想看看一個程序是怎麼被建立的,那我們就用 WinDbg 來看看從使用者態到核心態都呼叫了什麼:
第一步:我們先看看 nt 下有哪些方法跟建立程序相關的
0: kd> x nt!*CreateProcess*
fffff802`55d8a218 nt!PspSetCreateProcessNotifyRoutine (void)
fffff802`55cd9714 nt!ExpWnfCreateProcessContext (void)
fffff802`55dd9a2f nt!PspCreateProcess$filt$0 (void)
fffff802`55be24f4 nt!PspDeleteCreateProcessContext (void)
fffff802`55c40ed0 nt!MmCreateProcessAddressSpace (void)
fffff802`55dbd430 nt!PspCreateProcess (void)
fffff802`5594fb10 nt!ViCreateProcessCallback (void)
fffff802`55fdaaa4 nt!ViCreateProcessCallbackInternal (ViCreateProcessCallbackInternal)
fffff802`55f04550 nt!NtCreateProcessEx (NtCreateProcessEx)
fffff802`55fd1ce0 nt!VerifierPsSetCreateProcessNotifyRoutineEx (VerifierPsSetCreateProcessNotifyRoutineEx)
fffff802`559f4bf0 nt!ZwCreateProcessEx (ZwCreateProcessEx)
fffff802`56349360 nt!pXdvPsSetCreateProcessNotifyRoutineEx = <no type information>
fffff802`55cfd12c nt!PspValidateCreateProcessProtection (PspValidateCreateProcessProtection)
fffff802`55d89ea0 nt!PsSetCreateProcessNotifyRoutineEx (PsSetCreateProcessNotifyRoutineEx)
fffff802`5632e9d4 nt!PspCreateProcessNotifyRoutineCount = <no type information>
fffff802`55d89f00 nt!PsSetCreateProcessNotifyRoutineEx2 (PsSetCreateProcessNotifyRoutineEx2)
fffff802`5632e9d8 nt!PspCreateProcessNotifyRoutineExCount = <no type information>
fffff802`55d8a050 nt!PsSetCreateProcessNotifyRoutine (PsSetCreateProcessNotifyRoutine)
fffff802`55ed2e70 nt!MiCreateProcessDefaultAweInfo (MiCreateProcessDefaultAweInfo)
fffff802`55be0d1c nt!PspBuildCreateProcessContext (PspBuildCreateProcessContext)
fffff802`559f5970 nt!ZwCreateProcess (ZwCreateProcess)
fffff802`562ec260 nt!PspCreateProcessNotifyRoutine = <no type information>
fffff802`55fd1cc0 nt!VerifierPsSetCreateProcessNotifyRoutine (VerifierPsSetCreateProcessNotifyRoutine)
fffff802`56349378 nt!pXdvPsSetCreateProcessNotifyRoutine = <no type information>
fffff802`55f044c0 nt!NtCreateProcess (NtCreateProcess)
第二步:我們選擇 nt!MmCreateProcessAddressSpace 打上斷點(不要問我為啥選這個,實在不會選,就直接 bm nt!CreateProcess)
0: kd> bu nt!MmCreateProcessAddressSpace
Breakpoint 2 hit
nt!MmCreateProcessAddressSpace:
fffff802`55c40ed0 488bc4 mov rax,rsp
0: kd> k
# Child-SP RetAddr Call Site
00 ffff928c`4e5a7b48 fffff802`55d08608 nt!MmCreateProcessAddressSpace
01 ffff928c`4e5a7b50 fffff802`55cff75a nt!PspAllocateProcess+0x13ec
02 ffff928c`4e5a82c0 fffff802`55a096b5 nt!NtCreateUserProcess+0xa1a
03 ffff928c`4e5a8a90 00007ff8`cfc2e634 nt!KiSystemServiceCopyEnd+0x25
04 00000000`02aac598 00007ff8`cd818e73 ntdll!NtCreateUserProcess+0x14
05 00000000`02aac5a0 00007ff8`cd8171a6 KERNELBASE!CreateProcessInternalW+0xfe3
06 00000000`02aadb70 00007ff8`ced4cbb4 KERNELBASE!CreateProcessW+0x66
07 00000000`02aadbe0 00007ff8`cb56152d KERNEL32!CreateProcessWStub+0x54
08 00000000`02aadc40 00007ff8`cb4f6722 windows_storage!CInvokeCreateProcessVerb::CallCreateProcess+0x2cd
09 00000000`02aadef0 00007ff8`cb55a75c windows_storage!CInvokeCreateProcessVerb::_PrepareAndCallCreateProcess+0x2d6
0a 00000000`02aadf70 00007ff8`cb55a583 windows_storage!CInvokeCreateProcessVerb::_TryCreateProcess+0x3c
0b 00000000`02aadfa0 00007ff8`cb55a46d windows_storage!CInvokeCreateProcessVerb::Launch+0xef
0c 00000000`02aae040 00007ff8`cb599dc4 windows_storage!CInvokeCreateProcessVerb::Execute+0x5d
0d 00000000`02aae080 00007ff8`cb481d87 windows_storage!CBindAndInvokeStaticVerb::InitAndCallExecute+0x214
0e 00000000`02aae100 00007ff8`cb4f5787 windows_storage!CBindAndInvokeStaticVerb::TryCreateProcessDdeHandler+0x63
0f 00000000`02aae180 00007ff8`cb54586d windows_storage!CBindAndInvokeStaticVerb::Execute+0x1e7
10 00000000`02aae4a0 00007ff8`cb545785 windows_storage!RegDataDrivenCommand::_TryInvokeAssociation+0xad
11 00000000`02aae500 00007ff8`ce152b22 windows_storage!RegDataDrivenCommand::_Invoke+0x141
12 00000000`02aae570 00007ff8`ce1529da SHELL32!CRegistryVerbsContextMenu::_Execute+0xce
13 00000000`02aae5e0 00007ff8`ce15630c SHELL32!CRegistryVerbsContextMenu::InvokeCommand+0xaa
14 00000000`02aae8e0 00007ff8`ce15618d SHELL32!HDXA_LetHandlerProcessCommandEx+0x10c
15 00000000`02aae9f0 00007ff8`cb93be08 SHELL32!CDefFolderMenu::InvokeCommand+0x13d
16 00000000`02aaed50 00007ff8`cb93c7b6 windows_storage!CShellLink::_InvokeDirect+0x1d0
17 00000000`02aaf070 00007ff8`cb93945a windows_storage!CShellLink::_ResolveAndInvoke+0x202
18 00000000`02aaf230 00007ff8`ce15630c windows_storage!CShellLink::InvokeCommand+0x1aa
19 00000000`02aaf310 00007ff8`ce15618d SHELL32!HDXA_LetHandlerProcessCommandEx+0x10c
1a 00000000`02aaf420 00007ff8`ce3709d5 SHELL32!CDefFolderMenu::InvokeCommand+0x13d
1b 00000000`02aaf780 00007ff8`ce6244f9 SHELL32!SHInvokeCommandOnContextMenu2+0x1f5
1c 00000000`02aaf9c0 00007ff8`ceeec3f9 SHELL32!s_DoInvokeVerb+0xc9
1d 00000000`02aafa30 00007ff8`ced47034 shcore!_WrapperThreadProc+0xe9
1e 00000000`02aafb10 00007ff8`cfbe2651 KERNEL32!BaseThreadInitThunk+0x14
1f 00000000`02aafb40 00000000`00000000 ntdll!RtlUserThreadStart+0x21
如上 Windbg 輸出的結果所示,正是描述了從使用者態的 CreateProcess → 核心態的 NtCreateUserProcess. 其他鏈路,比如 CreateProcessAsTokenW 我們也可以驗證下,這裡就不做贅述。
使用者態部分,包含一些我們常用到的方法:CreateProcess, CreateProcessAsUser, CreateProcessWithLogonW, CreateProcessAsTokenW.
而核心部分,則都是通過 NT 下的 NtCreateUserProcess 來進行建立。