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