MiUnlockAndDereferenceVad
void __fastcall MiUnlockAndDereferenceVad(PVOID P){
signed __int32 v2;
unsigned int SessionId;
BOOL v4;
_ETHREAD *CurrentThread;
_ETHREAD *v6;
int v7;
bool v8;
__int64 v9;
unsigned __int64 v10;
__int64 v11;
char v12;
int v13;
v2 = _InterlockedDecrement((volatile signed __int32 *)P + 9);
SessionId = -1;
if( v2 == -1 )
__fastfail(0xEu);
v4 = !v2 && (*((_DWORD *)P + 12) & 4) != 0;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
*((_BYTE *)CurrentThread + 1304) &= ~0x80u;
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)P + 5, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((volatile INT64 *)P + 5);
v13 = 0;
v6 = (_ETHREAD *)KeGetCurrentThread();
if( (unsigned int)MiGetSystemRegionType((UINT64)P + 40) == 1 )
SessionId = MmGetSessionIdEx(*((_QWORD *)v6 + 23));
--*((_WORD *)v6 + 243);
++*((_BYTE *)v6 + 794);
v7 = (*((char *)v6 + 792) | *((char *)v6 + 870)) ^ 0x3F;
v12 = *((_BYTE *)v6 + 794);
v8 = !_BitScanReverse((unsigned int *)&v9, v7);
if( v8 )
goto LABEL_30;
while( 1 )
{
v10 = *((_QWORD *)v6 + 100) + 96 * v9;
v7 &= ~(1 << v9);
if( (*(_BYTE *)(v10 + 26) & 1) != 0
&& (*(_DWORD *)(v10 + 32) & 1) == 0
&& (*(_QWORD *)(v10 + 32) & 0x7FFFFFFFFFFFFFFCi64) == (((unsigned __int64)P + 40) & 0x7FFFFFFFFFFFFFFCi64)
&& *(_DWORD *)(v10 + 40) == SessionId )
{
*(_BYTE *)(v10 + 26) &= ~1u;
if( *(_QWORD *)(v10 + 32) )
break;
}
v8 = !_BitScanReverse((unsigned int *)&v9, v7);
if( v8 )
goto LABEL_30;
}
if( !v10 )
{
LABEL_30:
if( (*((_DWORD *)v6 + 30) & 0x10000) == 0 )
KeBugCheckEx(0x162u, (ULONG_PTR)v6, (ULONG_PTR)P + 40, SessionId, 0i64);
}
else
{
*(_BYTE *)(v10 + 32) |= 2u;
if( *(__int64 *)(v10 + 32) < 0 )
KiAbEntryRemoveFromTree(v10);
v13 = *(_DWORD *)(v10 + 88) & 0x1FFFF;
*(_DWORD *)(v10 + 88) &= 0xFFFE0000;
*(_BYTE *)(v10 + 25) &= ~1u;
*(_QWORD *)(v10 + 32) = 0i64;
v11 = (__int64)(v10 - *((_QWORD *)v6 + 100)) / 96;
if( v12 == 1 )
*((_BYTE *)v6 + 792) |= 1 << v11;
else
_InterlockedOr8((volatile signed __int8 *)v6 + 870, 1 << v11);
}
--*((_BYTE *)v6 + 794);
KiAbThreadRemoveBoosts((ULONG_PTR)v6, (__int64)P + 40, (unsigned int *)&v13);
v8 = (*((_WORD *)v6 + 243))++ == 0xFFFF;
if( v8 && *((_ETHREAD **)v6 + 19) != (_ETHREAD *)((char *)v6 + 152) )
KiCheckForKernelApcDelivery();
v8 = (*((_WORD *)CurrentThread + 243))++ == 0xFFFF;
if( v8 && *((_ETHREAD **)CurrentThread + 19) != (_ETHREAD *)((char *)CurrentThread + 152) )
KiCheckForKernelApcDelivery();
if( v4 )
ExFreePoolWithTag(P, 0);
}Referenced by:
MiAllocateFromSubAllocatedRegion
MiAllocateVirtualMemory
MiCfgInitializeProcess
MiCfgMarkValidEntries
MiCreateEnclave
MiDeleteAllHardwareEnclaves
MiDeprioritizeVad
MiFreeToSubAllocatedRegion
MiInitializeEnclave
MiLoadSectionIntoVsmEnclave
MiLockVadRange
MiMapLockedPagesInUserSpace
MiMapViewOfDataSection
MiObtainReferencedSecureVad
MiObtainReferencedVadEx
MiPerformImageHotPatch
MiProbeAndLockPages
MiProbeAndLockPrepare
MiProcessVaRangesInfoClass
MiReserveUserMemory
MiScrubProcessLargePages
MiSetImageHotPatchAllowed
MiUnmapLockedPagesInUserSpace
MiUnmapViewOfSection
MmFreeVirtualMemory
MmProtectVirtualMemory
MmQueryVirtualMemory
MmRotatePhysicalView
MmSecureVirtualMemoryAgainstWrites
MmSecureVirtualMemoryEx
MmSelectVsmEnclaveByAddress
MmSetGraphicsPtes
MmStoreAllocateVirtualMemory
MmUnsecureVirtualMemory
MmUpdateUserShadowStackValue
NtGetWriteWatch
NtLoadEnclaveData
NtResetWriteWatch
NtTerminateEnclave