MiFinishVadDeletion
VOID __fastcall MiFinishVadDeletion(UINT64 *P, INT64 a2, UINT64 a3, CHAR a4){
_ETHREAD *CurrentThread;
int v5;
unsigned int v8;
UINT64 v9;
int v10;
__int64 v11;
__int64 v12;
unsigned int v13;
ULONG_PTR v14;
_ETHREAD *v15;
ULONG_PTR SessionId;
char v17;
int v18;
bool v19;
__int64 v20;
unsigned __int64 v21;
unsigned __int8 v22;
UINT64 v23;
UINT64 *v24;
__int64 v25;
LONG *v26;
UINT8 CurrentIrql;
UINT64 v28;
__int64 v29;
int v30;
BOOL v31;
_ETHREAD *v32;
_ETHREAD *v33;
ULONG_PTR v34;
int v35;
__int64 v36;
unsigned __int64 v37;
__int64 v38;
__int64 v39;
UINT64 v40;
UINT64 v41;
int v42;
int v43;
int v44;
BOOL v45;
_ETHREAD *v46;
__int64 v47;
char v48;
int v49;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v5 = *((_DWORD *)P + 12);
v46 = CurrentThread;
v8 = 0;
v9 = *((_QWORD *)CurrentThread + 23);
if( (v5 & 4) != 0 )
{
v10 = 1;
v49 = 1;
if( (v5 & 0x100000) == 0 )
{
v11 = *((unsigned int *)P + 13);
LODWORD(v11) = v11 & 0x7FFFFFFF;
if( (v11 | ((unsigned __int64)*((unsigned __int8 *)P + 34) << 31)) < 0x7FFFFFFFDi64 )
v8 = 1;
v10 = 1;
}
}
else
{
v10 = 0;
v49 = 0;
}
if( a3 <= *(_QWORD *)(v9 + 1496) && (a4 & 1) == 0 )
{
*(_QWORD *)(v9 + 1176) -= a3 - a2 + 1;
v5 = *((_DWORD *)P + 12);
}
v12 = *(_QWORD *)(v9 + 1680);
v47 = v12;
if( (v5 & 0x100000) == 0 && (v5 & 0x70) == 32 && (v5 & 0x200000) != 0 )
--*(_QWORD *)(v12 + 384);
if( v10 == 1 )
{
_InterlockedIncrement((volatile signed __int32 *)(v12 + 280));
v13 = *((_DWORD *)P + 12);
if( MiVadPageSizes[(v13 >> 18) & 3] == 16 )
{
if( (v13 & 0x100000) != 0 )
--*(_QWORD *)(v12 + 424);
else
--*(_QWORD *)(v12 + 432);
}
MiReturnVadQuota((INT64)P, v9, v8);
MiRemoveVadCharges((__int64)P, v9);
}
*((_BYTE *)CurrentThread + 1304) &= ~1u;
v14 = v9 + 1224;
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)(v9 + 1224), 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((volatile INT64 *)(v9 + 1224));
v42 = 0;
v15 = (_ETHREAD *)KeGetCurrentThread();
if( (unsigned int)MiGetSystemRegionType(v9 + 1224) == 1 )
SessionId = (unsigned int)MmGetSessionIdEx(*((_QWORD *)v15 + 23));
else
SessionId = 0xFFFFFFFFi64;
--*((_WORD *)v15 + 243);
v17 = ++*((_BYTE *)v15 + 794);
v18 = (*((char *)v15 + 792) | *((char *)v15 + 870)) ^ 0x3F;
v19 = !_BitScanReverse((unsigned int *)&v20, v18);
if( v19 )
goto LABEL_76;
while( 1 )
{
v21 = *((_QWORD *)v15 + 100) + 96 * v20;
v18 &= ~(1 << v20);
if( (*(_BYTE *)(v21 + 26) & 1) != 0
&& (*(_DWORD *)(v21 + 32) & 1) == 0
&& (*(_QWORD *)(v21 + 32) & 0x7FFFFFFFFFFFFFFCi64) == (v14 & 0x7FFFFFFFFFFFFFFCi64)
&& *(_DWORD *)(v21 + 40) == (_DWORD)SessionId )
{
*(_BYTE *)(v21 + 26) &= ~1u;
if( *(_QWORD *)(v21 + 32) )
break;
}
v19 = !_BitScanReverse((unsigned int *)&v20, v18);
if( v19 )
goto LABEL_76;
}
if( !v21 )
{
LABEL_76:
if( (*((_DWORD *)v15 + 30) & 0x10000) == 0 )
KeBugCheckEx(0x162u, (ULONG_PTR)v15, v14, SessionId, 0i64);
}
else
{
*(_BYTE *)(v21 + 32) |= 2u;
if( *(__int64 *)(v21 + 32) < 0 )
KiAbEntryRemoveFromTree(v21);
v42 = *(_DWORD *)(v21 + 88) & 0x1FFFF;
*(_DWORD *)(v21 + 88) &= 0xFFFE0000;
*(_BYTE *)(v21 + 25) &= ~1u;
*(_QWORD *)(v21 + 32) = 0i64;
v22 = 1 << ((__int64)(v21 - *((_QWORD *)v15 + 100)) / 96);
if( v17 == 1 )
*((_BYTE *)v15 + 792) |= v22;
else
_InterlockedOr8((volatile signed __int8 *)v15 + 870, v22);
}
--*((_BYTE *)v15 + 794);
KiAbThreadRemoveBoosts((ULONG_PTR)v15, v14, (unsigned int *)&v42);
v19 = (*((_WORD *)v15 + 243))++ == 0xFFFF;
if( v19 && *((_ETHREAD **)v15 + 19) != (_ETHREAD *)((char *)v15 + 152) )
KiCheckForKernelApcDelivery();
v19 = (*((_WORD *)CurrentThread + 243))++ == 0xFFFF;
if( v19 && *((_ETHREAD **)CurrentThread + 19) != (_ETHREAD *)((char *)CurrentThread + 152) )
KiCheckForKernelApcDelivery();
v23 = 0i64;
if( v49 == 1 )
{
v24 = P + 7;
v25 = *((_QWORD *)KeGetCurrentThread() + 23);
if( (*(_BYTE *)(v25 + 1848) & 7) == 2 )
v26 = &dword_140C4F4C0;
else
v26 = (LONG *)(v25 + 1856);
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
ExpAcquireSpinLockExclusive((INT64 *)v26, CurrentIrql);
v26[1] = 0;
v28 = *v24;
if( *v24 )
{
do
{
v40 = *(_QWORD *)v28;
if( (*(_DWORD *)(v28 + 64) & 1) != 0 )
{
*(_QWORD *)v28 = v23;
v23 = v28;
*v24 = v40;
}
else
{
v24 = (UINT64 *)v28;
}
v28 = v40;
}
while( v40 );
}
MiUnlockWorkingSetExclusive(v25 + 1664, CurrentIrql);
v29 = (__int64)v46;
P[2] = -1i64;
if( v23 )
--*(_WORD *)(v29 + 484);
v30 = *((_DWORD *)P + 12);
if( (v30 & 0x100000) == 0 && (v30 & 0x70) == 32 && (v30 & 0x400000) != 0 )
{
MiUnlockVad(v29, (__int64)P);
MiDeleteImageHotPatchState((UINT64)P);
--*(_WORD *)(v29 + 486);
ExAcquirePushLockExclusiveEx((UINT64)(P + 5), 0i64);
*(_BYTE *)(v29 + 1304) |= 0x80u;
}
}
if( (a4 & 2) != 0 )
{
MiUnlockAndDereferenceNestedVad(P);
}
else
{
v31 = MiDereferenceVad((__int64)P);
v32 = (_ETHREAD *)KeGetCurrentThread();
v45 = v31;
*((_BYTE *)v32 + 1304) &= ~0x80u;
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)P + 5, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((volatile INT64 *)P + 5);
v44 = 0;
v33 = (_ETHREAD *)KeGetCurrentThread();
if( (unsigned int)MiGetSystemRegionType((UINT64)(P + 5)) == 1 )
v34 = (unsigned int)MmGetSessionIdEx(*((_QWORD *)v33 + 23));
else
v34 = 0xFFFFFFFFi64;
--*((_WORD *)v33 + 243);
++*((_BYTE *)v33 + 794);
v35 = (*((char *)v33 + 792) | *((char *)v33 + 870)) ^ 0x3F;
v48 = *((_BYTE *)v33 + 794);
v19 = !_BitScanReverse((unsigned int *)&v36, v35);
v43 = v36;
if( v19 )
goto LABEL_79;
while( 1 )
{
v37 = *((_QWORD *)v33 + 100) + 96 * v36;
v35 &= ~(1 << v36);
if( (*(_BYTE *)(v37 + 26) & 1) != 0
&& (*(_DWORD *)(v37 + 32) & 1) == 0
&& (*(_QWORD *)(v37 + 32) & 0x7FFFFFFFFFFFFFFCi64) == ((unsigned __int64)(P + 5) & 0x7FFFFFFFFFFFFFFCi64)
&& *(_DWORD *)(v37 + 40) == (_DWORD)v34 )
{
*(_BYTE *)(v37 + 26) &= ~1u;
if( *(_QWORD *)(v37 + 32) )
break;
}
v19 = !_BitScanReverse((unsigned int *)&v36, v35);
v43 = v36;
if( v19 )
goto LABEL_79;
}
if( !v37 )
{
LABEL_79:
if( (*((_DWORD *)v33 + 30) & 0x10000) == 0 )
KeBugCheckEx(0x162u, (ULONG_PTR)v33, (ULONG_PTR)(P + 5), v34, 0i64);
}
else
{
*(_BYTE *)(v37 + 32) |= 2u;
if( *(__int64 *)(v37 + 32) < 0 )
KiAbEntryRemoveFromTree(v37);
v44 = *(_DWORD *)(v37 + 88) & 0x1FFFF;
*(_DWORD *)(v37 + 88) &= 0xFFFE0000;
*(_BYTE *)(v37 + 25) &= ~1u;
*(_QWORD *)(v37 + 32) = 0i64;
v38 = (__int64)(v37 - *((_QWORD *)v33 + 100)) / 96;
if( v48 == 1 )
*((_BYTE *)v33 + 792) |= 1 << v38;
else
_InterlockedOr8((volatile signed __int8 *)v33 + 870, 1 << v38);
}
--*((_BYTE *)v33 + 794);
KiAbThreadRemoveBoosts((ULONG_PTR)v33, (__int64)(P + 5), (unsigned int *)&v44);
v19 = (*((_WORD *)v33 + 243))++ == 0xFFFF;
if( v19 && *((_ETHREAD **)v33 + 19) != (_ETHREAD *)((char *)v33 + 152) )
KiCheckForKernelApcDelivery();
v19 = (*((_WORD *)v32 + 243))++ == 0xFFFF;
if( v19 && *((_ETHREAD **)v32 + 19) != (_ETHREAD *)((char *)v32 + 152) )
KiCheckForKernelApcDelivery();
if( v45 )
ExFreePoolWithTag(P, 0);
}
if( v23 )
{
do
{
v41 = *(_QWORD *)v23;
KeSignalGate((_KGATE *)(v23 + 8), 1i64);
v23 = v41;
}
while( v41 );
KeLeaveCriticalRegionThread((__int64)v46);
}
if( v49 == 1 )
{
v39 = v47;
if( _InterlockedExchangeAdd((volatile signed __int32 *)(v47 + 280), 0xFFFFFFFF) == 1 )
KeSetEvent(*(PRKEVENT *)(v39 + 312), 0);
}
}Referenced by:
MiDeletePartialVad
MiDeleteVad