PspAllocateThread

INT64 __fastcall PspAllocateThread(
        INT64 a1,
        INT64 a2,
        INT8 a3,
        INT64 a4,
        INT32 *rdx0,
        INT64 a6,
        INT64 a7,
        INT64 a8,
        INT64 a9,
        INT64 a10,
        INT64 a11,
        INT64 a12){
  INT8 v13; 
  _QWORD *v16; 
  _ETHREAD *CurrentThread; 
  __int64 v18; 
  __int64 v19; 
  int v20; 
  _QWORD *v21; 
  int Teb; 
  _KNODE *v23; 
  _GROUP_AFFINITY *v24; 
  INT64 v25; 
  int v26; 
  _BYTE *v27; 
  unsigned __int16 v28; 
  PADAPTER_OBJECT v30; 
  __int64 v31; 
  int v32; 
  UINT64 v33; 
  void *Handle; 
  volatile INT64 *v35; 
  __int64 v36; 
  int v37; 
  __int16 v38; 
  __int16 v39; 
  __int16 v40; 
  char *v41; 
  char *v42; 
  __int64 v43; 
  int v44; 
  __int64 v45; 
  INT64 v46; 
  __int64 v47; 
  __int64 v48; 
  __int64 v49; 
  _DMA_OPERATIONS *PoolWithTag; 
  CHAR *ExtendedFeature; 
  __int64 v52; 
  __int64 v53; 
  _OWORD *v54; 
  __int64 v55; 
  int inited; 
  _DMA_OPERATIONS *DmaOperations; 
  __int64 v58; 
  int v59; 
  char v60; 
  __int16 v61; 
  int v62; 
  _QWORD *v63; 
  PADAPTER_OBJECT DmaAdapter; 
  INT64 a4a; 
  CHAR *v66; 
  _QWORD *p_DmaOperations; 
  SIZE_T NumberOfBytes; 
  __int64 v69; 
  __int64 v70; 
  __int64 v71; 
  _ETHREAD *v72; 
  INT64 v73; 
  INT64 v74; 
  INT32 *v75; 
  PVOID Lock; 
  char v77; 
  int v78; 
  __int16 v79; 
  char v80; 
  __int64 v81; 
  __int64 v82; 
  __int64 v83; 
  int v84; 
  int v85; 
  int v86; 
  int v87; 
  INT64 v88; 
  INT64 v89; 
  _QWORD *v90; 
  _KAPC_STATE ApcState; 
  v13 = a3;
  v73 = a1;
  Lock = (PVOID)a2;
  v74 = a4;
  v75 = rdx0;
  v69 = a6;
  v90 = (_QWORD *)a10;
  v66 = (CHAR *)a11;
  v16 = (_QWORD *)a12;
  p_DmaOperations = (_QWORD *)a12;
  memset(&ApcState, 0, sizeof(ApcState));
  a4a = 0i64;
  v70 = 0i64;
  DmaAdapter = 0i64;
  v78 = 0;
  v79 = 0;
  v80 = 0;
  LODWORD(NumberOfBytes) = 0;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  v72 = CurrentThread;
  v62 = 0;
  if( a6 )
    v18 = *(_QWORD *)a6;
  else
    v18 = 0i64;
  v71 = v18;
  v63 = (_QWORD *)v18;
  if( !a4 )
    goto LABEL_22;
  v19 = 0i64;
  v20 = *(_DWORD *)(a4 + 4);
  v21 = (_QWORD *)((a4 + 320) & -(__int64)((v20 & 0x1000) != 0));
  if( (v20 & 0x4000) != 0 )
    v19 = (__int64)*(&KiProcessorBlock + *(unsigned int *)(a4 + 252));
  if( v19 )
  {
    if( v21 )
    {
      if( *(unsigned __int8 *)(v19 + 208) != *(_WORD *)(((a4 + 320) & -(__int64)((*(_DWORD *)(a4 + 4) & 0x1000) != 0))
                                                       + 8)
        || *v21 && (*v21 & *(_QWORD *)(v19 + 200)) == 0i64 )
      {
        Teb = -1073741776;
LABEL_34:
        ObfDereferenceObjectWithTag((PVOID)a1, 0x72437350ui64);
        return(unsigned int)Teb;
      }
    }
    else
    {
      *(_DWORD *)(a4 + 4) = v20 | 0x1000;
      *(_WORD *)(a4 + 328) = *(unsigned __int8 *)(v19 + 208);
      *(_QWORD *)(a4 + 320) = KeActiveProcessors.Bitmap[*(unsigned __int8 *)(v19 + 208)];
    }
    v62 = *(unsigned __int16 *)(*(_QWORD *)(v19 + 192) + 146i64) + 1;
    goto LABEL_18;
  }
  if( v21 && *v21 )
  {
    v23 = KeSelectNodeForAffinity((_GROUP_AFFINITY *)((a4 + 320) & -(__int64)((*(_DWORD *)(a4 + 4) & 0x1000) != 0)));
    v62 = v23->Affinity.Reserved[0] + 1;
    *(_DWORD *)(a4 + 4) = v20 | 0x4000;
    *(_DWORD *)(a4 + 252) = (unsigned __int16)KeSelectIdealProcessor(v23, v24, 0i64);
    v16 = p_DmaOperations;
    CurrentThread = v72;
LABEL_18:
    v13 = a3;
  }
  if( (*(_DWORD *)(a4 + 4) & 0x8000) != 0 && (*(_QWORD *)(a1 + 1408) || a1 != *((_QWORD *)CurrentThread + 68)) )
    goto LABEL_24;
LABEL_22:
  *((_DWORD *)v16 + 96) = 0;
  *((_BYTE *)v16 + 388) = v13;
  if( rdx0 )
  {
    if( (PEPROCESS)a1 == PsInitialSystemProcess )
    {
LABEL_24:
      Teb = -1073741811;
      goto LABEL_34;
    }
    if( a2 )
    {
      if( v13 == 1 && (a2 & 3) != 0 )
        ExRaiseDatatypeMisalignment();
      *((_DWORD *)v16 + 96) = *(_DWORD *)(a2 + 24) & (v13 != 0 ? 7666 : 73714);
    }
  }
  else if( a2 )
  {
    *((_DWORD *)v16 + 96) = *(_DWORD *)(a2 + 24) & 0x11FF2;
  }
  v60 = PoEnergyEstimationEnabled();
  LOBYTE(v25) = -v60;
  v26 = v60 != 0 ? 2400 : 2200;
  KeQueryMaximumGroupCount(v25, v27);
  LODWORD(p_DmaOperations) = 0;
  if( v28 > 1u )
  {
    LODWORD(p_DmaOperations) = (v60 != 0 ? 2407 : 2207) & 0xFFFFFFF8;
    v26 = (_DWORD)p_DmaOperations + 8 * v28;
  }
  Teb = ObCreateObjectEx(a3, PsThreadType, a2, a3, v58, v26, 0, v26, &DmaAdapter, 0i64);
  v59 = Teb;
  if( Teb < 0 )
    goto LABEL_34;
  v30 = DmaAdapter;
  memset((INT64)DmaAdapter, 0i64);
  if( v60 )
  {
    v30[95].DmaOperations = (_DMA_OPERATIONS *)&v30[137].DmaOperations;
    _interlockedbittestandset((volatile signed __int32 *)v30, 0x15u);
    v30 = DmaAdapter;
  }
  if( KiSchedulerAssistThreadFlagEnabled )
  {
    _interlockedbittestandset((volatile signed __int32 *)v30, 0x16u);
    v30 = DmaAdapter;
  }
  v31 = (unsigned int)p_DmaOperations;
  if( (_DWORD)p_DmaOperations )
  {
    *(_DWORD *)&v30[81].Version |= 0x20000u;
    *(_QWORD *)&v30[96].Version = (char *)v30 + v31;
  }
  ExInitializePushLock((EX_RUNDOWN_REF *)&v30[79].DmaOperations);
  p_DmaOperations = &v30[71].DmaOperations;
  v30[71].DmaOperations = *(_DMA_OPERATIONS **)(a1 + 1088);
  v32 = *(_DWORD *)a9;
  if( (*(_DWORD *)a9 & 4) != 0 )
  {
    *(_DWORD *)&v30[81].Version |= 4u;
    v32 = *(_DWORD *)a9;
  }
  if( (v32 & 0x200) != 0 )
    *(_DWORD *)(&v30[7].Size + 1) |= 0x200000u;
  v33 = (UINT64)&v30[80];
  Lock = &v30[80];
  *(_QWORD *)&v30[80].Version = 0i64;
  LODWORD(v30[80].DmaOperations) = 7;
  KeInitializeSemaphore((_KSEMAPHORE *)&v30[72].DmaOperations, 0i64, 1i64);
  *(_QWORD *)&v30[68].Version = (char *)v30 + 1080;
  v30[67].DmaOperations = (_DMA_OPERATIONS *)&v30[67].DmaOperations;
  v30[86].DmaOperations = (_DMA_OPERATIONS *)&v30[86];
  *(_QWORD *)&v30[86].Version = v30 + 86;
  v30[87].DmaOperations = (_DMA_OPERATIONS *)&v30[87];
  *(_QWORD *)&v30[87].Version = v30 + 87;
  *(_QWORD *)&v30[88].Version = 0i64;
  *(_QWORD *)&v30[93].Version = (char *)v30 + 1480;
  v30[92].DmaOperations = (_DMA_OPERATIONS *)&v30[92].DmaOperations;
  v30[93].DmaOperations = 0i64;
  v30[75].DmaOperations = (_DMA_OPERATIONS *)&v30[75];
  *(_QWORD *)&v30[75].Version = v30 + 75;
  v30[88].DmaOperations = 0i64;
  *(_QWORD *)&v30[70].Version = 0i64;
  *(_QWORD *)&v30[71].Version = (char *)v30 + 1128;
  v30[70].DmaOperations = (_DMA_OPERATIONS *)&v30[70].DmaOperations;
  v30[96].DmaOperations = (_DMA_OPERATIONS *)-3i64;
  if( KeQuerySystemTimeUnsafe() )
  {
    KeQuerySystemTimePrecise((_LARGE_INTEGER *)&v30[67]);
  }
  else
  {
    v30 = DmaAdapter;
    *(_QWORD *)&DmaAdapter[67].Version = *(_QWORD *)&KUSER_SHARED_DATA.SystemTime.LowPart;
  }
  *(_QWORD *)&v30[99].Version = (char *)v30 + 1576;
  v30[98].DmaOperations = (_DMA_OPERATIONS *)&v30[98].DmaOperations;
  v30[99].DmaOperations = 0i64;
  v30[100].DmaOperations = (_DMA_OPERATIONS *)&v30[100];
  *(_QWORD *)&v30[100].Version = v30 + 100;
  ExAcquirePushLockExclusiveEx(v33, 0i64);
  Handle = ExCreateHandleEx((__int64)PspCidTable, (__int64)v30, 0, 0, 0i64);
  *(_QWORD *)&v30[72].Version = Handle;
  if( !Handle )
  {
    v35 = (volatile INT64 *)Lock;
    if( (_InterlockedExchangeAdd64((volatile signed __int64 *)Lock, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
      ExfTryToWakePushLock(v35);
    KeAbPostRelease((PVOID)v35);
    Teb = -1073741670;
    v59 = -1073741670;
    v30 = DmaAdapter;
    goto LABEL_121;
  }
  if( rdx0 )
  {
    v37 = *(_DWORD *)a9;
    v38 = (16 * (*(_DWORD *)a9 & 0x40)) | 8;
    if( (*(_DWORD *)a9 & 2) == 0 )
      v38 = 16 * (v37 & 0x40);
    v39 = v38 | 0x2000;
    if( (v37 & 0x80u) == 0 )
      v39 = v38;
    v40 = v39 | 0x4000;
    if( (v37 & 0x100) == 0 )
      v40 = v39;
    v61 = v40;
    v41 = v66;
    if( !v66 )
    {
      if( !*(_QWORD *)(a1 + 2240) )
      {
        v46 = *((_QWORD *)v72 + 30);
        a4a = v46;
        *(_QWORD *)&v30[69].Version = PsQueryThreadStartAddress((__int64)v72, 1);
        *(_QWORD *)&v30[77].Version = *((_QWORD *)v72 + 154);
        *(_DWORD *)(&v30[81].Size + 1) |= 0x10u;
        if( (*(_DWORD *)(a1 + 2516) & 0x4000) != 0
          && (rdx0[12] & 0x100040) == 1048640
          && (*(INT32 *)((char *)rdx0 + rdx0[312] + 1232) & 0x800i64) != 0 )
        {
          ExtendedFeature = RtlLocateExtendedFeature(rdx0 + 308, 0xBui64, 0i64);
          if( ExtendedFeature )
          {
            if( (*ExtendedFeature & 1) != 0 && *((_QWORD *)ExtendedFeature + 1) )
              *(_DWORD *)(&v30[7].Size + 1) |= 0x100000u;
          }
        }
        v52 = *(_QWORD *)(a1 + 1408);
        if( v52 )
        {
          v53 = 14392i64;
          if( *(_WORD *)(v52 + 8) != 0x8664 )
            v53 = 12288i64;
          v69 = v53;
        }
        else
        {
          v69 = 6200i64;
        }
        KiStackAttachProcess((_KPROCESS *)a1, 0i64, &ApcState);
        if( MmSecureVirtualMemoryEx(v46, v69, 4, 0) )
        {
          v54 = p_DmaOperations;
          *(_OWORD *)(v46 + 64) = *(_OWORD *)p_DmaOperations;
          *(_OWORD *)(v46 + 2008) = *v54;
          *(_DWORD *)(v46 + 6044) = 0;
          *(_DWORD *)(v46 + 6120) = 0;
          *(_WORD *)(v46 + 6126) &= 0x62Cu;
          *(_WORD *)(v46 + 6126) |= v61 | 0x40;
          v55 = *(_QWORD *)(a1 + 1408);
          if( v55 )
          {
            if( *(_WORD *)(v55 + 8) == 0x8664 )
            {
              v88 = v46 + 0x2000;
              *(_QWORD *)(v46 + 8256) = *(_QWORD *)v54;
              *(_QWORD *)(v46 + 8264) = *(_QWORD *)&v30[72].Version;
              *(_QWORD *)(v46 + 10200) = *(_QWORD *)v54;
              *(_QWORD *)(v46 + 10208) = *(_QWORD *)&v30[72].Version;
              *(_DWORD *)(v46 + 14236) = 0;
              *(_DWORD *)(v46 + 14312) = 0;
              *(_WORD *)(v46 + 14318) &= 0x62Cu;
              *(_WORD *)(v46 + 14318) |= v61 | 0x40;
            }
            else
            {
              v89 = v46 + 0x2000;
              v84 = *(_DWORD *)v54;
              *(_DWORD *)(v46 + 8224) = v84;
              v85 = *(_DWORD *)&v30[72].Version;
              *(_DWORD *)(v46 + 8228) = v85;
              v86 = *(_DWORD *)v54;
              *(_DWORD *)(v46 + 9908) = v86;
              v87 = *(_DWORD *)&v30[72].Version;
              *(_DWORD *)(v46 + 9912) = v87;
              *(_DWORD *)(v46 + 12188) = 0;
              *(_DWORD *)(v46 + 12228) = 0;
              *(_WORD *)(v46 + 12234) &= 0x62Cu;
              *(_WORD *)(v46 + 12234) |= v61 | 0x40;
            }
          }
        }
        else
        {
          Teb = -1073741503;
          v59 = -1073741503;
        }
LABEL_110:
        KiUnstackDetachProcess(&ApcState, 0i64);
        if( Teb < 0 )
          goto LABEL_121;
        goto LABEL_111;
      }
      v48 = *((_QWORD *)rdx0 + 31);
      *(_QWORD *)&v30[69].Version = v48;
      *(_QWORD *)&v30[77].Version = v48;
      v49 = v69;
      v30[94].DmaOperations = *(_DMA_OPERATIONS **)(v69 + 8);
      *(_QWORD *)&v30[95].Version = *(_QWORD *)(v49 + 16);
      _interlockedbittestandset((volatile signed __int32 *)v30, 0x1Au);
      RtlGetExtendedContextLength(KUSER_SHARED_DATA.XState.EnabledFeatures != 0 ? 1048671 : 1048607, &NumberOfBytes);
      PoolWithTag = (_DMA_OPERATIONS *)ExAllocatePoolWithTag(PagedPool, (unsigned int)NumberOfBytes, 0x63537350ui64);
      v30 = DmaAdapter;
      DmaAdapter[97].DmaOperations = PoolWithTag;
      if( !PoolWithTag )
      {
        Teb = -1073741670;
        v59 = -1073741670;
        goto LABEL_121;
      }
      v46 = a4a;
LABEL_111:
      inited = KeInitThread(v30, 0i64, PspUserThreadStartup);
      goto LABEL_113;
    }
    if( (*(_DWORD *)(a1 + 2516) & 0x4000) != 0 && (!a4 || (*(_DWORD *)(a4 + 4) & 0x8000) == 0) )
      *(_DWORD *)(&v30[7].Size + 1) |= 0x100000u;
    if( *(_QWORD *)(a1 + 1408) )
    {
      v77 = 0;
      v82 = 0x8000i64;
      v83 = 0x40000i64;
      v81 = 0i64;
      Teb = PspSetupUserStack(a1, (__int64)rdx0, (__int64)v63, &v77, v62);
      v59 = Teb;
      if( Teb >= 0 )
      {
        v42 = v66;
        *v66 ^= (v77 ^ *v66) & 2;
        v43 = (__int64)v63;
        v44 = PspWow64SetupUserStack(a1, v36, (__int64)v63, v42, v62);
LABEL_68:
        Teb = v44;
        v59 = v44;
LABEL_73:
        if( Teb < 0 )
          goto LABEL_121;
        v45 = v70;
        if( a4 && (*(_DWORD *)(a4 + 4) & 0x8000) != 0 && (KeFeatureBits & 0x10000000) == 0 )
          v45 = 0x100000000i64;
        Teb = MmCreateTeb(a1, v43, p_DmaOperations, v45, (__int64)&a4a);
        v59 = Teb;
        if( Teb < 0 )
          goto LABEL_121;
        *(_QWORD *)&v30[69].Version = *((_QWORD *)rdx0 + 31);
        *(_QWORD *)&v30[77].Version = *((_QWORD *)rdx0 + 16);
        v46 = a4a;
        if( *(_QWORD *)(a1 + 1408) )
        {
          Teb = PspWow64InitThread((PVOID)a1);
          v59 = Teb;
          if( Teb < 0 )
            goto LABEL_121;
        }
        if( v61 )
        {
          KiStackAttachProcess((_KPROCESS *)a1, 0i64, &ApcState);
          *(_WORD *)(v46 + 6126) = v61;
          v47 = *(_QWORD *)(a1 + 1408);
          if( v47 )
          {
            if( *(_WORD *)(v47 + 8) == 0x8664 )
            {
              v88 = v46 + 0x2000;
              *(_WORD *)(v46 + 14318) = v61;
            }
            else
            {
              v89 = v46 + 0x2000;
              *(_WORD *)(v46 + 12234) = v61;
            }
          }
          Teb = 0;
          v59 = 0;
          goto LABEL_110;
        }
        goto LABEL_111;
      }
    }
    else
    {
      Teb = PspSetupUserStack(a1, (__int64)rdx0, (__int64)v63, v41, v62);
      v59 = Teb;
      if( Teb >= 0 && (*(_DWORD *)(&v30[7].Size + 1) & 0x100000) != 0 )
      {
        v43 = (__int64)v63;
        v44 = PspSetupUserShadowStack(a1, rdx0, (__int64)v63, v66, v62);
        goto LABEL_68;
      }
    }
    v43 = (__int64)v63;
    goto LABEL_73;
  }
  *(_QWORD *)&v30[69].Version = a7;
  *(_QWORD *)&v30[77].Version = a7;
  inited = KeInitThread(v30, 0i64, PspSystemThreadStartup);
  v46 = a4a;
LABEL_113:
  v59 = inited;
  Teb = inited;
  if( inited < 0 )
  {
    if( !v46 || !v66 )
      goto LABEL_121;
    goto LABEL_120;
  }
  if( a4 )
  {
    if( (*(_DWORD *)(a4 + 4) & 0x8000) != 0 )
    {
      Teb = PspUmsInitThread((INT64)v30, a3, a4, v46);
      v59 = Teb;
      if( Teb < 0 )
      {
LABEL_120:
        MmDeleteTeb(a1, v46);
LABEL_121:
        if( v66 && *v66 )
          PspDeleteUserStack((_EPROCESS *)a1, v36, v63, v66);
        DmaOperations = v30[97].DmaOperations;
        if( DmaOperations )
        {
          ExFreePoolWithTag(DmaOperations, 0x63537350u);
          v30[97].DmaOperations = 0i64;
        }
        if( *(_QWORD *)&v30[72].Version )
        {
          if( (_InterlockedExchangeAdd64((volatile signed __int64 *)&v30[80], 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
            ExfTryToWakePushLock((volatile INT64 *)&v30[80]);
          KeAbPostRelease(&v30[80]);
          Teb = v59;
          v30 = DmaAdapter;
        }
        if( !*(_QWORD *)&v30[34].Version )
          ObfDereferenceObjectWithTag((PVOID)a1, 0x72437350ui64);
        HalPutDmaAdapter(v30);
        return(unsigned int)Teb;
      }
    }
  }
  *v90 = v30;
  return 0i64;
}

Referenced by:

NtCreateUserProcess
PspCreatePicoThread
PspCreateThread