类似于进程的创建过程:进程创建过程分析NtCreateProcess-NtCreateProcessEx-PspCreateProcess。
线程的创建是从NtCreateThread函数开始的。NtCreateThread所做的事很简单,首先,对于非内核模式传递过来的调用,检查参数是否可写。处理InitialTeb参数,将它放到局部变量CapturedInitialTeb中。这些操作都是在try块中完成的。然后调用真正创建线程的函数PspCreateThread。
NTSTATUS
NtCreateThread(
    __out PHANDLE ThreadHandle,
    __in ACCESS_MASK DesiredAccess,
    __in_opt POBJECT_ATTRIBUTES ObjectAttributes,
    __in HANDLE ProcessHandle,
    __out Pcreateprocess-analyseCLIENT_ID ClientId,
    __in PCONTEXT ThreadContext,
    __in PINITIAL_TEB InitialTeb,
    __in BOOLEAN CreateSuspended
    )
{
    NTSTATUS Status;
    INITIAL_TEB CapturedInitialTeb;
PAGED_CODE();
    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));
        }
        CapturedInitialTeb.OldInitialTeb = InitialTeb->OldInitialTeb;
        if (CapturedInitialTeb.OldInitialTeb.OldStackBase == NULL &&
            CapturedInitialTeb.OldInitialTeb.OldStackLimit == NULL) {
            CapturedInitialTeb = *InitialTeb;
        }
    } except (ExSystemExceptionFilter ()) {
        return GetExceptionCode ();
    }
    Status = PspCreateThread (ThreadHandle,
                              DesiredAccess,
                              ObjectAttributes,
                              ProcessHandle,
                              NULL,
                              ClientId,
                              ThreadContext,
                              &CapturedInitialTeb,
                              CreateSuspended,
                              NULL,
                              NULL);
    return Status;
}
下面进入PspCreateThread的流程分析。
1.得到当前线程,判断模式,得到进程对象。
CurrentThread = PsGetCurrentThread ();
   if (StartRoutine != NULL) {
       PreviousMode = KernelMode;
   } else {
       PreviousMode = KeGetPreviousModeByThread (&CurrentThread->Tcb);
   }
Teb = NULL;
   Thread = NULL;
   Process = NULL;
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;
       }
   }
   if (!NT_SUCCESS (Status)) {
       return Status;
   }
   if ((PreviousMode != KernelMode) && (Process == PsInitialSystemProcess)) {
       ObDereferenceObject (Process);
       return STATUS_INVALID_HANDLE;
   }
2.调用ObCreateObject创建一个线程对象ETHREAD,并清零。
Status = ObCreateObject (PreviousMode,
                            PsThreadType,
                            ObjectAttributes,
                            PreviousMode,
                            NULL,
                            sizeof(ETHREAD),
                            0,
                            0,
                            &Thread);
   if (!NT_SUCCESS (Status)) {
       ObDereferenceObject (Process);
       return Status;
   }
RtlZeroMemory (Thread, sizeof (ETHREAD));
3.初始化基本域。
//初始化rundown
ExInitializeRundownProtection (&Thread->RundownProtect);
  Thread->ThreadsProcess = Process;
Thread->Cid.UniqueProcess = Process->UniqueProcessId;
  CidEntry.Object = Thread;
  CidEntry.GrantedAccess = 0;
//从CID句柄表中创建一个句柄表项
  Thread->Cid.UniqueThread = ExCreateHandle (PspCidTable, &CidEntry);
  if (Thread->Cid.UniqueThread == NULL) {
      ObDereferenceObject (Thread);
      return (STATUS_INSUFFICIENT_RESOURCES);
  }
Thread->ReadClusterSize = MmReadClusterSize;
  KeInitializeSemaphore (&Thread->LpcReplySemaphore, 0L, 1L);
  InitializeListHead (&Thread->LpcReplyChain);
InitializeListHead (&Thread->IrpList);
InitializeListHead (&Thread->PostBlockList);
PspInitializeThreadLock (Thread);
  KeInitializeSpinLock (&Thread->ActiveTimerListLock);
  InitializeListHead (&Thread->ActiveTimerListHead);
