这些变量的申明保存在WRK的Psinit.c中。先看下PspCreateProcess的参数
PspCreateProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE ParentProcess OPTIONAL, //如果没有指定,表明此进程没有父进程。是系统进程
IN ULONG Flags,
IN HANDLE SectionHandle OPTIONAL,
IN HANDLE DebugPort OPTIONAL,
IN HANDLE ExceptionPort OPTIONAL,
IN ULONG JobMemberLevel
)
③ 一个进程的诞生,CreateProcess的步骤 ----
用户程序可以调用CreateProcess、CreateProcessAsUser、CreateProcessWithTokenWor、CreateProcessWithLogonW创建进程。而进程的创建主要由3部分参合进来完成的:Kernel32.dll、the Windows executive、子系统进程CSRSS.exe。
// 函数PspCreateProcess中创建EPROCESS
// Create the process object
Status = ObCreateObject (PreviousMode, // PreviousMode = KeGetPreviousModeByThread(&CurrentThread->Tcb);
PS: 进程的地址空间分为4种:
1. Boot Process--Address space is initialized during MmInit. Parent is not specified
2. System Process--系统地址空间,看看前面介绍的这个全局变量PspInitialSystemProcess,熟悉了吧
3. User Process (Cloned Address Space) 从指定的进程复制的
4. User Process (New Image Address Space) 新的
------------------------------------------------------
if (SectionHandle != NULL) {
// User Process (New Image Address Space).
Status = MmInitializeProcessAddressSpace (Process,
NULL,
SectionObject,
&Flags,
&(Process->SeAuditProcessCreationInfo.ImageFileName));
...//省略
} else if (Parent != NULL) { //如果存在父进程
if (Parent != PsInitialSystemProcess) { // 如果父进程不是系统进程,说明是一个普通的父进程创建的
Process->SectionBaseAddress = Parent->SectionBaseAddress;
// User Process ( Cloned Address Space )
Status = MmInitializeProcessAddressSpace (Process,
Parent,
NULL,
&Flags,
NULL);
// A cloned process isn't started from an image file, so we give it the name
// of the process of which it is a clone, provided the original has a name.
// 暂时不重要,省略掉
} else {
// System Process
Flags &= ~PROCESS_CREATE_FLAGS_ALL_LARGE_PAGE_FLAGS;
Status = MmInitializeProcessAddressSpace (Process,
NULL,
NULL,
&Flags,
NULL);
}
----- stage2.6 完成进程内核对象的创建-----
1.> Audit the process creation
if (SeDetailedAuditingWithToken (NULL)) {
SeAuditProcessCreation (Process); // Process为当前的EPROCESS
}
2.> See if the parent has a job. If so reference the job and add the process in.
3.> 将EPROCESS插入的系统的active process链表中 [联想的断链和复制链]
PspLockProcessList (CurrentThread);
InsertTailList (&PsActiveProcessHead, &Process->ActiveProcessLinks);
PspUnlockProcessList (CurrentThread);
4.> 线程创建的时间被设定,然后当线程的句柄可用的时候,返回到最初的调用者CreateProcess中[Kernel32.dll]
----- stage4 通知WINDOWS子系统已经创建了一个新进程-----
这时候所有的进程和线程对象都已经继续.Kernel32.dll发送消息到WINDOWS子系统,以便让它设置新的进程和线程.消息如下:
■进程和线程句柄
■Creation Flags的入口
■父进程的ID
■Flag标志,表明此程序是否有窗体,以便CSRSS决定是否创建漏斗状的鼠标,表明有程序在后台运行
■The Csrss thread block is allocated and initialized.[没怎么看明白,CSRSS咋还有新的线程块呢?]
■CreateProcess 在进程的线程表中插入新的线程
■进程的关闭等级设定为 0x280
■The new process block is inserted into the list of Windows subsystemwide processes. The per-process data
structure used by the kernel-mode part of the Windows subsystem (W32PROCESS structure) is allocated and
initialized.[没完全理解]
----- stage6 在进程和线程的context里,完成地址空间的初始化[eg.加载需要的DLL],开始执行程序-----
线程经过漫长的等待后终于开始了它的生命之旅,这要拜KiThreadStartup函数所赐. KiThreadStartup降低IRQL[从DPC到APC],然后调用PspUserThreadStartup函数.它再降低IRQL到PASSIVE.然后...
最后,PspUserThreadStartup queues a user-mode APC to run the image loader initialization routine
(LdrInitializeThunk in Ntdll.dll). The APC will be delivered when the thread attempts to return to user mode.
// Queue the initial APC to the thread
KeRaiseIrql (APC_LEVEL, &OldIrql); KiInitializeUserApc (PspGetBaseExceptionFrame (Thread),
PspGetBaseTrapFrame (Thread),
PspSystemDll.LoaderInitRoutine,
NULL,
PspSystemDll.DllBase,
NULL);
KeLowerIrql (PASSIVE_LEVEL);
当PspUserThreadStartup函数返回到KiThreadStartup中时,APC已经被传送出去了,LdrInitializeThunk也被调用[All threads start with an APC at LdrInitializeThunk,它负责初始化loader,heap manager,NLS表,TLS(线程局部存储)数组,critialsection结构,然后加载任何需要的DLL,并调用DLL中的代码]
This function initializes the system DLL and locates various entrypoints within the DLL.
Arguments:
None.
--*/
{ NTSTATUS st; PSZ dll_entrypoint;
// // If we skipped dll load because we are kernel only then exit now. // if (PsSystemDllDllBase == NULL) { return STATUS_SUCCESS; } // // Locate the important system dll entrypoints //
dll_entrypoint = "LdrInitializeThunk";
st = PspLookupSystemDllEntryPoint (dll_entrypoint, (PVOID) &PspSystemDll.LoaderInitRoutine);
if (!NT_SUCCESS (st)) { #if DBG DbgPrint("PS: Unable to locate LdrInitializeThunk in system dll\n"); #endif KeBugCheckEx (PROCESS1_INITIALIZATION_FAILED, st, 6, 0, 0); }
st = PspLookupKernelUserEntryPoints ();
if ( !NT_SUCCESS (st)) { KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED,st,8,0,0); }