MiProtectEnclavePages
NTSTATUS __stdcall MiProtectEnclavePages(
PVOID StartingAddress,
PVOID EndingAddress,
UINT64 ProtectionMask,
UINT64 EnclaveFlags,
UINT64 *CapturedOldProtect,
PVOID *ReturnedBaseAddress,
UINT64 *ReturnedRegionSize){
UINT64 v10;
int v11;
__int64 v12;
char *v13;
NTSTATUS result;
_QWORD *v15;
unsigned int v16;
unsigned int v17;
int v18;
_MMPTE *PteBase;
_XSTATE_CONFIGURATION *v20;
UINT64 v21;
unsigned __int64 v22;
unsigned __int64 v23;
unsigned int v24;
unsigned int v25;
VOID *v26;
UINT8 v27;
unsigned __int64 v28;
unsigned __int64 v29;
int v30;
UINT64 v31;
UINT64 v32;
UINT64 v33;
UINT64 v34;
UINT64 v35;
UINT64 v36;
__int64 v37;
NTSTATUS v38;
UINT64 v39;
unsigned __int64 v40;
UINT64 Flags;
UINT8 WsIrql;
UINT64 PageTableVirtualAddress;
NTSTATUS v44;
int v45;
unsigned int v46;
_MMSUPPORT_FULL *p_Vm;
UINT64 v48;
VOID *Va;
VOID *a2;
UINT64 v51;
INT64 v52;
UINT64 v53;
unsigned __int64 v54;
char *v55;
__int64 v56;
unsigned __int64 v57;
_QWORD *v58;
_DWORD *v59;
unsigned __int64 *v60;
_MI_TB_FLUSH_LIST TbFlushList[48];
unsigned int a3;
_DWORD *v63;
UINT64 *v64;
_QWORD *v65;
v52 = ProtectionMask;
v59 = v63;
v60 = v64;
v10 = EnclaveFlags;
v58 = v65;
v53 = EnclaveFlags;
memset(TbFlushList, 0i64, 0xB8u);
v11 = *(_DWORD *)(ProtectionMask + 64);
if( (v11 & 1) != 0 )
{
v16 = (unsigned int)ReturnedRegionSize;
LOBYTE(v17) = 0;
v18 = a3 & 0x20000000;
if( (a3 & 0x20000000) != 0 )
{
if( (a3 & 0x90000000) != 0 )
return -1073741755;
}
else
{
if( (v11 & 2) == 0 || (*(_DWORD *)(v52 + 72) & 1) == 0 )
return -1073741800;
if( (a3 & 0x80000000) != 0 )
{
if( a3 == 0x80000000 && !(_DWORD)ReturnedBaseAddress )
{
LOBYTE(v17) = 8;
goto LABEL_30;
}
return -1073741755;
}
if( (a3 & 0x10000000) != 0 )
{
if( a3 != 0x10000000 || (_DWORD)ReturnedBaseAddress )
return -1073741755;
LOBYTE(v17) = 0x80;
goto LABEL_30;
}
}
if( (unsigned int)ReturnedRegionSize > 7 && (_DWORD)ReturnedRegionSize != 24
|| ((unsigned __int8)ReturnedRegionSize & 5) == 5 )
{
return -1073741755;
}
if( (_DWORD)ReturnedRegionSize == 24 )
{
if( v18 )
return -1073741755;
}
else
{
v17 = ((unsigned __int8)ReturnedRegionSize & 4 | 2u) >> 1;
if( ((unsigned __int8)ReturnedRegionSize & 2) != 0 )
LOBYTE(v17) = v17 | 4;
}
LABEL_30:
PteBase = MmGetPteBase();
v20 = (_XSTATE_CONFIGURATION *)((char *)PteBase + ((v10 >> 9) & 0x7FFFFFFFF8i64));
v44 = 0;
v54 = (unsigned __int64)PteBase + (((unsigned __int64)CapturedOldProtect >> 9) & 0x7FFFFFFFF8i64);
v56 = 0xFFFFFFFFi64;
v21 = 0i64;
v51 = 0i64;
a2 = (VOID *)-1i64;
p_Vm = &KeGetCurrentThread()->ApcState.Process->Vm;
if( !v18 )
v16 = (unsigned __int8)ReturnedRegionSize & 2 | 4;
TbFlushList[0] = 1;
LOWORD(TbFlushList[1]) = 0;
*(_QWORD *)&TbFlushList[4] = 0i64;
TbFlushList[2] = 20;
*(_QWORD *)&TbFlushList[6] = 0i64;
v45 = v18 != 0 ? 2 : 4;
LODWORD(v22) = MiMakeValidPte(v20, -1i64, v16 | 0x80000000);
v23 = v22;
MiLockWorkingSetShared();
v24 = 0;
v25 = v45;
v26 = (VOID *)(v53 & 0xFFFFFFFFFFFFF000ui64);
WsIrql = v27;
v28 = v54;
v57 = v53 & 0xFFFFFFFFFFFFF000ui64;
v46 = 0;
while( 1 )
{
Va = v26;
v29 = (unsigned __int64)v20;
PageTableVirtualAddress = (UINT64)v20;
if( (unsigned __int64)v20 <= v28 )
break;
v38 = v44;
LABEL_69:
if( v38 < 0 || (++v24, v46 = v24, v24 >= v25) )
{
LABEL_73:
MiFlushEnclaveTb(TbFlushList, a2, a3);
v39 = v51;
if( v51 )
MiUnlockPageTableInternal((INT64)p_Vm, v51);
LOBYTE(v39) = WsIrql;
MiUnlockWorkingSetShared(&p_Vm->Instance, v39);
if( v38 >= 0 )
{
v38 = 0;
*v59 = MmProtectToValue[(unsigned int)v56];
v40 = ((unsigned __int64)CapturedOldProtect & 0xFFFFFFFFFFFFF000ui64) - v57;
*v60 = v57;
*v58 = v40 + 4096;
}
return v38;
}
v21 = v51;
v26 = (VOID *)v57;
}
while( 1 )
{
if( (v29 & 0x78) != 0 || (_XSTATE_CONFIGURATION *)v29 == v20 )
goto LABEL_44;
LOBYTE(v30) = MiWorkingSetIsContended((INT64)p_Vm);
if( v30 || (unsigned int)KeShouldYieldProcessor() )
goto LABEL_40;
if( v21 )
break;
LABEL_46:
MiFlushEnclaveTb(TbFlushList, a2, a3);
a2 = (VOID *)-1i64;
if( v21 )
MiUnlockPageTableInternal((INT64)p_Vm, v21);
v51 = (UINT64)MmGetPteBase() + ((PageTableVirtualAddress >> 9) & 0x7FFFFFFFF8i64);
LODWORD(Flags) = 0;
MiMakeSystemAddressValid(
(VOID *)PageTableVirtualAddress,
0i64,
(*(_DWORD *)(v52 + 48) >> 12) & 0x3F,
WsIrql,
Flags);
v29 = PageTableVirtualAddress;
LABEL_49:
if( v46 )
{
if( v46 == v45 - 1 )
{
LODWORD(v35) = MI_READ_PTE_LOCK_FREE(v29);
v48 = v35;
v36 = v35;
MiPteInShadowRange((UINT64)&v48);
v37 = (v36 >> 12) & 0xFFFFFFFFFi64;
MiUpdateEnclavePfnProtection(&MmGetPfnDb()[v37], v16);
v23 = (v37 << 12) | v23 & 0xFFFF000000000FFFui64;
LODWORD(Flags) = 0;
MiWriteEnclavePte(PageTableVirtualAddress, v23, v52, 1i64, Flags);
if( (MiFlags & 0x100) == 0 && (MiFlags & 0x200) == 0 || MI_TIGHTER_PERMISSIONS((_MMPTE)v48, (_MMPTE)v23) )
MiInsertTbFlushEntry(TbFlushList, Va, 1ui64, 0i64);
a2 = Va;
}
else if( v46 == 1 )
{
v44 = KeCanChangeEnclavePageProtection();
if( v44 < 0 )
{
v28 = v54;
v38 = -1073741800;
v44 = -1073741800;
LABEL_68:
v25 = v45;
v24 = v46;
goto LABEL_69;
}
}
else
{
KeChangeEnclavePageProtection((__int64)Va, v17);
KeTrackEnclaveTbFlush();
}
goto LABEL_63;
}
LODWORD(v32) = MI_READ_PTE_LOCK_FREE(v29);
v48 = v32;
v33 = v32;
if( (v32 & 1) == 0 )
{
v38 = -1073741800;
goto LABEL_73;
}
v34 = PageTableVirtualAddress;
if( (_XSTATE_CONFIGURATION *)PageTableVirtualAddress == v20 )
{
MiPteInShadowRange((UINT64)&v48);
v56 = (*((_DWORD *)&MmGetPfnDb()[(v33 >> 12) & 0xFFFFFFFFFi64].3 + 4) >> 5) & 0x1F;
LABEL_63:
v34 = PageTableVirtualAddress;
}
Va = (char *)Va + 4096;
v29 = v34 + 8;
v28 = v54;
PageTableVirtualAddress = v29;
if( v29 > v54 )
{
v38 = v44;
goto LABEL_68;
}
v21 = v51;
}
if( (unsigned int)MiPageTableLockIsContended((__int64)p_Vm, v21) )
{
LABEL_40:
MiFlushEnclaveTb(TbFlushList, a2, a3);
a2 = (VOID *)-1i64;
if( v21 )
{
MiUnlockPageTableInternal((INT64)p_Vm, v21);
v21 = 0i64;
v51 = 0i64;
}
LOBYTE(v31) = WsIrql;
MiUnlockWorkingSetShared(&p_Vm->Instance, v31);
MiLockWorkingSetShared();
}
v29 = PageTableVirtualAddress;
LABEL_44:
if( v21 && (v29 & 0xFFF) != 0 )
goto LABEL_49;
goto LABEL_46;
}
v12 = *(_QWORD *)(ProtectionMask + 72);
v13 = (char *)CapturedOldProtect - v10 + 1;
v55 = v13;
if( *(_BYTE *)(v12 + 76) && (a3 & 0x20000000) != 0 )
{
*v63 = 4;
result = 0;
LABEL_7:
v15 = v58;
*v64 = v10;
*v15 = v13;
return result;
}
result = VslDebugProtectSecureProcessMemory(
(__int64)StartingAddress,
(__int64)EndingAddress,
(__int64 *)&v53,
(__int64 *)&v55,
(unsigned int)ReturnedBaseAddress,
v63);
if( result >= 0 )
{
v13 = v55;
v10 = v53;
goto LABEL_7;
}
return result;
}Referenced by:
MmProtectVirtualMemory