PspAllocateThread
NTSTATUS __stdcall PspAllocateThread(
_EPROCESS *Process,
_OBJECT_ATTRIBUTES *ObjectAttributes,
INT64 PreviousMode,
PSP_CREATE_PROCESS_CONTEXT *CreateContext,
_CONTEXT *ThreadContext,
_PSP_USER_BASES *UserBases,
VOID *StartRoutine,
VOID *a8,
VOID *StartContext,
PSP_CREATE_THREAD_FLAGS *CreateFlags,
_ETHREAD **NewThread,
PSP_STACK_ALLOCATION_STATE *StackAllocationState,
PSP_OBJECT_CREATION_STATE *ThreadAccessState){
char v14;
PSP_STACK_ALLOCATION_STATE *v17;
_ETHREAD *CurrentThread;
__int64 v19;
__int64 v20;
PSP_CREATE_PROCESS_CONTEXT v21;
_QWORD *v22;
NTSTATUS v23;
_KNODE *v24;
_GROUP_AFFINITY *v25;
INT64 v26;
size_t v27;
_BYTE *v28;
unsigned __int16 v29;
UINT64 v30;
UINT64 v31;
char *v33;
__int64 v34;
int v35;
_EX_PUSH_LOCK *v36;
VOID *Handle;
_EX_PUSH_LOCK *v38;
_PS_INITIAL_TEB *v39;
int v40;
__int16 v41;
__int16 v42;
__int16 v43;
PSP_STACK_ALLOCATION_STATE *v44;
_PSP_STACK_ALLOCATION_STATE *v45;
__int64 v46;
NTSTATUS v47;
__int64 v48;
char *v49;
_EWOW64PROCESS *v50;
unsigned __int64 Rip;
__int64 v52;
VOID **PoolWithTag;
char *ExtendedFeature;
_EWOW64PROCESS *WoW64Process;
__int64 v56;
PSP_STACK_ALLOCATION_STATE *v57;
_EWOW64PROCESS *v58;
int inited;
void *v60;
_HANDLE_TABLE_ENTRY_INFO *ExtraInfo;
_HANDLE_TABLE_ENTRY_INFO *ExtraInfoa;
_HANDLE_TABLE_ENTRY_INFO *ExtraInfob;
UINT64 ObjectBodySize;
UINT64 PagedPoolCharge;
UINT64 NonPagedPoolCharge;
int v67;
char v68;
__int16 v69;
int PreferredNode;
PS_INITIAL_TEB *InitialTeb;
VOID *ObjectPointer;
_TEB *Teb;
_PSP_STACK_ALLOCATION_STATE *v74;
PSP_STACK_ALLOCATION_STATE *v75;
UINT64 ContextLength;
__int64 v77;
__int64 v78;
__int64 v79;
_ETHREAD *Thread;
_EPROCESS *v81;
PSP_CREATE_PROCESS_CONTEXT *v82;
_CONTEXT *v83;
_EX_PUSH_LOCK *PushLock;
_PSP_STACK_ALLOCATION_STATE v85;
__int64 v86;
__int64 v87;
PSP_STACK_ALLOCATION_STATE v88;
int v89;
PSP_STACK_ALLOCATION_STATE v90;
int v91;
char *v92;
char *v93;
PSP_CREATE_THREAD_FLAGS *v94;
_KAPC_STATE ApcState;
char ProbeMode;
ProbeMode = PreviousMode;
v14 = PreviousMode;
v81 = Process;
PushLock = (_EX_PUSH_LOCK *)ObjectAttributes;
v82 = CreateContext;
v83 = ThreadContext;
v77 = (__int64)UserBases;
v94 = CreateFlags;
v74 = (_PSP_STACK_ALLOCATION_STATE *)NewThread;
v17 = StackAllocationState;
v75 = StackAllocationState;
memset(&ApcState, 0, sizeof(ApcState));
Teb = 0i64;
v78 = 0i64;
ObjectPointer = 0i64;
*(_DWORD *)(&v85.0 + 1) = 0;
*(_WORD *)((char *)&v85.ZeroBits + 1) = 0;
HIBYTE(v85.ZeroBits) = 0;
LODWORD(ContextLength) = 0;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
Thread = CurrentThread;
PreferredNode = 0;
if( UserBases )
v19 = *(_QWORD *)UserBases;
else
v19 = 0i64;
v79 = v19;
InitialTeb = (PS_INITIAL_TEB *)v19;
if( !CreateContext )
goto LABEL_22;
v20 = 0i64;
v21 = CreateContext[1];
v22 = (_QWORD *)((unsigned __int64)(CreateContext + 80) & -(__int64)((v21 & 0x1000) != 0));
if( (v21 & 0x4000) != 0 )
v20 = (__int64)*(&KiProcessorBlock + (unsigned int)CreateContext[63]);
if( v20 )
{
if( v22 )
{
if( *(unsigned __int8 *)(v20 + 208) != *(_WORD *)(((unsigned __int64)(CreateContext + 80) & -(__int64)((CreateContext[1] & 0x1000) != 0))
+ 8)
|| *v22 && (*v22 & *(_QWORD *)(v20 + 200)) == 0i64 )
{
v23 = -1073741776;
LABEL_34:
ObfDereferenceObjectWithTag(Process, 0x72437350ui64);
return v23;
}
}
else
{
CreateContext[1] = v21 | 0x1000;
*((_WORD *)CreateContext + 164) = *(unsigned __int8 *)(v20 + 208);
*((_QWORD *)CreateContext + 40) = KeActiveProcessors.Bitmap[*(unsigned __int8 *)(v20 + 208)];
}
PreferredNode = *(unsigned __int16 *)(*(_QWORD *)(v20 + 192) + 146i64) + 1;
goto LABEL_18;
}
if( v22 && *v22 )
{
v24 = KeSelectNodeForAffinity((_GROUP_AFFINITY *)((unsigned __int64)(CreateContext + 80) & -(__int64)((CreateContext[1] & 0x1000) != 0)));
PreferredNode = v24->Affinity.Reserved[0] + 1;
CreateContext[1] = v21 | 0x4000;
CreateContext[63] = (unsigned __int16)KeSelectIdealProcessor(v24, v25, 0i64);
v17 = v75;
CurrentThread = Thread;
LABEL_18:
v14 = ProbeMode;
}
if( (CreateContext[1] & 0x8000) != 0 && (Process->WoW64Process || Process != CurrentThread->Tcb.Process) )
goto LABEL_24;
LABEL_22:
v17[96] = 0;
*((_BYTE *)v17 + 388) = v14;
if( ThreadContext )
{
if( Process == PsInitialSystemProcess )
{
LABEL_24:
v23 = -1073741811;
goto LABEL_34;
}
if( ObjectAttributes )
{
if( v14 == 1 && ((unsigned __int8)ObjectAttributes & 3) != 0 )
ExRaiseDatatypeMisalignment();
v17[96] = ObjectAttributes->Attributes & (v14 != 0 ? 7666 : 73714);
}
}
else if( ObjectAttributes )
{
v17[96] = ObjectAttributes->Attributes & 0x11FF2;
}
v68 = PoEnergyEstimationEnabled();
LOBYTE(v26) = -v68;
v27 = v68 != 0 ? 2400 : 2200;
KeQueryMaximumGroupCount(v26, v28);
v31 = v29;
LODWORD(v75) = 0;
if( v29 > 1u )
{
LODWORD(v75) = (v68 != 0 ? 2407 : 2207) & 0xFFFFFFF8;
v27 = (_DWORD)v75 + 8 * v29;
}
LODWORD(NonPagedPoolCharge) = v27;
LODWORD(PagedPoolCharge) = 0;
LODWORD(ObjectBodySize) = v27;
LOBYTE(v30) = ProbeMode;
LOBYTE(v31) = ProbeMode;
v23 = ObCreateObjectEx(
v31,
(_OBJECT_TYPE *)PsThreadType,
ObjectAttributes,
v30,
ExtraInfo,
ObjectBodySize,
PagedPoolCharge,
NonPagedPoolCharge,
&ObjectPointer,
0i64);
v67 = v23;
if( v23 < 0 )
goto LABEL_34;
v33 = (char *)ObjectPointer;
memset(ObjectPointer, 0i64, v27);
if( v68 )
{
*((_QWORD *)v33 + 191) = v33 + 2200;
_interlockedbittestandset((volatile signed __int32 *)v33, 0x15u);
v33 = (char *)ObjectPointer;
}
if( KiSchedulerAssistThreadFlagEnabled )
{
_interlockedbittestandset((volatile signed __int32 *)v33, 0x16u);
v33 = (char *)ObjectPointer;
}
v34 = (unsigned int)v75;
if( (_DWORD)v75 )
{
*((_DWORD *)v33 + 324) |= 0x20000u;
*((_QWORD *)v33 + 192) = &v33[v34];
}
ExInitializePushLock((PULONG_PTR)v33 + 159);
v75 = (PSP_STACK_ALLOCATION_STATE *)(v33 + 1144);
*((_QWORD *)v33 + 143) = Process->UniqueProcessId;
v35 = *(_DWORD *)StartContext;
if( (*(_DWORD *)StartContext & 4) != 0 )
{
*((_DWORD *)v33 + 324) |= 4u;
v35 = *(_DWORD *)StartContext;
}
if( (v35 & 0x200) != 0 )
*((_DWORD *)v33 + 29) |= 0x200000u;
v36 = (_EX_PUSH_LOCK *)(v33 + 1280);
PushLock = (_EX_PUSH_LOCK *)(v33 + 1280);
*((_QWORD *)v33 + 160) = 0i64;
*((_DWORD *)v33 + 322) = 7;
KeInitializeSemaphore((PRKSEMAPHORE)(v33 + 1160), 0, 1);
*((_QWORD *)v33 + 136) = v33 + 1080;
*((_QWORD *)v33 + 135) = v33 + 1080;
*((_QWORD *)v33 + 173) = v33 + 1376;
*((_QWORD *)v33 + 172) = v33 + 1376;
*((_QWORD *)v33 + 175) = v33 + 1392;
*((_QWORD *)v33 + 174) = v33 + 1392;
*((_QWORD *)v33 + 176) = 0i64;
*((_QWORD *)v33 + 186) = v33 + 1480;
*((_QWORD *)v33 + 185) = v33 + 1480;
*((_QWORD *)v33 + 187) = 0i64;
*((_QWORD *)v33 + 151) = v33 + 1200;
*((_QWORD *)v33 + 150) = v33 + 1200;
*((_QWORD *)v33 + 177) = 0i64;
*((_QWORD *)v33 + 140) = 0i64;
*((_QWORD *)v33 + 142) = v33 + 1128;
*((_QWORD *)v33 + 141) = v33 + 1128;
*((_QWORD *)v33 + 193) = -3i64;
if( KeQuerySystemTimeUnsafe() )
{
KeQuerySystemTimePrecise((_LARGE_INTEGER *)v33 + 134);
}
else
{
v33 = (char *)ObjectPointer;
*((_QWORD *)ObjectPointer + 134) = *(_QWORD *)&KUSER_SHARED_DATA.SystemTime.LowPart;
}
*((_QWORD *)v33 + 198) = v33 + 1576;
*((_QWORD *)v33 + 197) = v33 + 1576;
*((_QWORD *)v33 + 199) = 0i64;
*((_QWORD *)v33 + 201) = v33 + 1600;
*((_QWORD *)v33 + 200) = v33 + 1600;
ExAcquirePushLockExclusiveEx(v36, 0i64);
Handle = ExCreateHandleEx(PspCidTable, v33, 0i64, 0i64, 0i64);
*((_QWORD *)v33 + 144) = Handle;
if( !Handle )
{
v38 = PushLock;
if( (_InterlockedExchangeAdd64(&PushLock->_bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock(v38);
KeAbPostRelease(v38);
v23 = -1073741670;
v67 = -1073741670;
v33 = (char *)ObjectPointer;
goto LABEL_121;
}
if( ThreadContext )
{
v40 = *(_DWORD *)StartContext;
v41 = (16 * (*(_DWORD *)StartContext & 0x40)) | 8;
if( (*(_DWORD *)StartContext & 2) == 0 )
v41 = 16 * (v40 & 0x40);
v42 = v41 | 0x2000;
if( (v40 & 0x80u) == 0 )
v42 = v41;
v43 = v42 | 0x4000;
if( (v40 & 0x100) == 0 )
v43 = v42;
v69 = v43;
v44 = (PSP_STACK_ALLOCATION_STATE *)v74;
if( !v74 )
{
if( !Process->PicoContext )
{
v49 = (char *)Thread->Tcb.Teb;
Teb = (_TEB *)v49;
*((_QWORD *)v33 + 138) = PsQueryThreadStartAddress(Thread, 1ui64);
*((_QWORD *)v33 + 154) = Thread->Win32StartAddress;
*((_DWORD *)v33 + 325) |= 0x10u;
if( (Process->MitigationFlags2 & 0x4000) != 0
&& (ThreadContext->ContextFlags & 0x100040) == 1048640
&& (*(_DWORD *)((_BYTE *)&ThreadContext[1].P1Home + SLODWORD(ThreadContext[1].P3Home)) & 0x800i64) != 0 )
{
ExtendedFeature = RtlLocateExtendedFeature(&ThreadContext[1], 0xBu, 0i64);
if( ExtendedFeature )
{
if( (*ExtendedFeature & 1) != 0 && *((_QWORD *)ExtendedFeature + 1) )
*((_DWORD *)v33 + 29) |= 0x100000u;
}
}
WoW64Process = Process->WoW64Process;
if( WoW64Process )
{
v56 = 14392i64;
if( WoW64Process->Machine != 0x8664 )
v56 = 12288i64;
v77 = v56;
}
else
{
v77 = 6200i64;
}
KiStackAttachProcess(Process, 0i64, &ApcState);
if( MmSecureVirtualMemoryEx((unsigned __int64)v49, v77, 4, 0) )
{
v57 = v75;
*((_OWORD *)v49 + 4) = *(_OWORD *)v75;
*(_OWORD *)(v49 + 2008) = *(_OWORD *)v57;
*((_DWORD *)v49 + 1511) = 0;
*((_DWORD *)v49 + 1530) = 0;
*((_WORD *)v49 + 3063) &= 0x62Cu;
*((_WORD *)v49 + 3063) |= v69 | 0x40;
v58 = Process->WoW64Process;
if( v58 )
{
if( v58->Machine == 0x8664 )
{
v92 = v49 + 0x2000;
*((_QWORD *)v49 + 1032) = *(_QWORD *)v57;
*((_QWORD *)v49 + 1033) = *((_QWORD *)v33 + 144);
*((_QWORD *)v49 + 1275) = *(_QWORD *)v57;
*((_QWORD *)v49 + 1276) = *((_QWORD *)v33 + 144);
*((_DWORD *)v49 + 3559) = 0;
*((_DWORD *)v49 + 3578) = 0;
*((_WORD *)v49 + 7159) &= 0x62Cu;
*((_WORD *)v49 + 7159) |= v69 | 0x40;
}
else
{
v93 = v49 + 0x2000;
v88 = *v57;
*((_DWORD *)v49 + 2056) = v88;
v89 = *((_DWORD *)v33 + 288);
*((_DWORD *)v49 + 2057) = v89;
v90 = *v57;
*((_DWORD *)v49 + 2477) = v90;
v91 = *((_DWORD *)v33 + 288);
*((_DWORD *)v49 + 2478) = v91;
*((_DWORD *)v49 + 3047) = 0;
*((_DWORD *)v49 + 3057) = 0;
*((_WORD *)v49 + 6117) &= 0x62Cu;
*((_WORD *)v49 + 6117) |= v69 | 0x40;
}
}
}
else
{
v23 = -1073741503;
v67 = -1073741503;
}
LABEL_110:
KiUnstackDetachProcess(&ApcState, 0i64);
if( v23 < 0 )
goto LABEL_121;
goto LABEL_111;
}
Rip = ThreadContext->_Rip;
*((_QWORD *)v33 + 138) = Rip;
*((_QWORD *)v33 + 154) = Rip;
v52 = v77;
*((_QWORD *)v33 + 189) = *(_QWORD *)(v77 + 8);
*((_QWORD *)v33 + 190) = *(_QWORD *)(v52 + 16);
_interlockedbittestandset((volatile signed __int32 *)v33, 0x1Au);
RtlGetExtendedContextLength(KUSER_SHARED_DATA.XState.EnabledFeatures != 0 ? 1048671 : 1048607, &ContextLength);
PoolWithTag = ExAllocatePoolWithTag(1ui64, (unsigned int)ContextLength, 1666413392i64);
v33 = (char *)ObjectPointer;
*((_QWORD *)ObjectPointer + 195) = PoolWithTag;
if( !PoolWithTag )
{
v23 = -1073741670;
v67 = -1073741670;
goto LABEL_121;
}
v49 = (char *)Teb;
LABEL_111:
inited = KeInitThread(
(_KTHREAD *)v33,
*((_QWORD *)v33 + 138),
(__int64)ThreadContext,
(__int64)v49,
(__int64)Process,
PreferredNode);
goto LABEL_113;
}
if( (Process->MitigationFlags2 & 0x4000) != 0 && (!CreateContext || (CreateContext[1] & 0x8000) == 0) )
*((_DWORD *)v33 + 29) |= 0x100000u;
LODWORD(ExtraInfoa) = PreferredNode;
if( Process->WoW64Process )
{
v85.StackAllocationFlags = 0;
v86 = 0x8000i64;
v87 = 0x40000i64;
*(_QWORD *)&v85.StackSize = 0i64;
v23 = PspSetupUserStack(
(ULONG_PTR)Process,
ThreadContext,
InitialTeb,
(PSP_STACK_ALLOCATION_STATE *)&v85,
(UINT64)ExtraInfoa);
v67 = v23;
if( v23 >= 0 )
{
v45 = v74;
v74->StackAllocationFlags ^= (v85.StackAllocationFlags ^ v74->StackAllocationFlags) & 2;
v46 = (__int64)InitialTeb;
v47 = PspWow64SetupUserStack(Process, (INT64)v39, (INT64)InitialTeb, (CHAR *)v45);
LABEL_68:
v23 = v47;
v67 = v47;
LABEL_73:
if( v23 < 0 )
goto LABEL_121;
v48 = v78;
if( CreateContext && (CreateContext[1] & 0x8000) != 0 && ((unsigned int)KeFeatureBits & 0x10000000) == 0 )
v48 = 0x100000000i64;
v23 = MmCreateTeb(Process, v46, v75, (VOID **)v48, (__int64)&Teb);
v67 = v23;
if( v23 < 0 )
goto LABEL_121;
*((_QWORD *)v33 + 138) = ThreadContext->_Rip;
*((_QWORD *)v33 + 154) = ThreadContext->_Rcx;
v49 = (char *)Teb;
if( Process->WoW64Process )
{
v23 = PspWow64InitThread((ULONG_PTR)Process);
v67 = v23;
if( v23 < 0 )
goto LABEL_121;
}
if( v69 )
{
KiStackAttachProcess(Process, 0i64, &ApcState);
*((_WORD *)v49 + 3063) = v69;
v50 = Process->WoW64Process;
if( v50 )
{
if( v50->Machine == 0x8664 )
{
v92 = v49 + 0x2000;
*((_WORD *)v49 + 7159) = v69;
}
else
{
v93 = v49 + 0x2000;
*((_WORD *)v49 + 6117) = v69;
}
}
v23 = 0;
v67 = 0;
goto LABEL_110;
}
goto LABEL_111;
}
}
else
{
v23 = PspSetupUserStack((ULONG_PTR)Process, ThreadContext, InitialTeb, v44, (UINT64)ExtraInfoa);
v67 = v23;
if( v23 >= 0 && (*((_DWORD *)v33 + 29) & 0x100000) != 0 )
{
LODWORD(ExtraInfob) = PreferredNode;
v46 = (__int64)InitialTeb;
v47 = PspSetupUserShadowStack(Process, (INT32 *)ThreadContext, (INT64)InitialTeb, v74, (UINT64)ExtraInfob);
goto LABEL_68;
}
}
v46 = (__int64)InitialTeb;
goto LABEL_73;
}
*((_QWORD *)v33 + 138) = StartRoutine;
*((_QWORD *)v33 + 154) = StartRoutine;
inited = KeInitThread((_KTHREAD *)v33, (__int64)a8, 0i64, 0i64, (__int64)Process, PreferredNode);
v49 = (char *)Teb;
LABEL_113:
v67 = inited;
v23 = inited;
if( inited < 0 )
{
if( !v49 || !v74 )
goto LABEL_121;
goto LABEL_120;
}
if( CreateContext )
{
if( (CreateContext[1] & 0x8000) != 0 )
{
v23 = PspUmsInitThread((INT64)v33, ProbeMode, (__int64)CreateContext, (__int64)v49);
v67 = v23;
if( v23 < 0 )
{
LABEL_120:
MmDeleteTeb((ULONG_PTR)Process, v49);
LABEL_121:
if( v74 && v74->StackAllocationFlags )
PspDeleteUserStack(Process, v39, (_PSP_STACK_ALLOCATION_STATE *)InitialTeb);
v60 = (void *)*((_QWORD *)v33 + 195);
if( v60 )
{
ExFreePoolWithTag(v60, 0x63537350u);
*((_QWORD *)v33 + 195) = 0i64;
}
if( *((_QWORD *)v33 + 144) )
{
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)v33 + 160, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((_EX_PUSH_LOCK *)v33 + 160);
KeAbPostRelease(v33 + 1280);
v23 = v67;
v33 = (char *)ObjectPointer;
}
if( !*((_QWORD *)v33 + 68) )
ObfDereferenceObjectWithTag(Process, 0x72437350ui64);
HalPutDmaAdapter((PADAPTER_OBJECT)v33);
return v23;
}
}
}
*(_QWORD *)v94 = v33;
return 0;
}Referenced by:
NtCreateUserProcess
PspCreatePicoThread
PspCreateThread