4.获得RundownProtect锁,以避免在创建过程中该进程被停掉(rundown),直到该线程被插入到进程的线程链表中,锁才被释放。
if (!ExAcquireRundownProtection (&Process->RundownProtect)) {
      ObDereferenceObject (Thread);
      return STATUS_PROCESS_IS_TERMINATING;
  }
5.判断是不是用户模式线程,并进行各种初始化。
if (ARGUMENT_PRESENT (ThreadContext)) {
//不为null,创建的是用户模式线程,创建TEB,并初始化
        Status = MmCreateTeb (Process, InitialTeb, &Thread->Cid, &Teb);
        if (!NT_SUCCESS (Status)) {
            ExReleaseRundownProtection (&Process->RundownProtect);
            ObDereferenceObject (Thread);
            return Status;
        }
try {
//利用ThreadContext中的程序指针(Eip寄存器)来设置线程的启动地址
            Thread->StartAddress = (PVOID)CONTEXT_TO_PROGRAM_COUNTER(ThreadContext);
#if defined(_AMD64_)
Thread->Win32StartAddress = (PVOID)ThreadContext->Rdx;
#elif defined(_X86_)
//将ThreadContext中的Eax寄存器设置到线程的Win32StartAddress
Thread->Win32StartAddress = (PVOID)ThreadContext->Eax;
#else
#error “no target architecture”
#endif
} except (EXCEPTION_EXECUTE_HANDLER) {
            Status = GetExceptionCode();
        }
if (NT_SUCCESS (Status)) {
//初始化一些线程属性
            Status = KeInitThread (&Thread->Tcb,
                                   NULL,
                                   PspUserThreadStartup,
                                   (PKSTART_ROUTINE)NULL,
                                   Thread->StartAddress,
                                   ThreadContext,
                                   Teb,
                                   &Process->Pcb);
       }
} else {
//系统线程
Teb = NULL;
//设置系统线程位
        PS_SET_BITS (&Thread->CrossThreadFlags, PS_CROSS_THREAD_FLAGS_SYSTEM);
        Thread->StartAddress = (PKSTART_ROUTINE) StartRoutine;
        Status = KeInitThread (&Thread->Tcb,
                               NULL,
                               PspSystemThreadStartup,
                               StartRoutine,
                               StartContext,
                               NULL,
                               NULL,
                               &Process->Pcb);
    }
    if (!NT_SUCCESS (Status)) {
        if (Teb != NULL) {
            MmDeleteTeb(Process, Teb);
        }
        ExReleaseRundownProtection (&Process->RundownProtect);
        ObDereferenceObject (Thread);
        return Status;
    }
6.锁住线程,确保此进程不是在退出或终止过程中。
PspLockProcessExclusive (Process, CurrentThread);
//进程正在结束
if ((Process->Flags&PS_PROCESS_FLAGS_PROCESS_DELETE) != 0 ||
       (((CurrentThread->CrossThreadFlags&PS_CROSS_THREAD_FLAGS_TERMINATED) != 0) &&
       (ThreadContext != NULL) &&
       (THREAD_TO_PROCESS(CurrentThread) == Process))) {
PspUnlockProcessExclusive (Process, CurrentThread);
KeUninitThread (&Thread->Tcb);
       if (Teb != NULL) {
           MmDeleteTeb(Process, Teb);
       }
       ExReleaseRundownProtection (&Process->RundownProtect);
       ObDereferenceObject(Thread);
       return STATUS_PROCESS_IS_TERMINATING;
   }
7.进程的活动线程+1,加入线程链表。
OldActiveThreads = Process->ActiveThreads++;
   InsertTailList (&Process->ThreadListHead, &Thread->ThreadListEntry);
