MmProtectVirtualMemory

NTSTATUS __stdcall MmProtectVirtualMemory(
        PFN_WDFDRIVERERRORREPORTAPIMISSING *a1,
        PFN_WDFDRIVERERRORREPORTAPIMISSING *a2,
        PFN_WDFDEVICEWDMDISPATCHPREPROCESSEDIRP **a3,
        _XSTATE_FEATURE **a4,
        INT64 a5,
        PFN_WDFDEVICEWDMDISPATCHPREPROCESSEDIRP *DeviceObject){
  int v6; 
  signed __int64 v7; 
  _XSTATE_FEATURE *v8; 
  int v9; 
  int v10; 
  unsigned int v11; 
  NTSTATUS ProtectionMask; 
  unsigned __int64 v13; 
  VOID *v14; 
  _MMVAD *v15; 
  _MMVAD *v16; 
  UINT64 v17; 
  union {unsigned int LongFlags;_MMVAD_FLAGS VadFlags;_MM_PRIVATE_VAD_FLAGS PrivateVadFlags;_MM_GRAPHICS_VAD_FLAGS GraphicsVadFlags;_MM_SHARED_VAD_FLAGS SharedVadFlags;volatile unsigned int VolatileVadLong;} v18; 
  int v19; 
  int v20; 
  unsigned int v21; 
  unsigned __int64 v22; 
  unsigned __int64 LongFlags; 
  int v24; 
  _MMVAD *v25; 
  int v26; 
  int v27; 
  NTSTATUS v29; 
  int v30; 
  char v31; 
  PFN_WDFDRIVERERRORREPORTAPIMISSING v32; 
  unsigned __int64 v33; 
  unsigned __int64 v34; 
  unsigned __int64 v35; 
  __int16 v36; 
  __int64 v37; 
  int v38; 
  int v39; 
  UINT64 NewProtect; 
  PVOID *RevertToFileMap; 
  UINT64 *CapturedOldProtect; 
  unsigned int ReturnedRegionSize; 
  UINT64 v44; 
  unsigned int v45; 
  int AnyPageLocked; 
  unsigned __int64 v47; 
  unsigned __int64 v48; 
  NTSTATUS v49; 
  int v50; 
  _MMVAD_SHORT *Vad; 
  VOID *Base; 
  int v53; 
  int v54; 
  UINT64 Size; 
  _QWORD *Teb; 
  _MMVAD *v57; 
  unsigned __int64 v58; 
  unsigned __int64 v59; 
  unsigned __int64 v60; 
  _MI_VA_PAIR VaRange[2]; 
  unsigned __int64 v62; 
  PFN_WDFDRIVERERRORREPORTAPIMISSING *Process; 

  Process = a2;
  v6 = 0;
  v44 = 0i64;
  *(_DWORD *)DeviceObject = 1;
  AnyPageLocked = 0;
  v50 = 1;
  v7 = (signed __int64)*a3;
  Base = (VOID *)v7;
  v57 = (_MMVAD *)v7;
  v8 = *a4;
  Size = (UINT64)v8;
  v58 = (unsigned __int64)v8;
  v9 = a5 & 0x7F800;
  v53 = a5 & 0x7F800;
  if( (a5 & 0x7F800) != 0 )
  {
    v27 = xHalUnmaskInterrupt((_KENLISTMENT *)DeviceObject, (_LARGE_INTEGER *)a2);
    HIDWORD(v44) = v27;
    if( v27 < 0 )
      return v27;
  }
  v45 = (unsigned int)a5 >> 31;
  LODWORD(Vad) = (unsigned int)a5 >> 31;
  v10 = a5 & 0xB0000000;
  v54 = a5 & 0xB0000000;
  v11 = a5 & 0x4FF807FF;
  if( (a5 & 0x40000000) != 0 )
  {
    v11 = a5 & 0xFF807FF;
    if( (a5 & 0xFF8070F) != 0 )
      return -1073741582;
    v50 = 0;
  }
  if( v11 )
  {
    ProtectionMask = MiMakeProtectionMask(v11);
    ReturnedRegionSize = ProtectionMask;
    v49 = ProtectionMask;
    if( ProtectionMask != -1 )
    {
      a2 = Process;
      goto LABEL_6;
    }
    return -1073741755;
  }
  if( v10 != 0x80000000 && v10 != 0x10000000 )
    return -1073741755;
  ProtectionMask = 24;
  ReturnedRegionSize = 24;
  v49 = 24;
LABEL_6:
  v13 = ((unsigned __int64)v8 + v7 - 1) | 0xFFF;
  v60 = v13;
  v14 = (VOID *)(v7 & 0xFFFFFFFFFFFFF000ui64);
  v59 = v7 & 0xFFFFFFFFFFFFF000ui64;
  Teb = 0i64;
  v47 = 0i64;
  v48 = 0i64;
  if( (ProtectionMask & 0xFFFFFFF8) == 16 )
  {
    if( KeGetCurrentThread()->ApcStateIndex == 1
      || (v32 = a2[176]) != 0i64 && ((v36 = *((_WORD *)v32 + 4), v36 == 332) || v36 == 452) )
    {
      v33 = v48;
    }
    else
    {
      Teb = KeGetCurrentThread()->Teb;
      v47 = (unsigned __int64)Teb;
      v33 = Teb[2] & 0xFFFFFFFFFFFFF000ui64;
      v48 = v33;
    }
    v47 = v33;
  }
  Vad = 0i64;
  v58 = v13 >> 12;
  LODWORD(v15) = MiObtainReferencedVadEx((UINT64)v14, 0, (INT64 *)((char *)&v44 + 4));
  v16 = v15;
  v57 = v15;
  if( !v15 )
  {
    v27 = HIDWORD(v44);
    if( HIDWORD(v44) != -1073741664 )
      goto LABEL_117;
    goto LABEL_80;
  }
  Vad = &v15->Core;
  if( v58 > (v15->Core.EndingVpn | ((unsigned __int64)v15->Core.EndingVpnHigh << 32)) )
  {
    v27 = -1073741800;
    goto LABEL_117;
  }
  if( (v15->Core.u.LongFlags & 0x1100000) == 17825792 )
  {
    if( !v9 )
    {
      v27 = -1073741755;
      goto LABEL_117;
    }
  }
  else if( v9 )
  {
    v27 = -1073741755;
    goto LABEL_117;
  }
  v17 = ReturnedRegionSize;
  if( (ReturnedRegionSize & 2) == 0 )
  {
LABEL_12:
    v18.LongFlags = (unsigned int)v16->Core.u;
    v19 = v18.LongFlags & 0x100000;
    if( ((v18.LongFlags & 0x100000) == 0 || (v18.LongFlags & 0x400000) == 0 && (v18.LongFlags & 0xC0000) < 0x80000)
      && (v18.LongFlags & 0x70) != 80 )
    {
      goto LABEL_14;
    }
    if( (v18.LongFlags & 0x500000) == 5242880 )
    {
      LODWORD(v37) = MiGetVadPageSize((INT64)v16);
      if( (((unsigned __int64)Base | (v13 + 1)) & ((v37 << 12) - 1)) != 0 )
      {
        v27 = -1073741800;
        goto LABEL_117;
      }
LABEL_14:
      if( (v18.LongFlags & 0x3100000) == 34603008 )
      {
        LODWORD(CapturedOldProtect) = v17;
        LODWORD(RevertToFileMap) = v11;
        v29 = MiProtectEnclavePages(
                Process,
                a1,
                (UINT64)v16,
                (UINT64)v14,
                (UINT64 *)v13,
                RevertToFileMap,
                CapturedOldProtect);
        MiUnlockAndDereferenceVad(&v16->Core);
        return v29;
      }
      if( (v10 & 0x5FFFFFFF) != 0 )
      {
        v27 = -1073741755;
        goto LABEL_117;
      }
      if( !v11 )
      {
        v27 = -1073741755;
        goto LABEL_117;
      }
      v20 = v18.LongFlags & 0x70;
      if( v20 == 48 )
      {
        v38 = MiProtectAweRegion(v14, (VOID *)v13, v17);
        if( v38 >= 0 )
        {
          MiUnlockAndDereferenceVad(&v16->Core);
          *a4 = (_XSTATE_FEATURE *)(v13 - (_QWORD)v14 + 1);
          *a3 = (PFN_WDFDEVICEWDMDISPATCHPREPROCESSEDIRP *)v14;
          *(_DWORD *)DeviceObject = v44;
          return v38;
        }
        v27 = -1073741800;
        goto LABEL_117;
      }
      if( v20 == 16 )
      {
        v27 = -1073741800;
        goto LABEL_117;
      }
      v21 = v45;
      if( v45 == 1 && (v19 || (v16->Subsection->ControlArea->u.LongFlags & 0x20) != 0) )
        goto LABEL_116;
      if( (v18.LongFlags & 8) == 0 || v6 )
      {
        v22 = v47;
      }
      else
      {
        v27 = MiCheckSecuredVad(&v16->Core, Base, Size, (unsigned int)v17);
        if( v27 < 0 )
          goto LABEL_117;
        v22 = v48;
        v21 = v45;
        LODWORD(v17) = ReturnedRegionSize;
      }
      LongFlags = v16->Core.u.LongFlags;
      if( (LongFlags & 0x100000) != 0 )
      {
        if( (v11 & 0x88) == 0 && v21 != 1 )
        {
          if( (LongFlags & 0x70) == 64 )
          {
            if( (v11 & 0xFFFFF9F9) != 0 )
            {
              v27 = -1073741755;
              goto LABEL_117;
            }
            v11 &= 0x7FFFF9FFu;
            v39 = v16->Core.u.LongFlags & 0xC00;
            if( (v16->Core.u.LongFlags & 0x380) != 0 && v39 == 3072 )
            {
              v11 |= 0x400u;
            }
            else if( v39 == 1024 )
            {
              v11 |= 0x200u;
            }
            LODWORD(v17) = MiMakeProtectionMask(v11);
          }
          LODWORD(NewProtect) = v11;
          v27 = MiProtectPrivateMemory(
                  &v16->Core,
                  v14,
                  (VOID *)v13,
                  (unsigned int)v17,
                  NewProtect,
                  (UINT64 *)RevertToFileMap,
                  &v44);
          if( v27 < 0 )
            goto LABEL_117;
          if( v22 )
          {
            if( v22 < v13 )
            {
              v34 = v22 >> 12;
              if( v34 >= (v16->Core.StartingVpn | ((unsigned __int64)v16->Core.StartingVpnHigh << 32)) )
              {
                v35 = v16->Core.EndingVpn | ((unsigned __int64)v16->Core.EndingVpnHigh << 32);
                if( v34 <= v35 && (v13 + 1) >> 12 <= v35 )
                  Teb[2] = v13 + 1;
              }
            }
          }
          goto LABEL_34;
        }
      }
      else if( (v11 & 0x600) == 0 )
      {
        if( (LongFlags & 0x70) == 32 )
        {
          if( (v11 & 4) != 0 )
            v11 = v11 & 0xFFFFFFF3 | 8;
          if( (v11 & 0x40) != 0 )
            v11 = v11 & 0xFFFFFF3F | 0x80;
        }
        v24 = MmCompatibleProtectionMask[(LongFlags >> 7) & 7] | 0x700;
        if( (v11 | v24) != v24 )
        {
          v27 = -1073741746;
          goto LABEL_117;
        }
        if( (v16->Subsection->ControlArea->u.LongFlags & 0xA0) == 0x80 )
        {
LABEL_33:
          LODWORD(RevertToFileMap) = v21;
          LODWORD(NewProtect) = v11;
          v27 = MiSetProtectionOnSection(
                  (ULONG_PTR)Process,
                  v16,
                  v14,
                  (VOID *)v13,
                  NewProtect,
                  (UINT64)RevertToFileMap,
                  &v44,
                  (UINT64 *)&AnyPageLocked);
          if( v27 < 0 )
            goto LABEL_117;
LABEL_34:
          MiUnlockAndDereferenceVad(&v16->Core);
          *a4 = (_XSTATE_FEATURE *)(v13 - (_QWORD)v14 + 1);
          *a3 = (PFN_WDFDEVICEWDMDISPATCHPREPROCESSEDIRP *)v14;
          *(_DWORD *)DeviceObject = v44;
          if( AnyPageLocked == 1 )
            return 1073741847;
          return 0;
        }
        if( !MiVadMapsLargeImage(v16) )
        {
          MiIsRangeFullyCommitted(v25, v14, (VOID *)v13);
          if( !v26 )
          {
            v27 = -1073741779;
            goto LABEL_117;
          }
          goto LABEL_33;
        }
        if( v11 != 128 && v11 != 8 )
        {
          v27 = -1073741746;
          goto LABEL_117;
        }
        MiUnlockAndDereferenceVad(&v25->Core);
LABEL_93:
        *a4 = (_XSTATE_FEATURE *)(v13 - (_QWORD)v14 + 1);
        *a3 = (PFN_WDFDEVICEWDMDISPATCHPREPROCESSEDIRP *)v14;
        *(_DWORD *)DeviceObject = MmProtectToValue[ReturnedRegionSize];
        return 0;
      }
LABEL_116:
      v27 = -1073741582;
      goto LABEL_117;
    }
    if( (_DWORD)v17 == ((v18.LongFlags >> 7) & 0x1F) )
    {
      MiUnlockAndDereferenceVad(&v16->Core);
      goto LABEL_93;
    }
LABEL_80:
    v27 = -1073741800;
    goto LABEL_117;
  }
  MiAllowProtectionChange((_EPROCESS *)Process, (_EPROCESS *)a1, v15, ReturnedRegionSize, v14, (VOID *)v13);
  v27 = v30;
  if( v30 < 0 )
    goto LABEL_117;
  if( (v16->Core.u.LongFlags & 0x100) != 0 || !MiIsProcessCfgEnabled() || v50 != 1 )
    goto LABEL_50;
  if( (v31 & 8) != 0 )
  {
    v27 = MiCheckSecuredVad(&v16->Core, Base, Size, ReturnedRegionSize);
    if( v27 < 0 )
      goto LABEL_117;
    v6 = 1;
    v47 = v48;
  }
  *(_QWORD *)VaRange = v14;
  v62 = v13;
  v27 = MiCommitVadCfgBits(v16, VaRange, 0i64);
  if( v27 >= 0 )
  {
LABEL_50:
    v17 = ReturnedRegionSize;
    v10 = a5 & 0xB0000000;
    goto LABEL_12;
  }
LABEL_117:
  if( Vad )
    MiUnlockAndDereferenceVad(Vad);
  return v27;
}

Referenced by:

KiTpWriteUmMemory
NtProtectVirtualMemory
PsDispatchIumService