MiFinishVadDeletion
VOID __stdcall MiFinishVadDeletion(
PVOID Vad,
_MMVAD *PreviousVad,
VOID *NextVad,
VOID *DeletedHierarchyBits,
VOID *DeletedHierarchyBitsa,
_MI_DELETED_PAGE_TABLE_LEVEL_BITS *a6){
_ETHREAD *CurrentThread;
int v7;
unsigned int v10;
_EX_PUSH_LOCK *Process;
int v12;
__int64 v13;
__int64 bf_0;
unsigned int v15;
unsigned __int64 v16;
_ETHREAD *v17;
__int64 SessionId;
unsigned __int8 v19;
int v20;
bool v21;
__int64 v22;
_KLOCK_ENTRY *v23;
unsigned __int8 v24;
__int64 *v25;
__int64 **v26;
_EPROCESS *v27;
_MMSUPPORT_SHARED *p_Shared;
UINT8 CurrentIrql;
__int64 *v30;
_ETHREAD *v31;
int v32;
NTSTATUS v33;
_ETHREAD *v34;
_ETHREAD *v35;
__int64 v36;
int v37;
__int64 v38;
_KLOCK_ENTRY *v39;
__int64 v40;
__int64 v41;
__int64 *v42;
__int64 *v43;
UINT64 a3;
UINT64 v45;
_ETHREAD *Thread;
__int64 v47;
unsigned __int8 AbAllocationRegionCount;
int v49;
char v50;
v50 = (char)DeletedHierarchyBits;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v7 = *((_DWORD *)Vad + 12);
Thread = CurrentThread;
v10 = 0;
Process = (_EX_PUSH_LOCK *)CurrentThread->Tcb.ApcState.Process;
if( (v7 & 4) != 0 )
{
v12 = 1;
v49 = 1;
if( (v7 & 0x100000) == 0 )
{
v13 = *((unsigned int *)Vad + 13);
LODWORD(v13) = v13 & 0x7FFFFFFF;
if( (v13 | ((unsigned __int64)*((unsigned __int8 *)Vad + 34) << 31)) < 0x7FFFFFFFDi64 )
v10 = 1;
v12 = 1;
}
}
else
{
v12 = 0;
v49 = 0;
}
if( (unsigned __int64)NextVad <= Process[187]._bf_0 && ((unsigned __int8)DeletedHierarchyBits & 1) == 0 )
{
Process[147]._bf_0 -= (_BYTE *)NextVad - (_BYTE *)PreviousVad + 1;
v7 = *((_DWORD *)Vad + 12);
}
bf_0 = Process[210]._bf_0;
v47 = bf_0;
if( (v7 & 0x100000) == 0 && (v7 & 0x70) == 32 && (v7 & 0x200000) != 0 )
--*(_QWORD *)(bf_0 + 384);
if( v12 == 1 )
{
_InterlockedIncrement((volatile signed __int32 *)(bf_0 + 280));
v15 = *((_DWORD *)Vad + 12);
if( MiVadPageSizes[(v15 >> 18) & 3] == 16 )
{
if( (v15 & 0x100000) != 0 )
--*(_QWORD *)(bf_0 + 424);
else
--*(_QWORD *)(bf_0 + 432);
}
MiReturnVadQuota((_MMVAD *)Vad, (ULONG_PTR)Process, v10);
MiRemoveVadCharges((_MMVAD *)Vad, (ULONG_PTR)Process);
}
CurrentThread->$84F33738BEE95ACDF5C5BF1C8FDC7C8C::_bf_0 &= ~1u;
v16 = (unsigned __int64)&Process[153];
if( (_InterlockedExchangeAdd64(&Process[153]._bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock(Process + 153);
LODWORD(a3) = 0;
v17 = (_ETHREAD *)KeGetCurrentThread();
if( MiGetSystemRegionType((UINT64)&Process[153]) == 1 )
SessionId = (unsigned int)MmGetSessionIdEx(v17->Tcb.ApcState.Process);
else
SessionId = 0xFFFFFFFFi64;
--v17->Tcb.SpecialApcDisable;
v19 = ++v17->Tcb.AbAllocationRegionCount;
v20 = ((char)v17->Tcb.AbEntrySummary | (char)v17->Tcb.AbOrphanedEntrySummary) ^ 0x3F;
v21 = !_BitScanReverse((unsigned int *)&v22, v20);
if( v21 )
goto LABEL_76;
while( 1 )
{
v23 = &v17->Tcb.LockEntries[v22];
v20 &= ~(1 << v22);
if( (v23->AcquiredByte & 1) != 0
&& (v23->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 & 1) == 0
&& (v23->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 & 0x7FFFFFFFFFFFFFFCi64) == (v16 & 0x7FFFFFFFFFFFFFFCi64)
&& v23->LockState.SessionId == (_DWORD)SessionId )
{
v23->AcquiredByte &= ~1u;
if( v23->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 )
break;
}
v21 = !_BitScanReverse((unsigned int *)&v22, v20);
if( v21 )
goto LABEL_76;
}
if( !v23 )
{
LABEL_76:
if( (*(&v17->Tcb.MiscFlags + 1) & 0x10000) == 0 )
KeBugCheckEx(0x162u, v17, (PVOID)v16, (PVOID)SessionId, 0i64);
}
else
{
v23->CrossThreadReleasableAndBusyByte |= 2u;
if( v23->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 < 0 )
KiAbEntryRemoveFromTree(v23);
LODWORD(a3) = v23->BoostBitmap.AllFields & 0x1FFFF;
v23->BoostBitmap.AllFields &= 0xFFFE0000;
v23->ThreadLocalFlags &= ~1u;
v23->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 = 0i64;
v24 = 1 << (v23 - v17->Tcb.LockEntries);
if( v19 == 1 )
v17->Tcb.AbEntrySummary |= v24;
else
_InterlockedOr8((volatile signed __int8 *)&v17->Tcb.AbOrphanedEntrySummary, v24);
}
--v17->Tcb.AbAllocationRegionCount;
KiAbThreadRemoveBoosts(&v17->Tcb, (VOID *)v16, &a3);
v21 = v17->Tcb.SpecialApcDisable++ == -1;
if( v21 && ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)v17->Tcb.ApcState.ApcListHead[0].Flink != &v17->Tcb.152 )
KiCheckForKernelApcDelivery();
v21 = CurrentThread->Tcb.SpecialApcDisable++ == -1;
if( v21
&& ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)CurrentThread->Tcb.ApcState.ApcListHead[0].Flink != &CurrentThread->Tcb.152 )
{
KiCheckForKernelApcDelivery();
}
v25 = 0i64;
if( v49 == 1 )
{
v26 = (__int64 **)((char *)Vad + 56);
v27 = KeGetCurrentThread()->ApcState.Process;
if( (v27->Vm.Instance.Flags._bf_0 & 7) == 2 )
p_Shared = (_MMSUPPORT_SHARED *)((char *)&stru_140C4DB30 + 6544);
else
p_Shared = &v27->Vm.Shared;
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
ExpAcquireSpinLockExclusive((INT64 *)&p_Shared->WorkingSetLock, CurrentIrql);
p_Shared->GoodCitizenWaiting = 0;
v30 = *v26;
if( *v26 )
{
do
{
v42 = (__int64 *)*v30;
if( (v30[8] & 1) != 0 )
{
*v30 = (__int64)v25;
v25 = v30;
*v26 = v42;
}
else
{
v26 = (__int64 **)v30;
}
v30 = v42;
}
while( v42 );
}
MiUnlockWorkingSetExclusive(&v27->Vm.Instance, CurrentIrql);
v31 = Thread;
*((_QWORD *)Vad + 2) = -1i64;
if( v25 )
--v31->Tcb.KernelApcDisable;
v32 = *((_DWORD *)Vad + 12);
if( (v32 & 0x100000) == 0 && (v32 & 0x70) == 32 && (v32 & 0x400000) != 0 )
{
MiUnlockVad(v31, (_MMVAD_SHORT *)Vad);
MiDeleteImageHotPatchState((UINT64)Vad);
--v31->Tcb.SpecialApcDisable;
ExAcquirePushLockExclusiveEx((_EX_PUSH_LOCK *)Vad + 5, 0i64);
v31->$84F33738BEE95ACDF5C5BF1C8FDC7C8C::_bf_0 |= 0x80u;
}
}
if( (v50 & 2) != 0 )
{
MiUnlockAndDereferenceNestedVad((_MMVAD_SHORT *)Vad);
}
else
{
v33 = MiDereferenceVad((_MMVAD_SHORT *)Vad);
v34 = (_ETHREAD *)KeGetCurrentThread();
HIDWORD(v45) = v33;
v34->$84F33738BEE95ACDF5C5BF1C8FDC7C8C::_bf_0 &= ~0x80u;
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)Vad + 5, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((_EX_PUSH_LOCK *)Vad + 5);
LODWORD(v45) = 0;
v35 = (_ETHREAD *)KeGetCurrentThread();
if( MiGetSystemRegionType((UINT64)Vad + 40) == 1 )
v36 = (unsigned int)MmGetSessionIdEx(v35->Tcb.ApcState.Process);
else
v36 = 0xFFFFFFFFi64;
--v35->Tcb.SpecialApcDisable;
++v35->Tcb.AbAllocationRegionCount;
v37 = ((char)v35->Tcb.AbEntrySummary | (char)v35->Tcb.AbOrphanedEntrySummary) ^ 0x3F;
AbAllocationRegionCount = v35->Tcb.AbAllocationRegionCount;
v21 = !_BitScanReverse((unsigned int *)&v38, v37);
HIDWORD(a3) = v38;
if( v21 )
goto LABEL_79;
while( 1 )
{
v39 = &v35->Tcb.LockEntries[v38];
v37 &= ~(1 << v38);
if( (v39->AcquiredByte & 1) != 0
&& (v39->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 & 1) == 0
&& (v39->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 & 0x7FFFFFFFFFFFFFFCi64) == (((unsigned __int64)Vad
+ 40) & 0x7FFFFFFFFFFFFFFCi64)
&& v39->LockState.SessionId == (_DWORD)v36 )
{
v39->AcquiredByte &= ~1u;
if( v39->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 )
break;
}
v21 = !_BitScanReverse((unsigned int *)&v38, v37);
HIDWORD(a3) = v38;
if( v21 )
goto LABEL_79;
}
if( !v39 )
{
LABEL_79:
if( (*(&v35->Tcb.MiscFlags + 1) & 0x10000) == 0 )
KeBugCheckEx(0x162u, v35, (char *)Vad + 40, (PVOID)v36, 0i64);
}
else
{
v39->CrossThreadReleasableAndBusyByte |= 2u;
if( v39->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 < 0 )
KiAbEntryRemoveFromTree(v39);
LODWORD(v45) = v39->BoostBitmap.AllFields & 0x1FFFF;
v39->BoostBitmap.AllFields &= 0xFFFE0000;
v39->ThreadLocalFlags &= ~1u;
v39->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 = 0i64;
v40 = v39 - v35->Tcb.LockEntries;
if( AbAllocationRegionCount == 1 )
v35->Tcb.AbEntrySummary |= 1 << v40;
else
_InterlockedOr8((volatile signed __int8 *)&v35->Tcb.AbOrphanedEntrySummary, 1 << v40);
}
--v35->Tcb.AbAllocationRegionCount;
KiAbThreadRemoveBoosts(&v35->Tcb, (char *)Vad + 40, &v45);
v21 = v35->Tcb.SpecialApcDisable++ == -1;
if( v21 && ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)v35->Tcb.ApcState.ApcListHead[0].Flink != &v35->Tcb.152 )
KiCheckForKernelApcDelivery();
v21 = v34->Tcb.SpecialApcDisable++ == -1;
if( v21 && ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)v34->Tcb.ApcState.ApcListHead[0].Flink != &v34->Tcb.152 )
KiCheckForKernelApcDelivery();
if( HIDWORD(v45) == 1 )
ExFreePoolWithTag(Vad, 0);
}
if( v25 )
{
do
{
v43 = (__int64 *)*v25;
KeSignalGate((_KGATE *)(v25 + 1), 1i64);
v25 = v43;
}
while( v43 );
KeLeaveCriticalRegionThread(&Thread->Tcb);
}
if( v49 == 1 )
{
v41 = v47;
if( _InterlockedExchangeAdd((volatile signed __int32 *)(v47 + 280), 0xFFFFFFFF) == 1 )
KeSetEvent(*(PRKEVENT *)(v41 + 312), 0, 0);
}
}Referenced by:
MiDeletePartialVad
MiDeleteVad