KeStartThread (&Thread->Tcb);
PspUnlockProcessExclusive (Process, CurrentThread);
ExReleaseRundownProtection (&Process->RundownProtect);
8.若是进程的第一个线程,则触发该进程的创建通知。
if (OldActiveThreads == 0) {
        PERFINFO_PROCESS_CREATE (Process);
        if (PspCreateProcessNotifyRoutineCount != 0) {
            ULONG i;
            PEX_CALLBACK_ROUTINE_BLOCK CallBack;
            PCREATE_PROCESS_NOTIFY_ROUTINE Rtn;
            for (i=0; i<PSP_MAX_CREATE_PROCESS_NOTIFY; i++) {
                CallBack = ExReferenceCallBackBlock (&PspCreateProcessNotifyRoutine[i]);
                if (CallBack != NULL) {
                    Rtn = (PCREATE_PROCESS_NOTIFY_ROUTINE) ExGetCallBackBlockRoutine (CallBack);
                    Rtn (Process->InheritedFromUniqueProcessId,
                         Process->UniqueProcessId,
                         TRUE);
                    ExDereferenceCallBackBlock (&PspCreateProcessNotifyRoutine[i],
                                                CallBack);
                }
            }
        }
    }
9.如果新线程的进程在一个作业中,则需要做特定的处理。
Job = Process->Job;
    if (Job != NULL && Job->CompletionPort &&
        !(Process->JobStatus & (PS_JOB_STATUS_NOT_REALLY_ACTIVE|PS_JOB_STATUS_NEW_PROCESS_REPORTED))) {
PS_SET_BITS (&Process->JobStatus, PS_JOB_STATUS_NEW_PROCESS_REPORTED);
        KeEnterCriticalRegionThread (&CurrentThread->Tcb);
        ExAcquireResourceSharedLite (&Job->JobLock, TRUE);
        if (Job->CompletionPort != NULL) {
            IoSetIoCompletion (Job->CompletionPort,
                               Job->CompletionKey,
                               (PVOID)Process->UniqueProcessId,
                               STATUS_SUCCESS,
                               JOB_OBJECT_MSG_NEW_PROCESS,
                               FALSE);
        }
        ExReleaseResourceLite (&Job->JobLock);
        KeLeaveCriticalRegionThread (&CurrentThread->Tcb);
    }
PERFINFO_THREAD_CREATE(Thread, InitialTeb);
10.通知接受线程创建事件的出调例程。
if (PspCreateThreadNotifyRoutineCount != 0) {
        ULONG i;
        PEX_CALLBACK_ROUTINE_BLOCK CallBack;
        PCREATE_THREAD_NOTIFY_ROUTINE Rtn;
        for (i = 0; i < PSP_MAX_CREATE_THREAD_NOTIFY; i++) {
            CallBack = ExReferenceCallBackBlock (&PspCreateThreadNotifyRoutine[i]);
            if (CallBack != NULL) {
                Rtn = (PCREATE_THREAD_NOTIFY_ROUTINE) ExGetCallBackBlockRoutine (CallBack);
                Rtn (Thread->Cid.UniqueProcess,
                     Thread->Cid.UniqueThread,
                     TRUE);
                ExDereferenceCallBackBlock (&PspCreateThreadNotifyRoutine[i],
                                            CallBack);
            }
        }
    }
11.线程对象的引用计数加2,一个针对当前的创建操作,另一个针对要返回的线程句柄。
ObReferenceObjectEx (Thread, 2);
12.如果CreateSuspended指示新线程立即被挂起,则调用KeSuspendThread挂起线程。
if (CreateSuspended) {
        try {
            KeSuspendThread (&Thread->Tcb);
        } except ((GetExceptionCode () == STATUS_SUSPEND_COUNT_EXCEEDED)?
                     EXCEPTION_EXECUTE_HANDLER :
                     EXCEPTION_CONTINUE_SEARCH) {
        }
        if (Thread->CrossThreadFlags&PS_CROSS_THREAD_FLAGS_TERMINATED) {
            KeForceResumeThread (&Thread->Tcb);
        }
    }
13.根据指定的期望访问权限,调用SeCreateAccessStateEx函数创建一个访问状态结构
AccessState = NULL;
    if (!PsUseImpersonationToken) {
        AccessState = &LocalAccessState;
        Status = SeCreateAccessStateEx (NULL,
                                        ARGUMENT_PRESENT (ThreadContext)?PsGetCurrentProcessByThread (CurrentThread) : Process,
                                        AccessState,
                                        &AuxData,
                                        DesiredAccess,
                                        &PsThreadType->TypeInfo.GenericMapping);
        if (!NT_SUCCESS (Status)) {
            PS_SET_BITS (&Thread->CrossThreadFlags,
                         PS_CROSS_THREAD_FLAGS_DEADTHREAD);
            if (CreateSuspended) {
                (VOID) KeResumeThread (&Thread->Tcb);
            }
            KeReadyThread (&Thread->Tcb);
            ObDereferenceObjectEx (Thread, 2);
            return Status;
        }
    }
