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