1.95k likes | 2.14k Views
現代系統核心期末報告. 第四組 995202062 李宜庭 100522016 蔡逸祥 100522041 鍾珍慧 100522056 薛浩哲 100522065 吳季衡 100522069 潘偉誠 100522074 郭凱威 100522080 林依汶 100522083 曾敬忠 100522106 林宜姮 100522110 葉奇鑫 100582015 藍偉綺. 報告章節目錄 (P.137~176) Chapter 3 Windows 行程和緒程. 3.4 Windows 的行程和緒程管理
E N D
現代系統核心期末報告 第四組 995202062 李宜庭 100522016 蔡逸祥 100522041 鍾珍慧 100522056 薛浩哲 100522065 吳季衡 100522069 潘偉誠 100522074 郭凱威 100522080 林依汶 100522083 曾敬忠 100522106 林宜姮 100522110 葉奇鑫 100582015 藍偉綺
報告章節目錄 (P.137~176)Chapter 3Windows行程和緒程 • 3.4Windows的行程和緒程管理 • 3.4.3 行程和緒程的建立過程 • 3.4.4 行程和緒程的結束處理 • 3.4.5 系統初始行程和緒程 • 3.5Windows中的緒程排程 • 3.5.1 緒程優先層級 • 3.5.2 緒程狀態轉移 • 3.5.3 配量管理 • 3.5.4 優先層級排程和環境切換 • 3.6 行程和緒程執行狀態監視工具 • 3.6.1ProcMon使用範例 • 3.6.2ProcMon實作原理 • 3.7 本章總結
報告章節目錄 (P.137~176)Chapter 4Windows記憶體管理 • Chapter 4Windows記憶體管理 • 4.1 記憶體管理概述
3.4Windows的行程和緒程管理 3.4.3 行程和緒程的建立過程 3.4.4 行程和緒程的結束處理 3.4.5 系統初始行程和緒程 • 報告人:李宜庭 • 林宜媗 • 郭凱威
Windows 創建一個process的過程 • 完成這些工作以後,就可以開始參與系統的排程工作了。然而,透過Windows API 函數創建的process也要接受Windows 子系統的管理,系統在建立process過程中,也必須和子系統溝通才行。 • 另外,還必需給process一塊個別的memory space 這是Windows 建立process過程中不可或缺的步骤。 • NtCreateProcess只是簡單的對參數作一些處理的動作,然後把建立process的任務交给NtCreateProcessEx函數
NtCreateProcessEx NTSTATUS NtCreateProcessEx( __out PHANDLE ProcessHandle, __in ACCESS_MASK DesiredAccess, __in_opt POBJECT_ATTRIBUTES ObjectAttributes, __in HANDLE ParentProcess, __in ULONG Flags, __in_opt HANDLE SectionHandle, __in_opt HANDLE DebugPort, __in_opt HANDLE ExceptionPort, __in ULONG JobMemberLevel ); 如果process建立成功,則ProcessHandle就包含了所建立的process的控制代碼。
NtCreateProcessEx NTSTATUS NtCreateProcessEx( __out PHANDLE ProcessHandle, __in ACCESS_MASK DesiredAccess, __in_opt POBJECT_ATTRIBUTES ObjectAttributes, __in HANDLE ParentProcess, __in ULONG Flags, __in_opt HANDLE SectionHandle, __in_opt HANDLE DebugPort, __in_opt HANDLE ExceptionPort, __in ULONG JobMemberLevel ); DesiredAccess 包含了對新Process的存取權限。
NtCreateProcessEx NTSTATUS NtCreateProcessEx( __out PHANDLE ProcessHandle, __in ACCESS_MASK DesiredAccess, __in_opt POBJECT_ATTRIBUTES ObjectAttributes, __in HANDLE ParentProcess, __in ULONG Flags, __in_opt HANDLE SectionHandle, __in_opt HANDLE DebugPort, __in_opt HANDLE ExceptionPort, __in ULONG JobMemberLevel ); ObjectAttributes 是一個可選的指標參數 (可以為NULL), 它指定了行程物件的屬性。
NtCreateProcessEx NTSTATUS NtCreateProcessEx( __out PHANDLE ProcessHandle, __in ACCESS_MASK DesiredAccess, __in_opt POBJECT_ATTRIBUTES ObjectAttributes, __in HANDLE ParentProcess, __in ULONG Flags, __in_opt HANDLE SectionHandle, __in_opt HANDLE DebugPort, __in_opt HANDLE ExceptionPort, __in ULONG JobMemberLevel ); ParentProcess 指向父親process的控制代碼,不可以是NULL,並且呼叫者必須對該行程具有PROCESS_CREATE_PROCESS 的存取權限。
NtCreateProcessEx NTSTATUS NtCreateProcessEx( __out PHANDLE ProcessHandle, __in ACCESS_MASK DesiredAccess, __in_opt POBJECT_ATTRIBUTES ObjectAttributes, __in HANDLE ParentProcess, __in ULONG Flags, __in_opt HANDLE SectionHandle, __in_opt HANDLE DebugPort, __in_opt HANDLE ExceptionPort, __in ULONG JobMemberLevel ); Flags 是建立旗標,PROCESS_CREATE_FLAGS_INHERIT_HANDLES,表示新process的控制代碼表是否要複製父process的控制代碼表
NtCreateProcessEx NTSTATUS NtCreateProcessEx( __out PHANDLE ProcessHandle, __in ACCESS_MASK DesiredAccess, __in_opt POBJECT_ATTRIBUTES ObjectAttributes, __in HANDLE ParentProcess, __in ULONG Flags, __in_opt HANDLE SectionHandle, __in_opt HANDLE DebugPort, __in_opt HANDLE ExceptionPort, __in ULONG JobMemberLevel ); SectionHandle,指向一個記憶體區段物件,代表了該process的映像檔,呼叫者必須對於記憶體區段物件具有SECTION_MAP_EXECUTE 存取權限。
NtCreateProcessEx NTSTATUS NtCreateProcessEx( __out PHANDLE ProcessHandle, __in ACCESS_MASK DesiredAccess, __in_opt POBJECT_ATTRIBUTES ObjectAttributes, __in HANDLE ParentProcess, __in ULONG Flags, __in_opt HANDLE SectionHandle, __in_opt HANDLE DebugPort, __in_opt HANDLE ExceptionPort, __in ULONG JobMemberLevel ); DebugPort,指向一個連接埠物件,如果此控制代碼參數不為NULL,則此port被指定為新process的偵錯埠,否則,新process没有偵錯埠。
NtCreateProcessEx NTSTATUS NtCreateProcessEx( __out PHANDLE ProcessHandle, __in ACCESS_MASK DesiredAccess, __in_opt POBJECT_ATTRIBUTES ObjectAttributes, __in HANDLE ParentProcess, __in ULONG Flags, __in_opt HANDLE SectionHandle, __in_opt HANDLE DebugPort, __in_opt HANDLE ExceptionPort, __in ULONG JobMemberLevel ); ExceptionPort,指向一個連接埠物件,如果此控制代碼參數不為NULL,則此port被指定為新process的例外埠,否則,新process没有例外埠。
NtCreateProcessEx NTSTATUS NtCreateProcessEx( __out PHANDLE ProcessHandle, __in ACCESS_MASK DesiredAccess, __in_opt POBJECT_ATTRIBUTES ObjectAttributes, __in HANDLE ParentProcess, __in ULONG Flags, __in_opt HANDLE SectionHandle, __in_opt HANDLE DebugPort, __in_opt HANDLE ExceptionPort, __in ULONG JobMemberLevel ); JobMemberLevel 指定了要建立的process在一個Job 集中的層級。
PspCreateProcess • 其實,NtCreateProcessEx只是簡單的檢查了ProcessHandle參數代表的控制代碼是否可寫 • 然後把真正的建立工作交給PspCreateProcess • PspCreateProcess是負責windos中建立所有process的函式(包括systemprocess) • 只有三種函式會呼叫到它 • NtCreateProcessEx • PsCreateSystemProcess • PspInitPhase0
if (ARGUMENT_PRESENT (ParentProcess)) 父process控制代碼 1 NULL 非NULL Affinity = Parent->Pcb.Affinity; WorkingSetMinimum= PsMinimumWorkingSet; WorkingSetMaximum= PsMaximumWorkingSet; • Affinity 設置為全域變數 KeActiveProcessors。 透過ObReferenceObjectByHandle獲得父Process物件的EPROCESS 指標,放在Parent 區域變數中,且獲得父process的Affinity設置。 Affinity = KeActiveProcessors;
2 • 呼叫ObCreateObject,建立一個類型型為PsProcessType的核心物件,置於區域變數Process 中,其物件主體為EPROCESS 資料結構。 Status = ObCreateObject (PreviousMode, PsProcessType, ObjectAttributes, PreviousMode, NULL, sizeof (EPROCESS), 0, 0, &Process); 3 • 把process 物件中的所有欄位設為零,然後初始化其中部分成員
if (ARGUMENT_PRESENT (SectionHandle)) 檢查SectionHandle 4 對於系统process,此參數為NULL 若此參數不為NULL( 非系統process) • 此時若父process不為PsInitialSystemProcess,記憶體區段物件繼承自父process的記憶體區段物件,並且不得為NULL。 則利用此控制代碼參數呼叫ObReferenceObjectByHandle獲得記憶體區段物件的指標。 if (Parent != PsInitialSystemProcess) SectionObject = Parent->SectionObject; if (SectionObject == NULL) { Status = STATUS_PROCESS_IS_TERMINATING; gotoexit_and_deref; } Status = ObReferenceObjectByHandle (SectionHandle, SECTION_MAP_EXECUTE, MmSectionObjectType, PreviousMode, &SectionObject, NULL); 新process物件的記憶體區段物件已經完成初始化。
5 • 接下來根據DebugPort参數來初始化新process物件的DebugPort成員。 6 • 根據 ExceptionPort參數來初始化新process物件的 ExceptionPort成員。
if (Parent != NULL) 7 檢查父process NULL 不為NULL • 則建立一個全新的位址空間 讓新process的控制代碼表指向目前process的控制代碼表,並利用空閒thread的位址空間來初始化新process的位址空間。 Process->ObjectTable = CurrentProcess->ObjectTable; Status = STATUS_INSUFFICIENT_RESOURCES;
8 • 然後呼叫 KeInitializeProcess來初始化新process物件的基本優先層級、Affinity、行程分頁表目錄和超空間的分頁框編號。(paging) KeInitializeProcess (&Process->Pcb, NORMAL_BASE_PRIORITY,Affinity, &DirectoryTableBase[0], (BOOLEAN)(Process->DefaultHardErrorProcessing & PROCESS_HARDERROR_ALIGNMENT_BIT)); 9 • 透過 PspInitializeProcessSecurity函式初始化新process的安全屬性,主要是從父process複製一個權杖。 Status = PspInitializeProcessSecurity (Parent, Process); if (!NT_SUCCESS (Status)) { gotoexit_and_deref; }
if (Parent != NULL) 10 檢查父process NULL 不為NULL Process->PriorityClass = Parent->PriorityClass; Status = ObInitProcess ((Flags&PROCESS_CREATE_FLAGS_INHERIT_HANDLES) ? Parent : NULL, Process); • 利用MmInitializeHandBuiltProcess2設置新process的優先層級類别 • copy父process的優先層級類别,並且初始化新process的控制代碼表,若Flags 参數中包含了控制代碼繼承旗標的話,則把父process控制代碼表中凡是有繼承屬性的物件複製到新process控制代碼表中。 Status = MmInitializeHandBuiltProcess2 (Process);
11 • 接下來初始化新process的process位址空間,有三種可能性 • 新process有新的可執行映像記憶體區段物件 • 沒指定映像記憶體區段物件,但指定了父Process,非PsInitialSystemProcess • 沒指定映像記憶體區段物件,但指定了PsInitialSystemProcess作為父行程
12 • 建立process ID,利用ExCreateHandle函式在CID 控制代碼表中建立一個行程 ID 項。 Process->UniqueProcessId = ExCreateHandle (PspCidTable, &CidEntry); 13 • 對這次process建立行為進行”稽核” if (SeDetailedAuditingWithToken (NULL)) { SeAuditProcessCreation (Process); } 14 if (Parent) { Job = Parent->Job; … } • 如果父process屬於一個作業物件裡,把新建的process也加入父process所在的作業中
15 • 對於透過映像記憶體區段物件來建立行程的情形,建立一個PEB。對於process複製的情形,則使用繼承的PEB 16 • 把新process加入到全域的行程串列PsActiveProcessHead中。 InsertTailList (&PsActiveProcessHead, &Process->ActiveProcessLinks); 17 • 呼叫ObInsertObject函式,把新process物件插入到目前process的控制代碼表中。
18 • 接下來呼叫PspComputeQuantumAndPriority函式用以重新計算新process的基本優先層級和權重值,並且設置行程的記憶體優先層級。 BasePriority = PspComputeQuantumAndPriority(Process, PsProcessPriorityBackground, &QuantumReset); 19 • 設置process的存取權限(GranteAccess欄位) Process->GrantedAccess = PROCESS_TERMINATE; 20 • 最後,設定process的建立時間。並把新process的控制代碼指定輸出到ProcessHandle中,從而建立者可以獲得到新process的控制代碼。
以上是建立並初始化一個行程物件的過程,經過PspCreateProcess函式以後,以上是建立並初始化一個行程物件的過程,經過PspCreateProcess函式以後, • 新建process中並沒有任何Thread物件,所以其中的程式碼並沒有真正被執行 接下來有請下一位講者
NtCreateThread • 緒程的建立是從NtCreateThread函數開始 • 位於base\ntos\ps\create.c(77~169 行) • NTSTATUS • NtCreateThread( • __out PHANDLE ThreadHandle, • __in ACCESS_MASK DesiredAccess, • __in_opt POBJECT_ATTRIBUTES ObjectAttributes, • __in HANDLE ProcessHandle, • __out PCLIENT_ID ClientId, • __in PCONTEXT ThreadContext, • __in PINITIAL_TEB InitialTeb, • __in BOOLEAN CreateSuspended • );
NtCreateThread • NTSTATUS NtCreateThread(…) • { //… • try { • if (KeGetPreviousMode () != KernelMode) { • ProbeForWriteHandle (ThreadHandle); • if (ARGUMENT_PRESENT (ClientId)) { • ProbeForWriteSmallStructure (ClientId, sizeof (CLIENT_ID), sizeof (ULONG)); • } • if (ARGUMENT_PRESENT (ThreadContext) ) { • ProbeForReadSmallStructure (ThreadContext, sizeof (CONTEXT), CONTEXT_ALIGN); • } else { • return STATUS_INVALID_PARAMETER; • } • ProbeForReadSmallStructure (InitialTeb, sizeof (InitialTeb->OldInitialTeb), • sizeof (ULONG)); • } • //... • }//… • } 1. 對於非kernelmode傳遞過來的呼叫, 檢查參數是否可寫
NtCreateThread • NTSTATUS NtCreateThread(…) • { //… • try { • if (KeGetPreviousMode () != KernelMode) { • //… • } • CapturedInitialTeb.OldInitialTeb = InitialTeb->OldInitialTeb; • if (CapturedInitialTeb.OldInitialTeb.OldStackBase == NULL && • CapturedInitialTeb.OldInitialTeb.OldStackLimit == NULL) { • // • // Since the structure size here is less than 64k we don't need to reprobe • // • CapturedInitialTeb = *InitialTeb; • } • } • //… • } 2. 處理InitialTeb參數,將它放到區域變數CapturedInitialTeb中 這些處理工作是在一個try 區塊中完成的, 所以能夠捕捉發生在其中的異常, 保證核心的健壯性
NtCreateThread • NTSTATUS NtCreateThread(…) • { //... • try { • //… • }//… • Status = PspCreateThread (ThreadHandle, • DesiredAccess, • ObjectAttributes, • ProcessHandle, • NULL, • ClientId, • ThreadContext, • &CapturedInitialTeb, • CreateSuspended, • NULL, • NULL); • return Status; • } 3.NtCreateThread 呼叫真正建立緒程的函數PspCreateThread
PspCreateThread ThreadHandle 如果thread建立成功, 會包含了所建立的thread的控制代碼。 NTSTATUS PspCreateThread( OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN HANDLE ProcessHandle, IN PEPROCESS ProcessPointer, OUT PCLIENT_ID ClientId OPTIONAL, IN PCONTEXT ThreadContext OPTIONAL, IN PINITIAL_TEB InitialTeb OPTIONAL, IN BOOLEAN CreateSuspended, IN PKSTART_ROUTINE StartRoutine OPTIONAL, IN PVOID StartContext );
PspCreateThread DesiredAccess 包含對新緒程的存取權限 NTSTATUS PspCreateThread( OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN HANDLE ProcessHandle, IN PEPROCESS ProcessPointer, OUT PCLIENT_ID ClientId OPTIONAL, IN PCONTEXT ThreadContext OPTIONAL, IN PINITIAL_TEB InitialTeb OPTIONAL, IN BOOLEAN CreateSuspended, IN PKSTART_ROUTINE StartRoutine OPTIONAL, IN PVOID StartContext );
PspCreateThread ObjectAttributes 一個optional pointer (可為NULL) , 指定新緒程物件的屬性。 NTSTATUS PspCreateThread( OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN HANDLE ProcessHandle, IN PEPROCESS ProcessPointer, OUT PCLIENT_ID ClientId OPTIONAL, IN PCONTEXT ThreadContext OPTIONAL, IN PINITIAL_TEB InitialTeb OPTIONAL, IN BOOLEAN CreateSuspended, IN PKSTART_ROUTINE StartRoutine OPTIONAL, IN PVOID StartContext );
PspCreateThread ProcessHandle 指向一個行程的控制代碼,新緒程將執行在此行程的環境中。 NTSTATUS PspCreateThread( OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN HANDLE ProcessHandle, IN PEPROCESS ProcessPointer, OUT PCLIENT_ID ClientId OPTIONAL, IN PCONTEXT ThreadContext OPTIONAL, IN PINITIAL_TEB InitialTeb OPTIONAL, IN BOOLEAN CreateSuspended, IN PKSTART_ROUTINE StartRoutine OPTIONAL, IN PVOID StartContext );
PspCreateThread ProcessPointer 指向所屬行程的EPROCESS 物件, 當建立系統緒程時, 此參數指向全域的PsInitialSystemProcess物件, 其他情況下為NULL。 NTSTATUS PspCreateThread( OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN HANDLE ProcessHandle, IN PEPROCESS ProcessPointer, OUT PCLIENT_ID ClientId OPTIONAL, IN PCONTEXT ThreadContext OPTIONAL, IN PINITIAL_TEB InitialTeb OPTIONAL, IN BOOLEAN CreateSuspended, IN PKSTART_ROUTINE StartRoutine OPTIONAL, IN PVOID StartContext );
PspCreateThread ClientId 傳回新緒程的CLIENT_ID結構。 包含Unique process ID和Unique thread ID。 NTSTATUS PspCreateThread( OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN HANDLE ProcessHandle, IN PEPROCESS ProcessPointer, OUT PCLIENT_ID ClientId OPTIONAL, IN PCONTEXT ThreadContext OPTIONAL, IN PINITIAL_TEB InitialTeb OPTIONAL, IN BOOLEAN CreateSuspended, IN PKSTART_ROUTINE StartRoutine OPTIONAL, IN PVOID StartContext );
PspCreateThread ThreadContext 提供新緒程的執行環境。代表使用者模式緒程的初始執行環境。 如果該參數為NULL,則說明此次呼叫將建立一個系統緒程。 NTSTATUS PspCreateThread( OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN HANDLE ProcessHandle, IN PEPROCESS ProcessPointer, OUT PCLIENT_ID ClientId OPTIONAL, IN PCONTEXT ThreadContext OPTIONAL, IN PINITIAL_TEB InitialTeb OPTIONAL, IN BOOLEAN CreateSuspended, IN PKSTART_ROUTINE StartRoutine OPTIONAL, IN PVOID StartContext );
PspCreateThread InitialTeb 提供新緒程的TEB 結構初始值。 NTSTATUS PspCreateThread( OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN HANDLE ProcessHandle, IN PEPROCESS ProcessPointer, OUT PCLIENT_ID ClientId OPTIONAL, IN PCONTEXT ThreadContext OPTIONAL, IN PINITIAL_TEB InitialTeb OPTIONAL, IN BOOLEAN CreateSuspended, IN PKSTART_ROUTINE StartRoutine OPTIONAL, IN PVOID StartContext );
PspCreateThread CreateSuspended 指明新緒程被建立起來後是否被懸置。 若CreateSuspended為TRUE,則新緒程建立完成後並不立即執行,之後必須要透過NtResumeThread函式開始執行。 NTSTATUS PspCreateThread( OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN HANDLE ProcessHandle, IN PEPROCESS ProcessPointer, OUT PCLIENT_ID ClientId OPTIONAL, IN PCONTEXT ThreadContext OPTIONAL, IN PINITIAL_TEB InitialTeb OPTIONAL, IN BOOLEAN CreateSuspended, IN PKSTART_ROUTINE StartRoutine OPTIONAL, IN PVOID StartContext );
PspCreateThread StartRoutine 指定系統緒程啟動函式的位址。 NTSTATUS PspCreateThread( OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN HANDLE ProcessHandle, IN PEPROCESS ProcessPointer, OUT PCLIENT_ID ClientId OPTIONAL, IN PCONTEXT ThreadContext OPTIONAL, IN PINITIAL_TEB InitialTeb OPTIONAL, IN BOOLEAN CreateSuspended, IN PKSTART_ROUTINE StartRoutine OPTIONAL, IN PVOID StartContext );
PspCreateThread StartContext 指定系統緒程啟動函式的執行環境。 NTSTATUS PspCreateThread( OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN HANDLE ProcessHandle, IN PEPROCESS ProcessPointer, OUT PCLIENT_ID ClientId OPTIONAL, IN PCONTEXT ThreadContext OPTIONAL, IN PINITIAL_TEB InitialTeb OPTIONAL, IN BOOLEAN CreateSuspended, IN PKSTART_ROUTINE StartRoutine OPTIONAL, IN PVOID StartContext );
PspCreateThread • PspCreateThread只可能會被以下兩個函式呼叫 • NtCreateThread: 用在建立使用者緒程物件 • PsCreateSystemThread: 用在建立系統緒程物件 • 在PsCreateThread函式的參數中, • ThreadContext和InitialTeb : 針對使用者緒程的建立操作 • StartRoutine和StartContext: 是針對系統緒程的建立操作
PspCreateThread 取得目前緒程物件,以及此次建立操作來自於核心模式還是使用者模式。 根據ProcessHandle獲得相關的行程物件,放到區域變數Process 中 if (ProcessHandle != NULL) { Status = ObReferenceObjectByHandle (ProcessHandle, PROCESS_CREATE_THREAD, PsProcessType, PreviousMode, &Process, NULL); } else { if (StartRoutine != NULL) { ObReferenceObject (ProcessPointer); Process = ProcessPointer; Status = STATUS_SUCCESS; } else { Status = STATUS_INVALID_HANDLE; } } CurrentThread = PsGetCurrentThread (); if (StartRoutine != NULL) { PreviousMode = KernelMode; } else { PreviousMode = KeGetPreviousModeByThread (&CurrentThread->Tcb); }
PspCreateThread 2. 呼叫ObCreateObject 函式建立一個緒程物件ETHREAD,並初始化為零。 Status = ObCreateObject (PreviousMode, PsThreadType, ObjectAttributes, PreviousMode, NULL, sizeof(ETHREAD), 0, 0, &Thread); RtlZeroMemory (Thread, sizeof (ETHREAD));
PspCreateThread 3.初始化一些基本欄位,包括RundownProtect、ThreadsProcess、Cid。 ExInitializeRundownProtection (&Thread->RundownProtect); Thread->ThreadsProcess = Process; Thread->Cid.UniqueProcess = Process->UniqueProcessId; CidEntry.Object = Thread; CidEntry.GrantedAccess = 0; Thread->Cid.UniqueThread = ExCreateHandle (PspCidTable, &CidEntry); 4. 初始化新緒程物件ETHREAD 結構中的一些欄位,包括ReadClusterSize、LpcReplySemaphore、LpcReplyChain、IrpList、PostBlockList 成員,以及緒程鎖成員ThreadLock 和ActiveTimerListLock, 並初始化新緒程的計時器串列ActiveTimerListHead 成員。
PspCreateThread 5. 取得行程的RundownProtect,以避免在建立過程中該行程被取消。 直到該緒程被插入到行程的緒程串列中(透過呼叫KeStartThread 函式) PspCreateThread才release RundownProtect if (!ExAcquireRundownProtection (&Process->RundownProtect)) { ObDereferenceObject (Thread); return STATUS_PROCESS_IS_TERMINATING; }
PspCreateThread 6-1. 如果此次建立的是user-mode thread , 建立TEB,並且用InitialTeb 進行初始化。 利用ThreadContext中的程式指標(Eip)來設置緒程的 StartAddress 。 並且將ThreadContext 中的Eax設置到緒程的Win32StartAddress 。 if (ARGUMENT_PRESENT (ThreadContext)) { Status = MmCreateTeb (Process, InitialTeb, &Thread->Cid, &Teb); //… try { Thread->StartAddress = (PVOID)CONTEXT_TO_PROGRAM_COUNTER(ThreadContext); #if defined(_AMD64_) Thread->Win32StartAddress = (PVOID)ThreadContext->Rdx; #elif defined(_X86_) Thread->Win32StartAddress = (PVOID)ThreadContext->Eax; //… }//… }