MiDeleteVad
VOID __stdcall MiDeleteVad(_MMVAD *Vad, UINT64 Flags){
int v2;
unsigned int v4;
_CONTROL_AREA *ControlArea;
int v6;
_ETHREAD *CurrentThread;
INT64 Process;
unsigned __int64 v9;
union {unsigned int LongFlags;_MMVAD_FLAGS VadFlags;_MM_PRIVATE_VAD_FLAGS PrivateVadFlags;_MM_GRAPHICS_VAD_FLAGS GraphicsVadFlags;_MM_SHARED_VAD_FLAGS SharedVadFlags;volatile unsigned int VolatileVadLong;} v10;
union {unsigned int LongFlags;_MMVAD_FLAGS VadFlags;_MM_PRIVATE_VAD_FLAGS PrivateVadFlags;_MM_GRAPHICS_VAD_FLAGS GraphicsVadFlags;_MM_SHARED_VAD_FLAGS SharedVadFlags;volatile unsigned int VolatileVadLong;} v11;
_FILE_OBJECT *FileObject;
union {unsigned int LongFlags;_MMVAD_FLAGS VadFlags;_MM_PRIVATE_VAD_FLAGS PrivateVadFlags;_MM_GRAPHICS_VAD_FLAGS GraphicsVadFlags;_MM_SHARED_VAD_FLAGS SharedVadFlags;volatile unsigned int VolatileVadLong;} v13;
__int64 LongFlags1;
INT64 *v15;
UINT8 CurrentIrql;
__int64 v17;
bool v18;
union {unsigned int LongFlags;_MMVAD_FLAGS VadFlags;_MM_PRIVATE_VAD_FLAGS PrivateVadFlags;_MM_GRAPHICS_VAD_FLAGS GraphicsVadFlags;_MM_SHARED_VAD_FLAGS SharedVadFlags;volatile unsigned int VolatileVadLong;} v19;
int v20;
int v21;
unsigned int v22;
__int128 *v23;
_EPROCESS *v24;
INT64 v25;
__int64 v26;
unsigned __int64 v27;
union {unsigned int LongFlags;_MMVAD_FLAGS VadFlags;_MM_PRIVATE_VAD_FLAGS PrivateVadFlags;_MM_GRAPHICS_VAD_FLAGS GraphicsVadFlags;_MM_SHARED_VAD_FLAGS SharedVadFlags;volatile unsigned int VolatileVadLong;} v28;
int v29;
union {unsigned int LongFlags;_MMVAD_FLAGS VadFlags;_MM_PRIVATE_VAD_FLAGS PrivateVadFlags;_MM_GRAPHICS_VAD_FLAGS GraphicsVadFlags;_MM_SHARED_VAD_FLAGS SharedVadFlags;volatile unsigned int VolatileVadLong;} v30;
int v31;
int v32;
int v33;
_ETHREAD *v34;
VOID *v35;
_ETHREAD *v36;
__int64 v37;
unsigned __int8 AbEntrySummary;
__int64 AbOrphanedEntrySummary;
__int64 v40;
NTSTATUS SessionId;
int v42;
INT64 *v43;
_MMVAD *j;
_MMVAD *v45;
_MMVAD *i;
_MMVAD *ExtraCreateInfo;
_MMVAD *v48;
_MMVAD *v49;
_EPROCESS *v50;
int v51;
__int64 v52;
unsigned int v53;
_LIST_ENTRY *p_ViewLinks;
_CONTROL_AREA *v55;
_ETHREAD *v56;
_EX_PUSH_LOCK *p_FileObjectLock;
_LIST_ENTRY *Flink;
_LIST_ENTRY *Blink;
_ETHREAD *v60;
UINT64 v61;
unsigned int v62;
VOID *v63;
_SUBSECTION *v64;
_SUBSECTION *v65;
_MI_CROSS_PARTITION_CHARGES *v66;
_BOOL8 v67;
UINT8 v68;
UINT64 v69;
_MMVAD *NextVad;
_MMVAD *Vada;
_MMVAD *StartingAddress;
VOID *EndingAddress;
char a3[12];
_ETHREAD *v75;
INT64 v76;
_CONTROL_AREA **v77;
_EX_PUSH_LOCK *PushLock;
__int128 v79;
__int128 v80;
ULONG_PTR QuotaCharge[4];
UINT64 v82;
UINT8 v83;
int v85;
_MI_DELETED_PAGE_TABLE_LEVEL_BITS DeletedHierarchyBits;
v85 = v2;
DeletedHierarchyBits = 0;
v79 = 0i64;
v4 = 0;
ControlArea = 0i64;
v80 = 0i64;
v6 = 64;
*(_OWORD *)QuotaCharge = 0i64;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
Process = (INT64)CurrentThread->Tcb.ApcState.Process;
StartingAddress = (_MMVAD *)((Vad->Core.StartingVpn | ((unsigned __int64)Vad->Core.StartingVpnHigh << 32)) << 12);
v9 = Vad->Core.EndingVpn | ((unsigned __int64)Vad->Core.EndingVpnHigh << 32);
v75 = CurrentThread;
v10.LongFlags = (unsigned int)Vad->Core.u;
*(_QWORD *)&a3[4] = Process + 1664;
v77 = 0i64;
v76 = 0i64;
EndingAddress = (VOID *)((v9 << 12) | 0xFFF);
if( (v10.LongFlags & 0x100000) != 0 && ((v10.LongFlags & 0x400000) != 0 || (v10.LongFlags & 0xC0000) >= 0x80000)
|| MiVadMapsLargeImage(Vad) )
{
v4 = v6;
}
v11.LongFlags = (unsigned int)Vad->Core.u;
if( (v11.LongFlags & 0x100000) == 0 )
{
FileObject = Vad->FileObject;
if( FileObject )
{
HalPutDmaAdapter((PADAPTER_OBJECT)FileObject);
v11.LongFlags = (unsigned int)Vad->Core.u;
}
}
LOBYTE(v13.LongFlags) = v11.LongFlags;
if( (v11.LongFlags & 0x100000) != 0 && (v11.LongFlags & 0x1000000) == 0 && (v11.LongFlags & 0x2000000) != 0 )
{
MiDeleteEnclavePages((_MMVAD_SHORT *)Process);
v13.LongFlags = (unsigned int)Vad->Core.u;
}
if( (v13.LongFlags & 0x70) == 48 )
*(_QWORD *)QuotaCharge = MiRemoveUserPhysicalPagesView((INT64)Vad);
LongFlags1 = Vad->Core.u1.LongFlags1;
LODWORD(LongFlags1) = LongFlags1 & 0x7FFFFFFF;
if( (((unsigned __int64)Vad->Core.CommitChargeHigh << 31) | LongFlags1) == 0x7FFFFFFFDi64
&& Vad->Core.VadNode.ParentValue == -2i64 )
{
v4 |= 0x80u;
}
--CurrentThread->Tcb.SpecialApcDisable;
PushLock = (_EX_PUSH_LOCK *)(Process + 1232);
ExAcquirePushLockExclusiveEx((_EX_PUSH_LOCK *)(Process + 1232), 0i64);
if( (*(_BYTE *)(Process + 1848) & 7) == 2 )
v15 = (INT64 *)((char *)&stru_140C4DB30 + 6544);
else
v15 = (INT64 *)(Process + 1856);
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
ExpAcquireSpinLockExclusive(v15, CurrentIrql);
*((_DWORD *)v15 + 1) = 0;
MiSetVadFlags((_MI_PARTITION *)Vad, 2ui64, 1);
MiUnlockWorkingSetExclusive(*(_MMSUPPORT_INSTANCE **)&a3[4], CurrentIrql);
if( (_InterlockedExchangeAdd64(&PushLock->_bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock(PushLock);
KeAbPostRelease(PushLock);
v17 = (__int64)v75;
v18 = v75->Tcb.SpecialApcDisable++ == -1;
if( v18 && *(_QWORD *)(v17 + 152) != v17 + 152 )
KiCheckForKernelApcDelivery();
v19.LongFlags = (unsigned int)Vad->Core.u;
if( (v19.LongFlags & 0x100000) != 0 )
{
v20 = 0;
if( (v19.LongFlags & 0x70) == 48 && ((v19.LongFlags & 0x1000000) != 0 || (v19.LongFlags & 0x2000000) == 0) )
{
v20 = 16;
}
else if( (v19.LongFlags & 0x70) == 16 )
{
v20 = 32;
if( (v19.LongFlags & 0x8000000) != 0 )
v20 = 64;
}
if( (v19.LongFlags & 0x70) == 64 )
{
v20 = 8;
}
else if( (v19.LongFlags & 0x1000000) == 0 && (v19.LongFlags & 0x4000000) != 0 )
{
v20 |= 0x400u;
}
}
else
{
v20 = ((v85 >> 31) & 1) + 2;
if( (v85 & 1) != 0 )
v20 |= 4u;
}
if( (v19.LongFlags & 0x100000) != 0 && ((v19.LongFlags & 0x400000) != 0 || (v19.LongFlags & 0xC0000) >= 0x80000)
|| MiVadMapsLargeImage(Vad) )
{
v20 |= 0x800u;
}
v21 = v20 | 0x1000;
v22 = v4;
if( (Vad->Core.u.LongFlags & 0x1100000) != 17825792 )
v21 = v20;
if( v4 < 0x80 )
{
v23 = &v79;
LOBYTE(v23) = 17;
v24 = KeGetCurrentThread()->ApcState.Process;
LODWORD(Vada) = v21 | 0x80;
LODWORD(NextVad) = 0;
MiDeletePagablePteRange((_EPROCESS *)&v24->Vm, v23);
if( *((_QWORD *)&v80 + 1) )
_InterlockedExchangeAdd64((volatile signed __int64 *)&v24->NumberOfPrivatePages, -*((_QWORD *)&v80 + 1));
if( (v21 & 0x800) != 0 )
{
v25 = *(_QWORD *)&QuotaCharge[2];
if( *(_QWORD *)&QuotaCharge[2] )
{
*(_QWORD *)&QuotaCharge[2] = 0i64;
if( !MiVadCommitCrossPartition((INT64)Vad) )
{
v26 = Vad->Core.u1.LongFlags1;
LODWORD(v26) = v26 & 0x7FFFFFFF;
v27 = (((unsigned __int64)Vad->Core.CommitChargeHigh << 31) | v26) - v25;
Vad->Core.u1.LongFlags1 ^= (Vad->Core.u1.LongFlags1 ^ v27) & 0x7FFFFFFF;
Vad->Core.CommitChargeHigh = v27 >> 31;
MiReturnFullProcessCharges(Process, v25);
MiReturnProcessPhysicalPages(Process, v25);
}
}
}
v22 = v4;
}
if( (v21 & 2) != 0 )
{
v28.LongFlags = (unsigned int)Vad->Core.u;
ControlArea = Vad->Subsection->ControlArea;
if( (v28.LongFlags & 0x70) == 32 )
{
if( (Vad->u2.LongFlags2 & 0x1000000) != 0 )
v4 |= 0x18u;
}
else if( ControlArea->FilePointer.Value )
{
if( (v28.LongFlags & 0xF80) == 512 || (v28.LongFlags & 0xF80) == 768 )
_InterlockedDecrement(&ControlArea->u2.WritableUserReferences);
MiGetProtoPteAddress();
v4 = v22 | 0x20;
if( (Vad->u2.LongFlags2 & 0x1000000) == 0 )
v4 = v22;
MiGetProtoPteAddress();
}
v29 = v4;
if( (v4 & 8) == 0 )
{
if( (Vad->Core.u.LongFlags & 0x70) != 80 )
{
MiDrainSystemAccessLog(*(_MMSUPPORT_INSTANCE **)&a3[4]);
v30.LongFlags = (unsigned int)Vad->Core.u;
if( (v30.LongFlags & 0x70) == 32 )
{
v31 = v4 | 2;
if( (ControlArea->u.LongFlags & 0x4000000) == 0 )
v31 = v29;
v4 = v31 | 4;
}
else if( (v30.LongFlags & 0x100000) == 0 && !ControlArea->FilePointer.Value )
{
MiGetProtoPteAddress();
MiGetProtoPteAddress();
}
}
v32 = v4;
v33 = v4 | 1;
if( (__int64)Vad->u4.ExtendedInfo >= 0 )
v33 = v32;
v4 = v33 | 8;
}
}
v34 = (_ETHREAD *)KeGetCurrentThread();
--v34->Tcb.SpecialApcDisable;
*(_DWORD *)a3 = 0;
v35 = (VOID *)(Process + 1224);
v36 = (_ETHREAD *)KeGetCurrentThread();
v82 = Process + 1224;
--v36->Tcb.SpecialApcDisable;
if( ++v36->Tcb.AbAllocationRegionCount != 1 )
{
_interlockedbittestandset((volatile signed __int32 *)&v36->Tcb.116 + 1, 0x10u);
v37 = 0i64;
goto LABEL_92;
}
AbEntrySummary = v36->Tcb.AbEntrySummary;
if( AbEntrySummary )
goto LABEL_84;
if( v36->Tcb.AbOrphanedEntrySummary )
{
AbOrphanedEntrySummary = v36->Tcb.AbOrphanedEntrySummary;
v36->Tcb.AbOrphanedEntrySummary = 0;
AbEntrySummary = v36->Tcb.AbEntrySummary | AbOrphanedEntrySummary;
LABEL_84:
_BitScanForward((unsigned int *)&v40, AbEntrySummary);
v36->Tcb.AbEntrySummary = AbEntrySummary & ~(1 << v40);
v37 = (__int64)&v36->Tcb.LockEntries[v40];
v35 = (VOID *)(Process + 1224);
goto LABEL_85;
}
v37 = 0i64;
LABEL_85:
if( v37 )
{
if( MiGetSystemRegionType((UINT64)v35) == 1 )
SessionId = MmGetSessionIdEx(v36->Tcb.ApcState.Process);
else
SessionId = -1;
*(_DWORD *)(v37 + 40) = SessionId;
v35 = (VOID *)(Process + 1224);
*(_QWORD *)(v37 + 32) = v82 & 0x7FFFFFFFFFFFFFFCi64;
}
else
{
_interlockedbittestandset((volatile signed __int32 *)&v36->Tcb.116 + 1, 0x10u);
}
LABEL_92:
--v36->Tcb.AbAllocationRegionCount;
KiAbThreadRemoveBoosts(&v36->Tcb, v35, (UINT64 *)a3);
v18 = v36->Tcb.SpecialApcDisable++ == -1;
if( v18 && ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)v36->Tcb.ApcState.ApcListHead[0].Flink != &v36->Tcb.152 )
KiCheckForKernelApcDelivery();
if( _interlockedbittestandset64((volatile signed __int32 *)v82, 0i64) )
{
if( v37 )
KeAbPostReleaseEx((VOID *)v82, (VOID *)v37);
v42 = 0;
}
else
{
if( v37 )
*(_BYTE *)(v37 + 26) |= 1u;
v42 = 1;
}
if( v42 )
{
v34->$84F33738BEE95ACDF5C5BF1C8FDC7C8C::_bf_0 |= 1u;
}
else
{
MiUnlockVad(v34, &Vad->Core);
--v34->Tcb.SpecialApcDisable;
ExAcquirePushLockExclusiveEx((_EX_PUSH_LOCK *)v82, 0i64);
v34->$84F33738BEE95ACDF5C5BF1C8FDC7C8C::_bf_0 |= 1u;
--v34->Tcb.SpecialApcDisable;
ExAcquirePushLockExclusiveEx(&Vad->Core.PushLock, 0i64);
v34->$84F33738BEE95ACDF5C5BF1C8FDC7C8C::_bf_0 |= 0x80u;
KiLeaveGuardedRegionUnsafe((__int64)v34);
}
if( v4 >= 0x80 )
{
v50 = (_EPROCESS *)Process;
}
else
{
--v75->Tcb.SpecialApcDisable;
ExAcquirePushLockExclusiveEx(PushLock, 0i64);
v43 = (INT64 *)((char *)&stru_140C4DB30 + 6544);
if( (*(_BYTE *)(*(_QWORD *)&a3[4] + 184i64) & 7) != 2 )
v43 = (INT64 *)(*(_QWORD *)&a3[4] + 192i64);
v83 = KeGetCurrentIrql();
__writecr8(2ui64);
ExpAcquireSpinLockExclusive(v43, v83);
*((_DWORD *)v43 + 1) = 0;
MiCaptureDeleteHierarchy(StartingAddress, EndingAddress, v83, &DeletedHierarchyBits);
j = (_MMVAD *)Vad->Core.NextVad;
v45 = Vad;
if( Vad->Core.NextVad )
{
for( i = (_MMVAD *)j->Core.ExtraCreateInfo; i; i = (_MMVAD *)i->Core.ExtraCreateInfo )
j = i;
}
else
{
for( j = (_MMVAD *)(Vad->Core.VadNode.ParentValue & 0xFFFFFFFFFFFFFFFCui64);
j;
j = (_MMVAD *)(j->Core.VadNode.ParentValue & 0xFFFFFFFFFFFFFFFCui64) )
{
if( j->Core.ExtraCreateInfo == v45 )
break;
v45 = j;
}
}
ExtraCreateInfo = (_MMVAD *)Vad->Core.ExtraCreateInfo;
v48 = Vad;
if( ExtraCreateInfo )
{
v49 = (_MMVAD *)ExtraCreateInfo->Core.NextVad;
if( ExtraCreateInfo->Core.NextVad )
{
do
{
ExtraCreateInfo = v49;
v49 = (_MMVAD *)v49->Core.NextVad;
}
while( v49 );
}
}
else
{
for( ExtraCreateInfo = (_MMVAD *)(Vad->Core.VadNode.ParentValue & 0xFFFFFFFFFFFFFFFCui64);
ExtraCreateInfo;
ExtraCreateInfo = (_MMVAD *)(ExtraCreateInfo->Core.VadNode.ParentValue & 0xFFFFFFFFFFFFFFFCui64) )
{
if( (_MMVAD *)ExtraCreateInfo->Core.NextVad == v48 )
break;
v48 = ExtraCreateInfo;
}
}
v50 = (_EPROCESS *)Process;
RtlAvlRemoveNode((UINT64 *)(Process + 2008), (INT64 *)Vad);
if( *(_MMVAD **)(Process + 2016) == Vad )
*(_QWORD *)(Process + 2016) = *(_QWORD *)(Process + 2008);
--*(_QWORD *)(Process + 2024);
Vad->Core.VadNode.ParentValue = -2i64;
LOBYTE(v51) = MiIsVadLargePrivate((INT64)Vad);
if( v51 && (unsigned __int64)MiVadPageSizes[(Vad->Core.u.LongFlags >> 18) & 3] >= 0x200 )
--*(_DWORD *)(Process + 2140);
MiUnlockWorkingSetExclusive((_MMSUPPORT_INSTANCE *)(Process + 1664), v83);
if( !Flags )
MiClearVadBits(StartingAddress, EndingAddress, j, ExtraCreateInfo);
MiReturnPageTablePageCommitment(
StartingAddress,
EndingAddress,
Process,
j,
ExtraCreateInfo,
Vad,
&DeletedHierarchyBits);
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)(Process + 1232), 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((_EX_PUSH_LOCK *)(Process + 1232));
KeAbPostRelease((VOID *)(Process + 1232));
v52 = (__int64)v75;
v18 = v75->Tcb.SpecialApcDisable++ == -1;
if( v18 && *(_QWORD *)(v52 + 152) != v52 + 152 )
KiCheckForKernelApcDelivery();
if( Flags )
{
MiReInsertPlaceholderVad(Flags);
MiUnlockNestedVad((_MMVAD_SHORT *)Flags);
}
}
Vad->Core.ExtraCreateInfo = (void *)*((_QWORD *)&v79 + 1);
Vad->Core.NextVad = (_MMVAD_SHORT *)v80;
if( (v4 & 1) != 0 )
MiDereferenceExtendInfo(Vad, ControlArea);
if( (v4 & 8) != 0 )
{
if( (v4 & 2) != 0 )
{
v53 = MmGetSessionIdEx(v50);
MiDereferencePerSessionProtos(ControlArea, v53);
}
if( (v4 & 4) != 0 && (MiControlAreaRequiresCharge((INT64)ControlArea) & 0xFFFFFFFD) == 0 )
MiReturnCrossPartitionControlAreaCharges((INT64)ControlArea);
MiRemoveSharedCommitNode(ControlArea, v50, 0i64);
p_ViewLinks = &Vad->ViewLinks;
v55 = Vad->Subsection->ControlArea;
v56 = (_ETHREAD *)KeGetCurrentThread();
--v56->Tcb.SpecialApcDisable;
p_FileObjectLock = &v55->FileObjectLock;
ExAcquirePushLockExclusiveEx(&v55->FileObjectLock, 0i64);
if( (v55->u.LongFlags & 0x400) == 0 )
{
Flink = p_ViewLinks->Flink;
Blink = Vad->ViewLinks.Blink;
if( p_ViewLinks->Flink->Blink != p_ViewLinks || Blink->Flink != p_ViewLinks )
__fastfail(3u);
Blink->Flink = Flink;
Flink->Blink = Blink;
}
v60 = (_ETHREAD *)KeGetCurrentThread();
if( (_InterlockedExchangeAdd64(&p_FileObjectLock->_bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock(p_FileObjectLock);
KeAbPostRelease(p_FileObjectLock);
KiLeaveGuardedRegionUnsafe((__int64)v60);
}
v61 = 0i64;
v62 = 0;
if( Flags || v4 >= 0x80 )
v62 = 1;
v63 = (VOID *)(v62 | 2);
if( (v85 & 0x40000000) == 0 )
v63 = (VOID *)v62;
MiFinishVadDeletion(Vad, StartingAddress, EndingAddress, v63, NextVad, (_MI_DELETED_PAGE_TABLE_LEVEL_BITS *)Vada);
if( ControlArea )
{
if( (v4 & 0x10) != 0 )
{
MiDereferenceControlArea(ControlArea);
}
else
{
v64 = (_SUBSECTION *)v77;
v65 = (_SUBSECTION *)v76;
if( v77 && (v4 & 0x20) != 0 )
MiDecrementLargeSubsections(v77, v76);
v66 = 0i64;
v67 = ControlArea->FilePointer.Value != 0;
v68 = ExAcquireSpinLockExclusive((INT64 *)&ControlArea->ControlAreaLock);
if( v64 )
{
LODWORD(v69) = MiDecrementSubsections(v64, v65, 8ui64);
v61 = v69;
}
--ControlArea->NumberOfMappedViews;
--ControlArea->NumberOfUserReferences;
if( v61 )
v66 = *(_MI_CROSS_PARTITION_CHARGES **)(*(&stru_140C4DB30 + 267) + 8i64 * (ControlArea->u1.Flags._bf_0 & 0x3FF));
MiCheckControlArea(ControlArea, v68);
if( v61 )
MiReturnCrossPartitionSectionCharges(v66, v67, v61);
}
}
}Referenced by:
MiCleanVad
MiCoalescePlaceholderAllocations
MiCreateEnclave
MiDeleteInsertedCloneVads
MiFinishPlaceholderVadReplacement
MiFreeToSubAllocatedRegion
MiFreeVadRange
MiMapLockedPagesInUserSpace
MiMapViewOfPhysicalSection
MiReserveUserMemory
MiUnmapLockedPagesInUserSpace
MiUnmapVad
MiUnmapViewOfSection