MiReserveUserMemory

NTSTATUS __stdcall MiReserveUserMemory(INT64 a1, INT64 *rdx0, INT64 a3, UINT8 r9_0, UINT64 *a5, _WORD *a4){
  int v6; 
  unsigned int v7; 
  int v10; 
  __int64 v11; 
  UINT64 v12; 
  int v13; 
  _MMVAD *PoolMm; 
  _MMVAD *v15; 
  int v16; 
  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;} v17; 
  int v18; 
  unsigned __int64 v19; 
  int v20; 
  int v21; 
  _ETHREAD *CurrentThread; 
  int v23; 
  unsigned int LongFlags; 
  bool v25; 
  unsigned __int64 v26; 
  unsigned int v27; 
  _ETHREAD *v28; 
  _EPROCESS *v29; 
  _EPROCESS *v30; 
  int v31; 
  unsigned __int64 v32; 
  unsigned __int64 v33; 
  _ETHREAD *v34; 
  _EPROCESS *v35; 
  int v36; 
  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;} v37; 
  _MMVAD_SHORT *v38; 
  NTSTATUS result; 
  int v40; 
  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;} v41; 
  INT64 v42; 
  int v43; 
  INT64 v44; 
  INT64 v45; 
  unsigned int v46; 
  _EPROCESS *v47; 
  INT64 ProcessPartition; 
  int v49; 
  INT64 v50; 
  int v51; 
  int v52; 
  _EX_PUSH_LOCK *v53; 
  INT64 ProtectionMask; 
  UINT64 *HINTHonored; 
  PVOID *StartingAddress; 
  NTSTATUS PlaceholderStorage; 
  _ETHREAD *Thread; 
  _MMVAD_SHORT *Vad; 
  INT64 a2; 
  UINT64 v61; 
  INT64 a6[2]; 
  _EX_PUSH_LOCK *PushLock; 
  unsigned int v65; 
  UINT8 FillSet; 

  FillSet = r9_0;
  v65 = a3;
  v6 = 0;
  v7 = a3;
  PlaceholderStorage = 0;
  Vad = 0i64;
  if( rdx0 == (INT64 *)1 )
    return -1073741811;
  v10 = 16;
  v11 = *(_QWORD *)(*(_QWORD *)(a1 + 88) + 1680i64);
  if( *(_QWORD *)(a1 + 8) - *(_QWORD *)a1 + 1i64 != *(_QWORD *)(a1 + 24) )
    v10 = 0;
  if( (*(_DWORD *)(a1 + 44) & 0x88) != 0 )
    return -1073741755;
  if( (*(_DWORD *)(a1 + 60) & 0x20000000) != 0 && (MiFlags & 0x100000) == 0
    || (a3 & 2) == 0
    || (result = MiArbitraryCodeBlocked(*(_EPROCESS **)(a1 + 96)), PlaceholderStorage = result, result >= 0) )
  {
    v12 = ((*(_QWORD *)(a1 + 24) & 0xFFFi64) != 0) + (*(_QWORD *)(a1 + 24) >> 12);
    LOWORD(v13) = MmGetCurrentProcessorColor();
    PoolMm = (_MMVAD *)ExAllocatePoolMm(64i64, 0x40ui64, 0x53646156ui64, v13 | 0x80000000);
    v15 = PoolMm;
    if( !PoolMm )
      return -1073741670;
    v16 = *(_DWORD *)(a1 + 52);
    PoolMm->Core.NextVad = (_MMVAD_SHORT *)-2i64;
    PoolMm->Core.ExtraCreateInfo = (void *)-2i64;
    PoolMm->Core.VadNode.ParentValue = -2i64;
    PushLock = &PoolMm->Core.PushLock;
    PoolMm->Core.PushLock._bf_0 = 0i64;
    PoolMm->Core.u.LongFlags ^= (PoolMm->Core.u.LongFlags ^ (v16 << 12)) & 0x3F000;
    v17.LongFlags = (unsigned int)PoolMm->Core.u;
    if( v16 )
    {
      *(_BYTE *)(*(_QWORD *)(*(_QWORD *)(a1 + 88) + 1680i64) + 352i64) = 1;
      v17.LongFlags = (unsigned int)PoolMm->Core.u;
    }
    v18 = *(_DWORD *)(a1 + 40);
    if( (v18 & 0x1000) != 0 )
    {
      PoolMm->Core.u1.LongFlags1 |= 0x80000000;
      v19 = v12;
    }
    else
    {
      v19 = 0i64;
    }
    v20 = *(_DWORD *)(a1 + 60);
    PoolMm->Core.u.LongFlags = v17.LongFlags ^ (LOWORD(v17.LongFlags) ^ (unsigned __int16)((_WORD)v7 << 7)) & 0xF80 | 0x100000;
    if( (v20 & 0x40000000) != 0 )
      PoolMm->Core.u.LongFlags = v17.LongFlags ^ (LOWORD(v17.LongFlags) ^ (unsigned __int16)((_WORD)v7 << 7)) & 0xF80 | 0x4100000;
    if( (v20 & 1) != 0 )
    {
      v19 = 0x7FFFFFFFEi64;
    }
    else if( (v20 & 0x8000000) != 0 )
    {
      v19 = 0x7FFFFFFFDi64;
    }
    v21 = (PoolMm->Core.u1.LongFlags1 ^ v19) & 0x7FFFFFFF;
    v15->Core.CommitChargeHigh = v19 >> 31;
    v15->Core.u1.LongFlags1 ^= v21;
    CurrentThread = (_ETHREAD *)KeGetCurrentThread();
    v23 = v18 & 0x20400000;
    Thread = CurrentThread;
    if( (v18 & 0x20400000) == 0x20000000 )
    {
      v47 = *(_EPROCESS **)(a1 + 120);
      v6 = ((unsigned __int64)v47 >> 4) & 1 | 2;
    }
    else
    {
      if( v23 != 541065216 )
      {
        if( v23 != 0x400000 )
        {
          if( (v18 & 0x800000) == 0 )
            goto LABEL_21;
          if( !MiCreateRotateView(&v15->Core) )
          {
            v31 = -1073741670;
            LOBYTE(v27) = v10;
            goto LABEL_74;
          }
          v46 = v15->Core.u.LongFlags & 0xFFFFFF8F | 0x40;
          goto LABEL_69;
        }
        v49 = v7 & 7;
        if( (v7 & 0xFFFFFFF8) != 16 && (v49 == 4 || v49 == 1) )
        {
          v50 = v7;
          if( (*(_BYTE *)(a1 + 120) & 1) == 0 )
          {
LABEL_111:
            MiCreateUserPhysicalView(&v15->Core, v50, a1, a4);
            PlaceholderStorage = v52;
            if( v52 < 0 )
            {
              v31 = -1073741670;
              LOBYTE(v27) = v10;
              goto LABEL_74;
            }
            v46 = v15->Core.u.LongFlags & 0xFDFFFF8F | 0x30;
LABEL_69:
            v15->Core.u.LongFlags = v46;
            goto LABEL_21;
          }
          if( *(_QWORD *)(a1 + 112) )
          {
            v51 = *(_DWORD *)(a1 + 48);
            v50 = v7 | 2;
            if( (v51 & 0x1C000) == 0 )
              v50 = v7;
            if( (v51 & 0x12000) != 0 )
              v50 = v50 & 0xFFFFFFFA | 4;
            goto LABEL_111;
          }
        }
        v31 = -1073741755;
        LOBYTE(v27) = v10;
        goto LABEL_75;
      }
      v47 = *(_EPROCESS **)(a1 + 120);
      v6 = 1;
      if( ((unsigned __int8)v47 & 2) == 0 )
      {
LABEL_21:
        LongFlags = (v6 << 18) | v15->Core.u.LongFlags & 0xFFF3FFFF;
        v25 = (*(_DWORD *)(a1 + 40) & 0x200000) == 0;
        v15->Core.u.LongFlags = LongFlags;
        if( !v25 )
        {
          PlaceholderStorage = MiCreateWriteWatchView(*(_EPROCESS **)(a1 + 88), &v15->Core, v12);
          v31 = PlaceholderStorage;
          LOBYTE(v27) = v10;
          if( PlaceholderStorage < 0 )
            goto LABEL_74;
          v15->Core.u.LongFlags |= 0x200000u;
          LongFlags = v15->Core.u.LongFlags;
          v7 = v65;
        }
        if( (*(_BYTE *)(a1 + 120) & 1) != 0 )
        {
          if( (*(_DWORD *)(a1 + 40) & 0x20400000) == 0x400000 || (LongFlags & 0x500000) == 5242880 )
          {
            if( *(_DWORD *)(a1 + 48) )
            {
LABEL_24:
              v26 = 0i64;
              v27 = v10;
              v25 = (*(_DWORD *)(a1 + 60) & 0x4000000) == 0;
              a2 = 0i64;
              if( !v25 )
              {
                PlaceholderStorage = MiCreatePlaceholderStorage(&v15->Core);
                v31 = PlaceholderStorage;
                if( PlaceholderStorage < 0 )
                  goto LABEL_71;
                v7 = v65;
                v27 = v10 | 8;
              }
              v28 = Thread;
              v29 = *(_EPROCESS **)(a1 + 88);
              v61 = 0i64;
              v27 |= 4u;
              LOCK_ADDRESS_SPACE(Thread, v29);
              v30 = *(_EPROCESS **)(a1 + 88);
              if( (v30->Flags & 0x20) != 0 )
              {
                v31 = -1073741558;
                goto LABEL_72;
              }
              if( v27 < 0x10 )
              {
                LODWORD(StartingAddress) = *(_DWORD *)(a1 + 60);
                LODWORD(HINTHonored) = v7;
                v31 = MiSelectUserAddress(
                        *(unsigned int *)(a1 + 40),
                        *(_QWORD *)a1,
                        *(_QWORD *)(a1 + 8),
                        *(_QWORD *)(a1 + 24),
                        *(_QWORD *)(a1 + 16),
                        0i64,
                        HINTHonored,
                        StartingAddress);
                if( v31 >= 0 )
                {
                  v26 = a2;
                  v32 = *(_QWORD *)(a1 + 24) + a2 - 1;
                  goto LABEL_29;
                }
                MiLogReserveVaFailed(*(_QWORD *)(a1 + 24), *(_QWORD *)(a1 + 16), *(_QWORD *)a1);
                v26 = a2;
LABEL_72:
                *a5 = v26;
                if( Vad )
                  MiUnlockVad(v28, Vad);
                goto LABEL_74;
              }
              if( (*(_DWORD *)(a1 + 60) & 0x4000000) != 0 )
              {
                Vad = MiFindPlaceholderVadToReplace(
                        *(VOID **)a1,
                        *(_QWORD *)(a1 + 8),
                        *(unsigned __int8 *)(a1 + 104),
                        &PlaceholderStorage);
                if( !Vad )
                {
                  v31 = PlaceholderStorage;
                  goto LABEL_72;
                }
                v42 = *(_QWORD *)a1;
                v32 = *(_QWORD *)(a1 + 8);
LABEL_60:
                v26 = v42;
                a2 = v42;
LABEL_29:
                v33 = v32 >> 12;
                a6[1] = v26 >> 12;
                v15->Core.StartingVpn = v26 >> 12;
                v15->Core.StartingVpnHigh = v26 >> 44;
                v25 = (*(_BYTE *)(a1 + 120) & 1) == 0;
                v15->Core.EndingVpn = v33;
                v15->Core.EndingVpnHigh = BYTE4(v33);
                if( v25 )
                {
                  PlaceholderStorage = MiInsertVadCharges(&v15->Core, *(_QWORD *)(a1 + 88));
                  v31 = PlaceholderStorage;
                  if( PlaceholderStorage >= 0 )
                  {
                    if( Vad )
                    {
                      LOBYTE(v27) = v27 | 1;
                      MiPreparePlaceholderVadReplacement((_RTL_BALANCED_NODE *)Vad, *(_EPROCESS **)(a1 + 88), v11 + 48);
                      ExAcquirePushLockExclusiveEx(&v15->Core.PushLock, 0i64);
                      v34 = Thread;
                    }
                    else
                    {
                      v34 = Thread;
                      MiLockVad(Thread, &v15->Core);
                    }
                    MiInsertPrivateVad(&v15->Core, *(_MI_PHYSICAL_VIEW **)(a1 + 88), v35);
                    if( (v65 & 2) != 0 && MiIsProcessCfgEnabled() )
                      LOBYTE(v27) = 2;
                    v36 = v27 & 2;
                    if( !v36 )
                    {
                      v37.LongFlags = (unsigned int)v15->Core.u;
                      if( ((v37.LongFlags & 0x100000) == 0
                         || (v37.LongFlags & 0x400000) == 0 && (v37.LongFlags & 0xC0000) < 0x80000)
                        && !*(_QWORD *)(a1 + 80) )
                      {
                        v38 = Vad;
                        if( !Vad )
                        {
                          MiUnlockVad(v34, &v15->Core);
                          UNLOCK_ADDRESS_SPACE(v34, *(_EPROCESS **)(a1 + 88));
LABEL_41:
                          *a5 = v26;
                          return 0;
                        }
                        v53 = PushLock;
                        if( (_InterlockedExchangeAdd64(&PushLock->_bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
                          ExfTryToWakePushLock(v53);
                        KeAbPostRelease(v53);
                        UNLOCK_ADDRESS_SPACE_UNORDERED(v34, *(_EPROCESS **)(a1 + 88));
                        v26 = a2;
                        goto LABEL_143;
                      }
                    }
                    UNLOCK_ADDRESS_SPACE_UNORDERED(v34, *(_EPROCESS **)(a1 + 88));
                    MiReferenceVad(&v15->Core);
                    if( v36 && (v40 = MiCommitVadCfgBits(v15, 0i64, &FillSet), v40 < 0)
                      || (v41.LongFlags = (unsigned int)v15->Core.u, (v41.LongFlags & 0x100000) != 0)
                      && ((v41.LongFlags & 0x400000) != 0 || (v41.LongFlags & 0xC0000) >= 0x80000)
                      && (v15->Core.u1.LongFlags1 & 0x80000000) != 0
                      && (v40 = MiMapUserLargePages(&v15->Core, *(unsigned __int8 *)(a1 + 56)), v40 < 0) )
                    {
                      MiDeleteVad(v15, (UINT64)Vad);
                      return v40;
                    }
                    if( !*(_QWORD *)(a1 + 80) )
                    {
LABEL_54:
                      v38 = Vad;
                      if( !Vad )
                      {
                        MiUnlockAndDereferenceVad(&v15->Core);
                        goto LABEL_41;
                      }
                      MiUnlockAndDereferenceNestedVad(&v15->Core);
LABEL_143:
                      MiFinishPlaceholderVadReplacement(v38);
                      goto LABEL_41;
                    }
                    v44 = *(unsigned int *)(a1 + 76);
                    v25 = (*(_DWORD *)(a1 + 60) & 0x40000000) == 0;
                    a6[0] = 0i64;
                    if( v25 )
                    {
                      if( (_DWORD)v44 != -2147483647 && (unsigned int)(v44 - 1) > 1 && (_DWORD)v44 != 4 )
                      {
                        v31 = -1073741755;
                        goto LABEL_141;
                      }
                      LODWORD(ProtectionMask) = 0;
                      v31 = MiSecureVad((_MI_PARTITION *)v15, v26, *(_QWORD *)(a1 + 24), v44, ProtectionMask, (INT64)a6);
                      if( v31 >= 0 )
                      {
                        v45 = a6[0];
LABEL_65:
                        **(_QWORD **)(a1 + 80) = *(&stru_140C4DB30 + 12) ^ *(_QWORD *)(a1 + 88) ^ v45;
                        goto LABEL_54;
                      }
                    }
                    else
                    {
                      v45 = (INT64)MiAddSecureEntry(
                                     (_MI_PARTITION *)v15,
                                     (v15->Core.StartingVpn | ((unsigned __int64)v15->Core.StartingVpnHigh << 32)) << 12,
                                     ((v15->Core.EndingVpn | ((unsigned __int64)v15->Core.EndingVpnHigh << 32)) << 12) | 0xFFF,
                                     v44,
                                     1);
                      if( v45 )
                        goto LABEL_65;
                      v31 = -1073741670;
                    }
LABEL_141:
                    MiDeleteVad(v15, (UINT64)Vad);
                    return v31;
                  }
                }
                else
                {
                  MiStoreGraphicsProtectionInVad((__int64)v15, *(_DWORD *)(a1 + 48));
                  v31 = -1073741637;
                }
                goto LABEL_71;
              }
              v32 = *(_QWORD *)(a1 + 8);
              HIDWORD(ProtectionMask) = HIDWORD(v32);
              MiIsVaRangeAvailable(v30, *(VOID **)a1, *(_QWORD *)(a1 + 24), *(VOID **)a1);
              if( v43 )
                goto LABEL_60;
              v31 = -1073741800;
LABEL_71:
              v28 = Thread;
              goto LABEL_72;
            }
            v31 = -1073741755;
            LOBYTE(v27) = v10;
          }
          else
          {
            v31 = -1073741637;
            LOBYTE(v27) = v10;
          }
        }
        else
        {
          if( !*(_DWORD *)(a1 + 48) )
            goto LABEL_24;
          v31 = -1073741755;
          LOBYTE(v27) = v10;
        }
LABEL_74:
        CurrentThread = Thread;
LABEL_75:
        if( (v27 & 4) != 0 )
          UNLOCK_ADDRESS_SPACE(CurrentThread, *(_EPROCESS **)(a1 + 88));
        MiReleaseVadEventBlocks(&v15->Core);
        ExFreePoolWithTag(v15, 0);
        return v31;
      }
    }
    if( ((unsigned __int8)v47 & 4) != 0 )
    {
      if( ((unsigned __int8)v47 & 0x1A) == 0
        || (!rdx0 ? (ProcessPartition = (INT64)MiGetProcessPartition(*(VOID **)(a1 + 88), v47), CurrentThread = Thread) : (_ETHREAD *)(ProcessPartition = *rdx0),
            (*(_DWORD *)(ProcessPartition + 4) & 0x40) == 0) )
      {
        v31 = -1073741811;
        LOBYTE(v27) = v10;
        goto LABEL_75;
      }
      if( !SeSinglePrivilegeCheck(*(_QWORD *)&SeTcbPrivilege, *(_BYTE *)(a1 + 104)) )
      {
        v31 = -1073741727;
        LOBYTE(v27) = v10;
        goto LABEL_74;
      }
      v15->Core.u.LongFlags |= 0x800000u;
    }
    PlaceholderStorage = MiCreateLargePageVad(*(_EPROCESS **)(a1 + 88), &v15->Core);
    v31 = PlaceholderStorage;
    LOBYTE(v27) = v10;
    if( PlaceholderStorage < 0 )
      goto LABEL_74;
    if( rdx0 )
      *a4 = *(_WORD *)*rdx0;
    v7 = v65;
    if( (*(_BYTE *)(a1 + 120) & 0x1A) != 0 )
      v15->Core.u.LongFlags |= 0x400000u;
    goto LABEL_21;
  }
  return result;
}

Referenced by:

No references.