14.调用ObInsertObject函数把线程对象插入到当前进程的句柄表中。
Status = ObInsertObject (Thread,
                            AccessState,
                            DesiredAccess,
                            0,
                            NULL,
                            &LocalThreadHandle);
   if (AccessState != NULL) {
       SeDeleteAccessState (AccessState);
   }
if (!NT_SUCCESS (Status)) {
//调用失败,终止线程
       PS_SET_BITS (&Thread->CrossThreadFlags,
                    PS_CROSS_THREAD_FLAGS_DEADTHREAD);
       if (CreateSuspended) {
           KeResumeThread (&Thread->Tcb);
       }
} else {
try {
//设置ThreadHandle 、ClientId
           *ThreadHandle = LocalThreadHandle;
           if (ARGUMENT_PRESENT (ClientId)) {
               *ClientId = Thread->Cid;
           }
       } except(EXCEPTION_EXECUTE_HANDLER) {
           PS_SET_BITS (&Thread->CrossThreadFlags,
                        PS_CROSS_THREAD_FLAGS_DEADTHREAD);
           if (CreateSuspended) {
               (VOID) KeResumeThread (&Thread->Tcb);
           }
           KeReadyThread (&Thread->Tcb);
           ObDereferenceObject (Thread);
           ObCloseHandle (LocalThreadHandle, PreviousMode);
           return GetExceptionCode();
       }
   }
15.设置线程的创建时间。
KeQuerySystemTime(&CreateTime);
ASSERT ((CreateTime.HighPart & 0xf0000000) == 0);
    PS_SET_THREAD_CREATE_TIME(Thread, CreateTime);
16.设置线程的访问权限
if ((Thread->CrossThreadFlags&PS_CROSS_THREAD_FLAGS_DEADTHREAD) == 0) {
    Status = ObGetObjectSecurity (Thread,
                                  &SecurityDescriptor,
                                  &MemoryAllocated);
    if (!NT_SUCCESS (Status)) {
        PS_SET_BITS (&Thread->CrossThreadFlags,
                     PS_CROSS_THREAD_FLAGS_DEADTHREAD);
        if (CreateSuspended) {
            KeResumeThread(&Thread->Tcb);
        }
        KeReadyThread (&Thread->Tcb);
        ObDereferenceObject (Thread);
        ObCloseHandle (LocalThreadHandle, PreviousMode);
        return Status;
    }
    SubjectContext.ProcessAuditId = Process;
    SubjectContext.PrimaryToken = PsReferencePrimaryToken(Process);
    SubjectContext.ClientToken = NULL;
    AccessCheck = SeAccessCheck (SecurityDescriptor,
                                 &SubjectContext,
                                 FALSE,
                                 MAXIMUM_ALLOWED,
                                 0,
                                 NULL,
                                 &PsThreadType->TypeInfo.GenericMapping,
                                 PreviousMode,
                                 &Thread->GrantedAccess,
                                 &accesst);
PsDereferencePrimaryTokenEx (Process, SubjectContext.PrimaryToken);
    ObReleaseObjectSecurity (SecurityDescriptor,
                             MemoryAllocated);
    if (!AccessCheck) {
        Thread->GrantedAccess = 0;
    }
Thread->GrantedAccess |= (THREAD_TERMINATE | THREAD_SET_INFORMATION | THREAD_QUERY_INFORMATION);
} else {
    Thread->GrantedAccess = THREAD_ALL_ACCESS;
}
17.调用KeReadyThread,使线程进入“就绪”状态,准备马上执行。或者此时进程未在内存中,则新线程的状态为“转移”,以等待换入内存后再执行。引用计数减1.
KeReadyThread (&Thread->Tcb);
  ObDereferenceObject (Thread);
return Status;
至此线程的创建过程就完成了。