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 v14;
_QWORD *v15;
unsigned int v16;
unsigned int v17;
int v18;
_MMPTE *PteBase;
UINT64 v20;
UINT64 v21;
INT64 ValidPte;
CHAR v23;
unsigned int v24;
unsigned int v25;
unsigned __int64 v26;
unsigned __int64 v27;
unsigned __int64 v28;
INT64 v29;
INT64 v30;
int v31;
UINT64 v32;
ULONG_PTR v33;
UINT64 v34;
__int64 v35;
NTSTATUS v36;
unsigned __int64 v37;
UINT64 a5;
_DWORD *a6;
CHAR a7;
ULONG_PTR BugCheckParameter1;
NTSTATUS v42;
int v43;
unsigned int v44;
__int64 v45;
UINT64 v46;
INT64 a1;
UINT64 v48;
UINT64 v49;
UINT64 v50;
INT64 a3;
unsigned __int64 v52;
INT64 a4;
__int64 v54;
unsigned __int64 v55;
_QWORD *v56;
_DWORD *v57;
unsigned __int64 *v58;
int result;
__int16 result_4;
int v61;
__int64 v62;
__int64 v63;
unsigned int v64;
_DWORD *v65;
UINT64 *v66;
_QWORD *v67;
v50 = ProtectionMask;
v57 = v65;
v58 = v66;
v10 = EnclaveFlags;
v56 = v67;
a3 = EnclaveFlags;
memset((INT64)&result, 0i64);
v11 = *(_DWORD *)(ProtectionMask + 64);
if( (v11 & 1) != 0 )
{
v16 = (unsigned int)ReturnedRegionSize;
LOBYTE(v17) = 0;
v18 = v64 & 0x20000000;
if( (v64 & 0x20000000) != 0 )
{
if( (v64 & 0x90000000) != 0 )
return -1073741755;
}
else
{
if( (v11 & 2) == 0 || (*(_DWORD *)(v50 + 72) & 1) == 0 )
return -1073741800;
if( (v64 & 0x80000000) != 0 )
{
if( v64 == 0x80000000 && !(_DWORD)ReturnedBaseAddress )
{
LOBYTE(v17) = 8;
goto LABEL_30;
}
return -1073741755;
}
if( (v64 & 0x10000000) != 0 )
{
if( v64 != 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 = (UINT64)PteBase + ((v10 >> 9) & 0x7FFFFFFFF8i64);
v42 = 0;
v52 = (unsigned __int64)PteBase + (((unsigned __int64)CapturedOldProtect >> 9) & 0x7FFFFFFFF8i64);
v54 = 0xFFFFFFFFi64;
v21 = 0i64;
v49 = 0i64;
v48 = -1i64;
v45 = *((_QWORD *)KeGetCurrentThread() + 23) + 1664i64;
if( !v18 )
v16 = (unsigned __int8)ReturnedRegionSize & 2 | 4;
result = 1;
result_4 = 0;
v62 = 0i64;
v61 = 20;
v63 = 0i64;
v43 = v18 != 0 ? 2 : 4;
ValidPte = MiMakeValidPte(v20, -1i64, v16 | 0x80000000);
v23 = MiLockWorkingSetShared(v45);
v24 = 0;
v25 = v43;
v26 = a3 & 0xFFFFFFFFFFFFF000ui64;
a7 = v23;
v27 = v52;
v55 = a3 & 0xFFFFFFFFFFFFF000ui64;
v44 = 0;
while( 1 )
{
a1 = v26;
v28 = v20;
BugCheckParameter1 = v20;
if( v20 <= v27 )
break;
v36 = v42;
LABEL_69:
if( v36 < 0 || (++v24, v44 = v24, v24 >= v25) )
{
LABEL_73:
MiFlushEnclaveTb((INT64)&result, v48, v64);
if( v49 )
MiUnlockPageTableInternal(v45, v49);
MiUnlockWorkingSetShared(v45, a7);
if( v36 >= 0 )
{
v36 = 0;
*v57 = MmProtectToValue[(unsigned int)v54];
v37 = ((unsigned __int64)CapturedOldProtect & 0xFFFFFFFFFFFFF000ui64) - v55;
*v58 = v55;
*v56 = v37 + 4096;
}
return v36;
}
v21 = v49;
v26 = v55;
}
while( 1 )
{
if( (v28 & 0x78) != 0 || v28 == v20 )
goto LABEL_44;
if( MiWorkingSetIsContended(v45) || KeShouldYieldProcessor() )
goto LABEL_40;
if( v21 )
break;
LABEL_46:
MiFlushEnclaveTb((INT64)&result, v48, v64);
v48 = -1i64;
if( v21 )
MiUnlockPageTableInternal(v45, v21);
v49 = (UINT64)MmGetPteBase() + ((BugCheckParameter1 >> 9) & 0x7FFFFFFFF8i64);
MiMakeSystemAddressValid(BugCheckParameter1, 0i64, (*(_DWORD *)(v50 + 48) >> 12) & 0x3F, a7, 0);
v28 = BugCheckParameter1;
LABEL_49:
if( v44 )
{
if( v44 == v43 - 1 )
{
v46 = MI_READ_PTE_LOCK_FREE(v28);
v34 = v46;
MiPteInShadowRange((UINT64)&v46);
v35 = (v34 >> 12) & 0xFFFFFFFFFi64;
MiUpdateEnclavePfnProtection((INT64)MmGetPfnDb() + 48 * v35, v16);
ValidPte = (v35 << 12) | ValidPte & 0xFFFF000000000FFFui64;
LODWORD(a5) = 0;
MiWriteEnclavePte((PVOID)BugCheckParameter1, ValidPte);
if( (MiFlags & 0x100) == 0 && (MiFlags & 0x200) == 0 || MI_TIGHTER_PERMISSIONS(v46, ValidPte) )
MiInsertTbFlushEntry((INT64)&result, a1, 1i64, 0i64);
v48 = a1;
}
else if( v44 == 1 )
{
v42 = KeCanChangeEnclavePageProtection();
if( v42 < 0 )
{
v27 = v52;
v36 = -1073741800;
v42 = -1073741800;
LABEL_68:
v25 = v43;
v24 = v44;
goto LABEL_69;
}
}
else
{
KeChangeEnclavePageProtection(a1, v17);
KeTrackEnclaveTbFlush();
}
goto LABEL_63;
}
v46 = MI_READ_PTE_LOCK_FREE(v28);
v32 = v46;
if( (v46 & 1) == 0 )
{
v36 = -1073741800;
goto LABEL_73;
}
v33 = BugCheckParameter1;
if( BugCheckParameter1 == v20 )
{
MiPteInShadowRange((UINT64)&v46);
v54 = (*((_DWORD *)MmGetPfnDb() + 12 * ((v32 >> 12) & 0xFFFFFFFFFi64) + 4) >> 5) & 0x1F;
LABEL_63:
v33 = BugCheckParameter1;
}
a1 += 4096i64;
v28 = v33 + 8;
v27 = v52;
BugCheckParameter1 = v28;
if( v28 > v52 )
{
v36 = v42;
goto LABEL_68;
}
v21 = v49;
}
MiPageTableLockIsContended(v45, v21, v29, v30, a5, (INT64)a6, a7);
if( v31 )
{
LABEL_40:
MiFlushEnclaveTb((INT64)&result, v48, v64);
v48 = -1i64;
if( v21 )
{
MiUnlockPageTableInternal(v45, v21);
v21 = 0i64;
v49 = 0i64;
}
MiUnlockWorkingSetShared(v45, a7);
MiLockWorkingSetShared(v45);
}
v28 = BugCheckParameter1;
LABEL_44:
if( v21 && (v28 & 0xFFF) != 0 )
goto LABEL_49;
goto LABEL_46;
}
v12 = *(_QWORD *)(ProtectionMask + 72);
v13 = (char *)CapturedOldProtect - v10 + 1;
a4 = (INT64)v13;
if( *(_BYTE *)(v12 + 76) && (v64 & 0x20000000) != 0 )
{
*v65 = 4;
v14 = 0;
LABEL_7:
v15 = v56;
*v66 = v10;
*v15 = v13;
return v14;
}
LODWORD(a5) = (_DWORD)ReturnedBaseAddress;
v14 = VslDebugProtectSecureProcessMemory((INT64)StartingAddress, (INT64)EndingAddress, &a3, &a4, a5, v65);
if( v14 >= 0 )
{
v13 = (char *)a4;
v10 = a3;
goto LABEL_7;
}
return v14;
}Referenced by:
MmProtectVirtualMemory