MiDecommitHardwareEnclavePages
NTSTATUS __stdcall MiDecommitHardwareEnclavePages(INT64 a1, INT64 a2, INT64 r8_0, UINT64 a4, INT64 a5){
_MMSUPPORT_INSTANCE *v7;
char *v8;
unsigned int v9;
unsigned int v10;
UINT64 v11;
UINT8 v12;
unsigned int v13;
_MMPTE *PteBase;
__int64 v15;
VOID *v16;
unsigned __int64 v17;
int v18;
int v19;
UINT64 v20;
UINT8 v21;
UINT64 v22;
UINT64 v23;
__int64 v24;
UINT64 v25;
NTSTATUS v26;
int v27;
int v28;
__int64 v29;
unsigned int v30;
unsigned int v31;
__int64 v32;
unsigned int v33;
__int64 *v34;
__int64 i;
_MMSUPPORT_INSTANCE *v36;
UINT64 v37;
NTSTATUS v38;
unsigned __int64 v39;
_ETHREAD *v40;
__int64 SessionId;
unsigned __int8 v42;
_KLOCK_ENTRY *v43;
int v44;
__int64 v45;
bool v46;
__int64 v47;
__int64 v48;
unsigned int v49;
volatile signed __int32 *v50;
__int64 v51;
int v52;
UINT64 Flags;
UINT8 WsIrql;
int WsIrql_4;
unsigned int v57;
int v58;
__int64 v59;
UINT64 a3;
VOID *PageTableVirtualAddress;
char *v62;
UINT64 v63;
INT64 v64;
int v65;
PVOID BugCheckParameter2;
unsigned __int64 v67;
INT64 v68;
__int64 v69;
INT64 v70;
INT64 v71;
INT64 v72;
_ETHREAD *CurrentThread;
_MI_TB_FLUSH_LIST TbFlushList[48];
PageTableVirtualAddress = (VOID *)r8_0;
v64 = a2;
v70 = a2;
v71 = r8_0;
v63 = 0i64;
memset(TbFlushList, 0i64, 0xB8u);
v68 = a2;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v7 = (_MMSUPPORT_INSTANCE *)(a1 + 1664);
v72 = (INT64)v7;
v8 = 0i64;
v62 = 0i64;
v9 = 0;
v59 = 0i64;
v69 = 0i64;
TbFlushList[0] = 1;
LOWORD(TbFlushList[1]) = 0;
*(_QWORD *)&TbFlushList[4] = 0i64;
TbFlushList[2] = 20;
*(_QWORD *)&TbFlushList[6] = 0i64;
v10 = 2;
v58 = 2;
MiLockWorkingSetShared();
WsIrql = v12;
v13 = 0;
while( 1 )
{
PteBase = MmGetPteBase();
v57 = v13;
if( v13 >= v10 )
break;
if( v13 == 2 )
{
v15 = (_QWORD)PteBase << 25;
KeTrackEnclaveTbFlush();
MiInsertTbFlushEntry(TbFlushList, (VOID *)((((_QWORD)PageTableVirtualAddress << 25) - v15) >> 16), 1ui64, 0i64);
MiFlushTbList(TbFlushList);
}
v16 = PageTableVirtualAddress;
v17 = (unsigned __int64)PageTableVirtualAddress;
v67 = (unsigned __int64)PageTableVirtualAddress;
while( v17 <= a4 )
{
if( (v17 & 0x78) != 0 || (VOID *)v17 == v16 )
goto LABEL_18;
v18 = 0;
LOBYTE(v19) = MiWorkingSetIsContended((INT64)v7);
if( v19
|| (unsigned int)KeShouldYieldProcessor()
|| v8 && (unsigned int)MiPageTableLockIsContended((__int64)v7, (UINT64)v8) )
{
v18 = 1;
}
if( v18 != 1 )
{
LABEL_18:
v21 = WsIrql;
}
else
{
if( v8 )
{
MiFlushTbList(TbFlushList);
MiUnlockPageTableInternal((INT64)v7, (UINT64)v8);
v8 = 0i64;
v62 = 0i64;
}
v21 = WsIrql;
LOBYTE(v20) = WsIrql;
MiUnlockWorkingSetShared(v7, v20);
MiLockWorkingSetShared();
}
if( v8 )
{
if( (v17 & 0xFFF) != 0 )
goto LABEL_23;
MiFlushTbList(TbFlushList);
MiUnlockPageTableInternal((INT64)v7, (UINT64)v8);
}
v8 = (char *)MmGetPteBase() + ((v17 >> 9) & 0x7FFFFFFFF8i64);
v62 = v8;
LODWORD(Flags) = 0;
MiMakeSystemAddressValid((VOID *)v17, 0i64, (*(_DWORD *)(v68 + 48) >> 12) & 0x3F, v21, Flags);
LABEL_23:
LODWORD(v22) = MI_READ_PTE_LOCK_FREE(v17);
v23 = v22;
v63 = v22;
if( !v22 )
goto LABEL_51;
v24 = (__int64)((v17 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16;
BugCheckParameter2 = (PVOID)v24;
if( v57 )
{
if( v57 == 1 )
{
v26 = KeRemoveEnclavePage((PVOID)v24);
v27 = v26;
WsIrql_4 = v26;
if( v26 < 0 )
{
if( v26 != -1073741757 || (_DWORD)a5 )
{
v27 = 0;
}
else
{
if( !v59 )
{
while( 1 )
{
v28 = **(&stru_140C4DB30 + 532);
v29 = *(_QWORD *)(*(&stru_140C4DB30 + 532) + 8i64);
v30 = (*(_DWORD *)(*(&stru_140C4DB30 + 532) + 8i64) & 4) != 0i64 ? 0x20 : 0;
v65 = 0;
v31 = v30 + v28 - 1;
v32 = v29 - ((v29 & 4) != 0 ? 4 : 0);
if( v28 )
{
v34 = (__int64 *)(v32 + 8 * ((unsigned __int64)v30 >> 6));
for( i = *v34 | ((1i64 << v30) - 1); i == -1; i = *v34 )
{
if( (unsigned __int64)++v34 > v32 + 8 * ((unsigned __int64)v31 >> 6) )
goto LABEL_32;
}
_BitScanForward64((unsigned __int64 *)&i, ~i);
v65 = i;
v33 = i + ((unsigned int)(((__int64)v34 - v32) >> 3) << 6);
if( v33 > v31 )
v33 = -1;
}
else
{
LABEL_32:
v33 = -1;
}
v9 = v33 - v30;
if( v33 == -1 )
v9 = -1;
if( v9 == -1 )
break;
if( RtlInterlockedSetClearRun(*(&stru_140C4DB30 + 532), v9, 1ui64) )
goto LABEL_45;
}
MiFlushTbList(TbFlushList);
v36 = (_MMSUPPORT_INSTANCE *)v72;
MiUnlockPageTableInternal(v72, (UINT64)v8);
LOBYTE(v37) = WsIrql;
MiUnlockWorkingSetShared(v36, v37);
--CurrentThread->Tcb.SpecialApcDisable;
ExAcquirePushLockExclusiveEx((_EX_PUSH_LOCK *)&stru_140C4DB30 + 533, 0i64);
v9 = 0;
MiLockWorkingSetShared();
LODWORD(Flags) = 0;
MiMakeSystemAddressValid((VOID *)v17, 0i64, (*(_DWORD *)(v68 + 48) >> 12) & 0x3F, WsIrql, Flags);
LABEL_45:
v59 = *(&stru_140C4DB30 + 531) + 8 * v9;
++v58;
v27 = WsIrql_4;
}
KeBlockEnclavePage();
}
}
if( v27 < 0 )
goto LABEL_50;
}
else
{
do
{
ExAcquireSpinLockShared((INT64 *)&stru_140C4DB30 + 534);
v38 = KeOutPageEnclavePage(v24, *(_QWORD *)(v64 + 88));
ExReleaseSpinLockSharedFromDpcLevel((PEX_SPIN_LOCK)&stru_140C4DB30 + 1068);
}
while( v38 == -1073741802 );
if( v38 < 0 )
KeBugCheckEx(0x1Au, (PVOID)0x18011713, (PVOID)v24, (PVOID)v38, 0i64);
}
MiDeleteEnclavePage((_MMPTE *)v17, (_MI_TB_FLUSH_LIST *)1);
}
else
{
MiPteInShadowRange((UINT64)&v63);
LODWORD(v25) = MiMakeValidPte((_XSTATE_CONFIGURATION *)v17, (v23 >> 12) & 0xFFFFFFFFFi64, 3221225476i64);
v63 = v25;
MiWriteValidPteNewProtection((INT64 *)v17, v25);
}
LABEL_50:
MiInsertTbFlushEntry(TbFlushList, (VOID *)v24, 1ui64, 0i64);
v7 = (_MMSUPPORT_INSTANCE *)v72;
LABEL_51:
v17 += 8i64;
v67 = v17;
v16 = PageTableVirtualAddress;
}
MiFlushTbList(TbFlushList);
if( v8 )
{
MiUnlockPageTableInternal((INT64)v7, (UINT64)v8);
v8 = 0i64;
v62 = 0i64;
}
v13 = v57 + 1;
v10 = v58;
}
LOBYTE(v11) = WsIrql;
MiUnlockWorkingSetShared(v7, v11);
if( v59 )
{
if( v9 )
{
v49 = 1;
v50 = (volatile signed __int32 *)(*(_QWORD *)(*(&stru_140C4DB30 + 532) + 8i64) + 4 * ((unsigned __int64)v9 >> 5));
v51 = v9 & 0x1F;
LODWORD(v39) = v51 + 1;
if( (unsigned __int64)(v51 + 1) > 0x20 )
{
v52 = v9 & 0x1F;
if( v52 )
{
LODWORD(v39) = ~(((1 << (32 - v52)) - 1) << v51);
_InterlockedAnd(v50, v39);
v49 = 1 - (32 - v52);
++v50;
}
if( v49 >= 0x20 )
{
v39 = (unsigned __int64)v49 >> 5;
do
{
*v50++ = 0;
v49 -= 32;
--v39;
}
while( v39 );
}
if( v49 )
_InterlockedAnd(v50, -1 << v49);
}
else
{
_InterlockedAnd(v50, ~(1 << v51));
}
}
else
{
if( (_InterlockedExchangeAdd64((_QWORD *)&stru_140C4DB30 + 533, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((_EX_PUSH_LOCK *)&stru_140C4DB30 + 533);
LODWORD(a3) = 0;
v40 = (_ETHREAD *)KeGetCurrentThread();
if( MiGetSystemRegionType((UINT64)&stru_140C4DB30 + 4264) == 1 )
SessionId = (unsigned int)MmGetSessionIdEx(v40->Tcb.ApcState.Process);
else
SessionId = 0xFFFFFFFFi64;
--v40->Tcb.SpecialApcDisable;
v42 = ++v40->Tcb.AbAllocationRegionCount;
v43 = 0i64;
v44 = ((char)v40->Tcb.AbEntrySummary | (char)v40->Tcb.AbOrphanedEntrySummary) ^ 0x3F;
while( 1 )
{
v46 = !_BitScanReverse((unsigned int *)&v47, v44);
if( v46 )
break;
v44 &= ~(1 << v47);
v45 = (__int64)&v40->Tcb.LockEntries[v47];
if( (*(_BYTE *)(v45 + 26) & 1) != 0
&& (*(_DWORD *)(v45 + 32) & 1) == 0
&& (*(_QWORD *)(v45 + 32) & 0x7FFFFFFFFFFFFFFCi64) == (((unsigned __int64)&stru_140C4DB30 + 4264) & 0x7FFFFFFFFFFFFFFCi64)
&& *(_DWORD *)(v45 + 40) == (_DWORD)SessionId )
{
*(_BYTE *)(v45 + 26) &= ~1u;
if( *(_QWORD *)(v45 + 32) )
{
v43 = (_KLOCK_ENTRY *)v45;
break;
}
}
}
if( v43 )
{
v43->CrossThreadReleasableAndBusyByte |= 2u;
if( v43->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 < 0 )
KiAbEntryRemoveFromTree(v43);
LODWORD(a3) = v43->BoostBitmap.AllFields & 0x1FFFF;
v43->BoostBitmap.AllFields &= 0xFFFE0000;
v43->ThreadLocalFlags &= ~1u;
v43->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 = 0i64;
v48 = v43 - v40->Tcb.LockEntries;
if( v42 == 1 )
v40->Tcb.AbEntrySummary |= 1 << v48;
else
_InterlockedOr8((volatile signed __int8 *)&v40->Tcb.AbOrphanedEntrySummary, 1 << v48);
}
else if( (*(&v40->Tcb.MiscFlags + 1) & 0x10000) == 0 )
{
KeBugCheckEx(0x162u, v40, (char *)&stru_140C4DB30 + 4264, (PVOID)SessionId, 0i64);
}
--v40->Tcb.AbAllocationRegionCount;
KiAbThreadRemoveBoosts(&v40->Tcb, (char *)&stru_140C4DB30 + 4264, &a3);
v46 = v40->Tcb.SpecialApcDisable++ == -1;
if( v46 && ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)v40->Tcb.ApcState.ApcListHead[0].Flink != &v40->Tcb.152 )
KiCheckForKernelApcDelivery();
KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
}
}
return v39;
}Referenced by:
MiDecommitEnclavePages
MiTerminateHardwareEnclave