PspCreateThread

NTSTATUS __fastcall PspCreateThread(
        __int64 a1,
        int edx0,
        _OBJECT_ATTRIBUTES *a3,
        VOID *a4,
        _EPROCESS *a5,
        PSP_CREATE_PROCESS_CONTEXT *a6,
        __int64 a7,
        _CONTEXT *a8,
        _PSP_STACK_ALLOCATION_STATE *a9,
        char a10,
        VOID *a11,
        INT64 a12,
        _ETHREAD **a13){
  _ETHREAD *CurrentThread; 
  _EPROCESS *Process; 
  CHAR v16; 
  _EPROCESS *v17; 
  NTSTATUS Thread; 
  NTSTATUS result; 
  VOID *v20; 
  char v21; 
  INT64 v22; 
  PSP_CREATE_PROCESS_CONTEXT *v23; 
  int inserted; 
  _EX_RUNDOWN_REF *p_RundownProtect; 
  int v26; 
  unsigned int Flags3; 
  UINT64 Tag; 
  UINT64 Taga; 
  INT64 PreviousMode; 
  _CONTEXT *ThreadContext; 
  UINT64 v32; 
  VOID *StartRoutine; 
  PSP_CREATE_THREAD_FLAGS CreateFlags[2]; 
  PVOID Object; 
  PSP_CREATE_PROCESS_CONTEXT *CreateContext; 
  INT64 a2; 
  _ETHREAD **NewThread; 
  _PSP_STACK_ALLOCATION_STATE *v39; 
  _OBJECT_ATTRIBUTES *ObjectAttributes; 
  __int64 v41; 
  __int64 v42; 
  _PSP_USER_BASES UserBases[2]; 
  __int128 v44; 
  PSP_STACK_ALLOCATION_STATE StackAllocationState[100]; 

  HIDWORD(PreviousMode) = 0;
  CreateContext = a6;
  v41 = a7;
  v39 = a9;
  StartRoutine = a11;
  a2 = a12;
  ObjectAttributes = a3;
  LODWORD(v32) = edx0;
  v42 = a1;
  NewThread = a13;
  ThreadContext = a8;
  memset(StackAllocationState, 0i64, sizeof(StackAllocationState));
  v44 = 0i64;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  Process = CurrentThread->Tcb.ApcState.Process;
  if( a8 )
    v16 = CurrentThread->Tcb.PreviousMode;
  else
    v16 = 0;
  *(_QWORD *)CreateFlags = 0i64;
  v17 = 0i64;
  LOBYTE(PreviousMode) = v16;
  Thread = -1073741816;
  Object = 0i64;
  if( a4 )
  {
    LODWORD(Tag) = 1917023056;
    result = ObpReferenceObjectByHandleWithTag(a4, 2ui64, (_OBJECT_TYPE *)PsProcessType, v16, Tag, &Object, 0i64, 0i64);
    v17 = (_EPROCESS *)Object;
    goto LABEL_5;
  }
  if( ThreadContext )
  {
    result = -1073741816;
LABEL_5:
    if( result < 0 )
      return result;
    goto LABEL_6;
  }
  ObfReferenceObjectWithTag(a5, 0x72437350ui64);
  v17 = a5;
LABEL_6:
  if( v17 != Process && !PspIsProcessReadyForRemoteThread((INT64)v17) )
    return -1073741823;
  v20 = StartRoutine;
  if( StartRoutine && ThreadContext )
  {
    v20 = (VOID *)((unsigned __int64)StartRoutine & -(__int64)((*(_BYTE *)&v17->Pcb.SecureState & 1) != 0));
    StartRoutine = v20;
  }
  if( !CreateContext
    && !v20
    && ((v17->MitigationFlags & 1) != 0
     || (Process->MitigationFlags & 1) != 0
     || (v17->MitigationFlags2 & 0x4000) != 0
     || (Process->MitigationFlags2 & 0x4000) != 0) )
  {
    return -1073741790;
  }
  v21 = PreviousMode;
  if( (_BYTE)PreviousMode )
  {
    Flags3 = v17->Flags3;
    if( (Flags3 & 0x1000) != 0 || (Flags3 & 1) != 0 )
    {
LABEL_31:
      ObfDereferenceObjectWithTag(v17, 0x72437350ui64);
      return Thread;
    }
  }
  if( (v17->Flags3 & 1) != 0 && !v17->PicoContext && ThreadContext )
  {
    Thread = -1073741790;
    goto LABEL_31;
  }
  PspMapThreadCreationFlags(a10, (int *)&PreviousMode + 1);
  --CurrentThread->Tcb.KernelApcDisable;
  if( !ExAcquireRundownProtection(&v17->RundownProtect) )
  {
    KeLeaveCriticalRegionThread(&CurrentThread->Tcb);
    Thread = -1073741558;
    goto LABEL_31;
  }
  ObfReferenceObjectWithTag(v17, 0x72437350ui64);
  LOBYTE(v22) = v21;
  v23 = CreateContext;
  *(_QWORD *)UserBases = v39;
  Thread = PspAllocateThread(
             v17,
             ObjectAttributes,
             v22,
             CreateContext,
             ThreadContext,
             UserBases,
             StartRoutine,
             (VOID *)a2,
             (char *)&PreviousMode + 4,
             CreateFlags,
             NewThread,
             StackAllocationState,
             (PSP_OBJECT_CREATION_STATE *)PreviousMode);
  if( Thread < 0 )
  {
    ExReleaseRundownProtection(&v17->RundownProtect);
    KeLeaveCriticalRegionThread(&CurrentThread->Tcb);
    goto LABEL_31;
  }
  ObfDereferenceObjectWithTag(v17, 0x72437350ui64);
  LODWORD(Taga) = v32;
  inserted = PspInsertThread(
               *(_ETHREAD **)CreateFlags,
               v17,
               v39,
               (_DWORD *)&PreviousMode + 1,
               Taga,
               (__int64)NewThread,
               v23,
               a2,
               (_ACCESS_STATE *)StackAllocationState,
               v42,
               v41);
  p_RundownProtect = &v17->RundownProtect;
  v26 = inserted;
  ExReleaseRundownProtection(p_RundownProtect);
  KeLeaveCriticalRegionThread(&CurrentThread->Tcb);
  HalPutDmaAdapter(*(PADAPTER_OBJECT *)CreateFlags);
  return v26;
}

Referenced by:

NtCreateThread
NtCreateThreadEx
PsCreateSystemThreadEx