PspExitThread
VOID __stdcall PspExitThread(INT64 ExitStatus){
int v1;
_ETHREAD *CurrentThread;
ULONG_PTR v3;
ULONG_PTR v4;
struct _DMA_ADAPTER *v5;
volatile signed __int64 *v6;
void *v7;
void *v8;
__int64 v9;
union _LARGE_INTEGER v10;
unsigned int v11;
_QWORD *v12;
struct _DMA_ADAPTER *v13;
struct _DMA_ADAPTER *v14;
int v15;
INT64 *v16;
char v17;
unsigned __int64 v18;
__int64 v19;
void *v20;
__int16 v21;
_QWORD *v22;
void *v23;
_QWORD *v24;
_QWORD *v25;
_QWORD *v26;
struct DMA_ADAPTER *v27;
void *v28;
int v29;
_QWORD *v30;
_EJOB *v31;
_EJOB *ProcessServerSilo;
_EJOB *v33;
int v34[8];
PLARGE_INTEGER Timeout;
ULONG_PTR RegionSize;
ULONG_PTR v37;
__m256i v38;
__int128 v39;
void *v40;
PVOID BaseAddress;
PVOID v42;
ULONG_PTR v43;
_ETHREAD *v44;
__int128 v45;
__int128 v46;
unsigned int ExitStatusa;
char v48;
PMDL MemoryDescriptorList;
PVOID Object;
ExitStatusa = ExitStatus;
v1 = ExitStatus;
memset(&v38, 0, sizeof(v38));
v39 = 0i64;
v46 = 0i64;
v45 = 0i64;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v44 = CurrentThread;
v43 = *((_QWORD *)CurrentThread + 68);
v3 = v43;
PspClearProcessThreadCidRefs(CurrentThread, *((PVOID *)CurrentThread + 144), CurrentThread);
v4 = *((_QWORD *)CurrentThread + 23);
if( v43 != v4 )
KeBugCheckEx(5u, v43, v4, *((unsigned __int8 *)CurrentThread + 586), (ULONG_PTR)CurrentThread);
__writecr8(0i64);
if( (*((_DWORD *)CurrentThread + 325) & 1) != 0 )
KeBugCheckEx(0xE9u, (ULONG_PTR)CurrentThread, 0i64, 0i64, 0i64);
if( *((_DWORD *)CurrentThread + 121) )
KeBugCheckEx(0x20u, 0i64, *((unsigned int *)CurrentThread + 121), 0i64, 1ui64);
if( *((_QWORD *)CurrentThread + 155) )
{
KeSetThreadChargeOnlySchedulingGroup((_KTHREAD *)CurrentThread, 0i64);
ObfDereferenceObjectWithTag(*((PVOID *)CurrentThread + 155), 0x79517350ui64);
*((_QWORD *)CurrentThread + 155) = 0i64;
}
PspEmptyPropertySet((_PS_PROPERTY_SET *)((char *)CurrentThread + 1480));
PspRevertContainerImpersonation((ULONG_PTR)CurrentThread);
ExWaitForRundownProtectionRelease((EX_RUNDOWN_REF *)CurrentThread + 159);
v5 = (struct _DMA_ADAPTER *)*((_QWORD *)CurrentThread + 156);
if( v5 )
{
PopPowerRequestCleanUp(*((UINT64 **)CurrentThread + 156));
HalPutDmaAdapter(v5);
*((_QWORD *)CurrentThread + 156) = 0i64;
}
v48 = 0;
Object = 0i64;
*((_DWORD *)CurrentThread + 338) = v1;
--*((_WORD *)CurrentThread + 242);
if( (*(_DWORD *)(v3 + 2172) & 1) == 0 || *(_QWORD *)(v3 + 2240) )
PspCallThreadNotifyRoutines(CurrentThread, 0, 0);
v6 = (volatile signed __int64 *)(v3 + 1080);
ExAcquirePushLockExclusiveEx(v3 + 1080, 0i64);
if( --*(_DWORD *)(v3 + 1520) )
{
if( v1 != -1073741749 )
*(_DWORD *)(v3 + 1532) = v1;
}
else
{
_InterlockedOr((volatile signed __int32 *)(v3 + 1124), 0x2000008u);
KeForceResumeProcess((_KPROCESS *)v3);
v48 = 1;
if( *(_DWORD *)(v3 + 2004) == 259 )
{
if( v1 == -1073741749 )
*(_DWORD *)(v3 + 2004) = *(_DWORD *)(v3 + 1532);
else
*(_DWORD *)(v3 + 2004) = v1;
}
v24 = *(_QWORD **)(v3 + 1504);
if( v24 != (_QWORD *)(v3 + 1504) )
{
v25 = (_QWORD *)(v3 + 1504);
v26 = 0i64;
do
{
if( v24 - 157 != (_QWORD *)CurrentThread )
{
if( !*((_BYTE *)v24 - 1252) && ObReferenceObjectSafeWithTag(v24 - 157, 0x65547350ui64) )
{
if( (_InterlockedExchangeAdd64(v6, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((volatile INT64 *)(v3 + 1080));
KeAbPostRelease((PVOID)(v3 + 1080));
KeLeaveCriticalRegionThread((__int64)CurrentThread);
KeWaitForSingleObject(v24 - 157, Executive, 0, 0, 0i64);
if( v26 )
ObfDereferenceObjectWithTag(v26, 0x65547350ui64);
v26 = v24 - 157;
--*((_WORD *)CurrentThread + 242);
ExAcquirePushLockExclusiveEx(v3 + 1080, 0i64);
}
v25 = (_QWORD *)(v3 + 1504);
}
v24 = (_QWORD *)*v24;
}
while( v24 != v25 );
Object = v26;
}
}
if( (_InterlockedExchangeAdd64(v6, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((volatile INT64 *)(v3 + 1080));
KeAbPostRelease((PVOID)(v3 + 1080));
KeLeaveCriticalRegionThread((__int64)CurrentThread);
if( Object )
ObfDereferenceObjectWithTag(Object, 0x65547350ui64);
v9 = 0i64;
v10.QuadPart = -3i64;
if( *((_QWORD *)CurrentThread + 193) != -3i64 )
v9 = 1i64;
if( (_BYTE)v9 )
{
v31 = PsAttachSiloToCurrentThread((_EJOB *)0xFFFFFFFFFFFFFFFDi64);
if( v31 == (_EJOB *)HalSystemVectorDispatchEntry()
|| (POBJECT_TYPE *)ObTypeIndexTable[(unsigned __int8)ObHeaderCookie ^ LOBYTE(v31[-1].EnergyTrackingState.Value) ^ (unsigned __int64)(unsigned __int8)((unsigned __int16)((_WORD)v31 - 48) >> 8)] != PsJobType
|| (v31->JobFlags2 & 2) == 0 )
{
KeBugCheckEx(0x1CBu, (ULONG_PTR)CurrentThread, (ULONG_PTR)v31, v3, 1ui64);
}
ObfDereferenceObjectWithTag(v31, 0x6D497350ui64);
}
if( *(_QWORD *)(v3 + 1400) && (*((_DWORD *)CurrentThread + 29) & 0x400) == 0 )
{
if( !v48 )
{
v11 = ExitStatusa;
DbgkExitThread(ExitStatusa);
goto LABEL_22;
}
DbgkExitProcess(*(unsigned int *)(v3 + 2004));
}
v11 = ExitStatusa;
LABEL_22:
if( (*(_BYTE *)(v3 + 992) & 1) != 0 )
{
MemoryDescriptorList = 0i64;
if( (int)KeUnsecureThread(&MemoryDescriptorList) >= 0 )
{
MmUnlockPages(MemoryDescriptorList);
ExFreePoolWithTag(MemoryDescriptorList, 0x65537350u);
}
}
if( (_BYTE)KdDebuggerEnabled )
{
if( (*((_DWORD *)CurrentThread + 324) & 0x20) != 0 )
{
v10.QuadPart = *(unsigned int *)(*((_QWORD *)CurrentThread + 68) + 1124i64);
if( (v10.LowPart & 0x40000008) == 0 )
{
ProcessServerSilo = (_EJOB *)PsGetProcessServerSilo(v3);
LODWORD(Timeout) = v11;
PspCatchCriticalBreak(
(INT8 *)"Critical thread 0x%p(in %s) exited\n",
CurrentThread,
(UINT8 *)(v3 + 1448),
ProcessServerSilo,
(INT64)Timeout);
}
}
}
if( v48 && (*(_DWORD *)(v3 + 1124) & 0x2000) != 0 )
{
v33 = (_EJOB *)PsGetProcessServerSilo(v3);
LODWORD(Timeout) = v11;
PspCatchCriticalBreak(
(INT8 *)"Critical process 0x%p(%s) exited\n",
(PVOID)v3,
(UINT8 *)(v3 + 1448),
v33,
(INT64)Timeout);
}
v12 = (_QWORD *)*((_QWORD *)CurrentThread + 139);
if( v12 )
{
v38.m256i_i64[0] = 0x600300008i64;
*((_QWORD *)&v39 + 1) = *((_QWORD *)CurrentThread + 134);
do
{
while( 1 )
{
v29 = LpcRequestPort(v12[1], &v38);
if( v29 != -1073741801 && v29 != -1073741670 )
break;
KeDelayExecutionThread(0, 0, (PLARGE_INTEGER)&PspShortTime);
}
HalPutDmaAdapter((PADAPTER_OBJECT)v12[1]);
v30 = (_QWORD *)*v12;
ExFreePoolWithTag(v12, 0x70547350u);
v12 = v30;
}
while( v30 );
}
if( (*((_DWORD *)CurrentThread + 324) & 2) != 0 )
{
LODWORD(v13) = PsCaptureExceptionPort((_EPROCESS *)v3);
v14 = v13;
if( v13 )
{
v38.m256i_i64[0] = 0x600300008i64;
*((_QWORD *)&v39 + 1) = *((_QWORD *)CurrentThread + 134);
while( 1 )
{
v15 = LpcRequestPort((INT64)v14, &v38);
if( v15 != -1073741801 && v15 != -1073741670 )
break;
KeDelayExecutionThread(0, 0, (PLARGE_INTEGER)&PspShortTime);
}
HalPutDmaAdapter(v14);
}
}
if( *((_QWORD *)CurrentThread + 57) )
{
*(_QWORD *)&v45 = CurrentThread;
DWORD2(v45) = 1;
PsInvokeWin32Callout(1i64, &v45, 0i64, 0i64);
}
if( v48 && *(_QWORD *)(v3 + 1288) )
{
*(_QWORD *)&v46 = v3;
DWORD2(v46) = 0;
PsInvokeWin32Callout(0i64, &v46, 0i64, 0i64);
}
if( (*((_DWORD *)CurrentThread + 30) & 0x40) == 0 )
KeBugCheckEx(0x94u, 0i64, (ULONG_PTR)CurrentThread, 0i64, 0i64);
IoCancelThreadIo(v10, (void *)v9, v7, v8);
ExTimerRundown();
CmNotifyRunDown((__int64)CurrentThread);
KiRundownMutants(KeGetCurrentThread());
v17 = *((_BYTE *)CurrentThread + 3);
if( (v17 & 0x40) != 0 || v17 < 0 )
PspUmsUnInitThread(CurrentThread, v16);
v18 = *((_QWORD *)CurrentThread + 30);
Object = (PVOID)v18;
if( v18 )
{
*((_QWORD *)CurrentThread + 30) = 0i64;
--*((_WORD *)CurrentThread + 242);
_InterlockedOr(v34, 0);
if( (*((_QWORD *)CurrentThread + 160) & 1) != 0 )
ExfAcquireReleasePushLockExclusive((char *)CurrentThread + 1280);
KeLeaveCriticalRegionThread((__int64)CurrentThread);
if( (*((_DWORD *)CurrentThread + 29) & 0x400) == 0 && (*(_DWORD *)(v3 + 1124) & 0x40000008) == 0 )
{
if( (*((_DWORD *)CurrentThread + 324) & 2) != 0 )
{
v40 = *(void **)(v18 + 5240);
BaseAddress = v40;
RegionSize = 0i64;
ZwFreeVirtualMemory((PVOID)0xFFFFFFFFFFFFFFFFi64, &BaseAddress, &RegionSize, 0x8000ui64);
v19 = *(_QWORD *)(v3 + 1408);
if( v19 )
{
v21 = *(_WORD *)(v19 + 8);
if( v21 == 332 || v21 == 452 )
{
v42 = (PVOID)*(unsigned int *)(v18 + 11788);
v37 = 0i64;
ZwFreeVirtualMemory((PVOID)0xFFFFFFFFFFFFFFFFi64, &v42, &v37, 0x8000ui64);
}
}
}
v20 = *(void **)(v18 + 5800);
if( v20 )
ObCloseHandle(v20, 1);
if( (*((_DWORD *)CurrentThread + 29) & 0x100000) != 0 && (*((_DWORD *)CurrentThread + 324) & 2) != 0 )
PspFreeCurrentThreadUserShadowStack();
MmDeleteTeb(v3, v18);
}
}
v22 = (_QWORD *)((char *)CurrentThread + 1080);
if( KeQuerySystemTimeUnsafe() )
KeQuerySystemTimePrecise((_LARGE_INTEGER *)CurrentThread + 135);
else
*v22 = *(_QWORD *)&KUSER_SHARED_DATA.SystemTime.LowPart;
if( v48 )
{
*(_QWORD *)(v3 + 2112) = *v22;
PspExitProcess(1, v3);
v27 = (struct DMA_ADAPTER *)PsReferencePrimaryToken((PEPROCESS)v3);
if( (unsigned __int8)SeAuditingWithTokenForSubcategory(0x86ui64, v27) )
SeAuditProcessExit((_EPROCESS *)v3, *(_DWORD *)(v3 + 2004));
ObFastDereferenceObject((INT64 *)(v3 + 1208), v27);
ExWnfExitProcess(v3, 0i64);
PspRundownSingleProcess(v3, 1);
LpcExitProcess(v3);
v28 = *(void **)(v3 + 2120);
if( v28 )
{
ExFreePoolWithTag(v28, 0);
*(_QWORD *)(v3 + 2120) = 0i64;
}
}
KeRundownApcQueues((__int64)CurrentThread);
if( *((_QWORD *)CurrentThread + 90) && PspLegoNotifyRoutine )
PspLegoNotifyRoutine(CurrentThread);
v23 = (void *)*((_QWORD *)CurrentThread + 195);
if( v23 )
{
ExFreePoolWithTag(v23, 0x63537350u);
*((_QWORD *)CurrentThread + 195) = 0i64;
}
KeTerminateThread((_KTHREAD *)CurrentThread);
}Referenced by:
KiSchedulerApcTerminate
NtTerminateProcess
PspTerminateThreadByPointer