PsImpersonateContainerOfThread
BOOLEAN __fastcall PsImpersonateContainerOfThread(__int64 a1){
_ETHREAD *CurrentThread;
UINT8 CurrentIrql;
int v4;
unsigned __int8 v5;
struct _KPRCB *CurrentPrcb;
char v7;
struct _KPRCB *v8;
EVENT_DESCRIPTOR *v9;
__int64 v10;
_KSCHEDULING_GROUP *v11;
UINT64 v12;
BOOLEAN result;
__int64 v14;
ULONG_PTR v15;
struct _KPRCB *v16;
__int64 v18;
int v19;
__int64 v20;
__int64 v21;
__int16 v22;
bool v23;
INT64 v24;
unsigned int v25;
INT64 v26;
INT64 v27;
unsigned int v28;
unsigned int v29;
UINT64 UserDataCount;
UINT64 SpinCount;
int v32;
int v33;
_SINGLE_LIST_ENTRY ReadyList;
EVENT_DATA_DESCRIPTOR UserData;
int *v36;
__int64 v37;
int v38;
if( ObpTraceFlags )
ObpPushStackInfo(a1 - 48, 1, 1i64, 1953394499i64);
ObpIncrPointerCount((volatile INT64 *)(a1 - 48));
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
PspRevertContainerImpersonation((ULONG_PTR)CurrentThread);
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
ExpAcquireSpinLockExclusive((INT64 *)PspThreadWorkOnBehalfLock, CurrentIrql);
*((_QWORD *)CurrentThread + 184) = a1;
v4 = *(char *)(a1 + 195);
if( v4 > 15 )
LOBYTE(v4) = 15;
ReadyList.Next = 0i64;
v5 = KeGetCurrentIrql();
__writecr8(2ui64);
CurrentPrcb = KeGetCurrentPrcb();
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)CurrentThread + 16, 0i64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( *((_QWORD *)CurrentThread + 8) );
v14 = *((_QWORD *)CurrentPrcb + 4247);
if( v14 && *((_BYTE *)CurrentPrcb + 32) <= 1u )
++*(_DWORD *)(v14 + 24);
}
*((_BYTE *)CurrentThread + 795) = v4;
v7 = *((_BYTE *)CurrentThread + (char)v4 + 824);
if( v7 == -1 )
KeBugCheckEx(0x157u, (ULONG_PTR)CurrentThread, (char)v4, 1ui64, 0i64);
*((_BYTE *)CurrentThread + (char)v4 + 824) = v7 + 1;
*((_DWORD *)CurrentThread + 214) |= 1 << v4;
if( *((char *)CurrentThread + 195) < (char)v4 )
KiSetPriorityThread((_KTHREAD *)CurrentThread, &ReadyList, (unsigned int)(char)v4);
KiReleaseThreadLockSafe((INT64)CurrentThread);
v8 = KeGetCurrentPrcb();
KiReadyDeferredReadyList(v8, &ReadyList);
if( v5 < 2u )
{
v15 = *((_QWORD *)v8 + 1);
if( *((_QWORD *)v8 + 2) )
{
KiAbProcessContextSwitch(*((_KTHREAD **)v8 + 1), 0i64);
v16 = KeGetCurrentPrcb();
HIDWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)v8 + 12, 0i64) )
{
do
KeYieldProcessorEx((UINT64 *)((char *)&SpinCount + 4));
while( *((_QWORD *)v8 + 6) );
v18 = *((_QWORD *)v16 + 4247);
if( v18 && *((_BYTE *)v16 + 32) <= 1u )
{
v19 = *(_DWORD *)(v18 + 24) + 1;
*(_DWORD *)(v18 + 24) = v19;
}
}
v20 = *((_QWORD *)v8 + 2);
*((_QWORD *)v8 + 2) = 0i64;
_disable();
KiEndThreadCycleAccumulation(v8, (_KTHREAD *)v15, 0i64);
_enable();
*((_QWORD *)v8 + 1) = v20;
if( *(_BYTE *)(v20 + 388) == 1 )
{
v21 = (unsigned int)(*(_DWORD *)(v20 + 132) - *(_DWORD *)(v20 + 436));
*(_DWORD *)(v20 + 132) = v21 + KUSER_SHARED_DATA.TickCount.LowPart;
}
*(_BYTE *)(v20 + 388) = 2;
*(_BYTE *)(v15 + 643) = 32;
*(_BYTE *)(v15 + 390) = v5;
KiQueueReadyThread((__int64)v8, v15, v21);
if( !KiSwapContext((PKTHREAD)v15, (PKTHREAD)v20) )
goto LABEL_37;
}
else if( (*(_DWORD *)(v15 + 116) & 0x40) == 0 )
{
goto LABEL_37;
}
__writecr8(1ui64);
*(_DWORD *)(v15 + 116) &= ~0x40u;
KiDeliverApc(0, 0i64, 0i64);
LABEL_37:
__writecr8(v5);
goto LABEL_12;
}
if( *((_QWORD *)v8 + 2) && !*((_BYTE *)v8 + 12586) )
KiRequestSoftwareInterrupt(v8, 2);
LABEL_12:
if( KeHeteroSystemQos )
{
v22 = v38;
_disable();
v23 = (v22 & 0x200) != 0;
v24 = (unsigned __int8)*(_DWORD *)(a1 + 512);
v25 = (unsigned __int8)*((_DWORD *)CurrentThread + 128);
if( (_DWORD)v24 != v25 && ((_DWORD)v24 == 3 || v25 == 3 || (unsigned int)v24 < v25) )
{
KeSetThreadBamQosLevel((INT64)CurrentThread, v24);
v28 = (unsigned __int8)*(_DWORD *)(v27 + 236);
v29 = (unsigned __int8)*((_DWORD *)CurrentThread + 128);
if( v29 != v28 && (v29 == 3 || v28 == 3 || v29 < v28) )
KeCheckAndApplyBamQos(v27, (INT64)CurrentThread, v26, v27);
}
if( v23 )
_enable();
}
ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)PspThreadWorkOnBehalfLock);
__writecr8(CurrentIrql);
v10 = *(_QWORD *)(*(_QWORD *)(a1 + 544) + 1296i64);
if( v10 )
{
v11 = *(_KSCHEDULING_GROUP **)(v10 + 1016);
if( v11 )
KeSetThreadChargeOnlySchedulingGroup((_KTHREAD *)CurrentThread, v11);
}
v12 = *(_QWORD *)EtwpPsProvRegHandle;
result = EtwEventEnabled(*(UINT64 *)EtwpPsProvRegHandle, (EVENT_DESCRIPTOR *)&ThreadWorkOnBehalfUpdate, v9);
if( result )
{
v32 = 0;
UserData.Ptr = (unsigned __int64)&v32;
v33 = *(_DWORD *)(a1 + 1152);
*(_QWORD *)&UserData.Size = 4i64;
v36 = &v33;
v37 = 4i64;
LODWORD(UserDataCount) = 2;
return EtwWriteEx(
v12,
(EVENT_DESCRIPTOR *)&ThreadWorkOnBehalfUpdate,
0i64,
1ui64,
0i64,
0i64,
UserDataCount,
&UserData);
}
return result;
}Referenced by:
IopProcessWorkItem
NtAlpcImpersonateClientContainerOfPort
NtSetInformationThread