MiSplitPrivatePage

INT64 __fastcall MiSplitPrivatePage(UINT64 rcx0, INT64 a2){
  __int64 v3; 
  INT64 v4; 
  signed __int64 v5; 
  __int64 v6; 
  ULONG_PTR v7; 
  int v8; 
  __int64 v9; 
  char *v10; 
  unsigned int v11; 
  char v12; 
  UINT8 v13; 
  UINT64 v14; 
  unsigned __int64 v15; 
  ULONG_PTR v16; 
  volatile INT64 *v17; 
  int v18; 
  _MMPTE *v19; 
  INT64 v20; 
  _MMPFN *UsedPtesHandle; 
  __int16 v22; 
  unsigned __int64 v23; 
  UNICODE_STRING *v24; 
  UINT8 v25; 
  PWCHAR v26; 
  int v27; 
  __int64 v28; 
  int v29; 
  __int64 v30; 
  int v32; 
  int v33; 
  unsigned __int64 v34; 
  ULONG_PTR v35; 
  int v36; 
  INT64 v37; 
  int v38; 
  int v39; 
  __int64 v40; 
  int a6; 
  _ETHREAD *CurrentThread; 
  ULONG_PTR v43; 
  _MMPTE *ProtoPteAddress; 
  void *ContainingSubsection[11]; 
  UINT8 WsIrql; 
  int v49; 
  a6 = 0;
  v3 = a2;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  v43 = *((_QWORD *)CurrentThread + 23);
  v4 = v43 + 1664;
  v38 = MiVadPureReserve(a2);
  v5 = (signed __int64)MmGetPteBase() + ((rcx0 >> 9) & 0x7FFFFFFFF8i64);
  ContainingSubsection[0] = *(void **)(v6 + 72);
  v8 = MiChargeFullProcessCommitment(v7, 1ui64);
  v9 = v8;
  v10 = 0i64;
  v11 = (*(_DWORD *)(v3 + 48) >> 12) & 0x3F;
  v49 = v8;
  v36 = 0;
  v39 = 0;
  v12 = MiLockWorkingSetShared(v43 + 1664);
  WsIrql = v12;
  v40 = v9;
  while( 1 )
  {
    v13 = v12;
    v14 = v5;
    if( v38 )
      break;
LABEL_11:
    MiMakeSystemAddressValid(v14, 0i64, v11, v13, 0);
LABEL_12:
    ProtoPteAddress = MiGetProtoPteAddress((_MMVAD *)v3, rcx0 >> 12, 0i64, (_SUBSECTION **)ContainingSubsection);
    v19 = ProtoPteAddress;
    v37 = MI_READ_PTE_LOCK_FREE(v5);
    v20 = v37;
    if( !v37 )
    {
      if( v40 < 0 )
        goto LABEL_47;
      UsedPtesHandle = MiGetUsedPtesHandle(rcx0);
      MiIncreaseUsedPtesCount(UsedPtesHandle, 1ui64);
      if( v38 )
      {
        if( !v19
          || (v22 = MI_READ_PTE_LOCK_FREE((INT64)MmGetPteBase() + (((unsigned __int64)v19 >> 9) & 0x7FFFFFFFF8i64)),
              (v22 & 1) == 0)
          && (v22 & 0x3E0) == 0 )
        {
          v36 = 1;
LABEL_44:
          v32 = v49;
          goto LABEL_45;
        }
      }
      v37 = MiSwizzleInvalidPte(-4294966240i64);
      v20 = v37;
      *(_QWORD *)v5 = v37;
      v3 = a2;
      v19 = ProtoPteAddress;
    }
    if( (v20 & 1) != 0 )
    {
      v23 = MI_READ_PTE_LOCK_FREE((INT64)&v37);
      LOBYTE(v27) = MI_PFN_IS_PROTO((UNICODE_STRING *)MmGetPfnDb() + 3 * ((v23 >> 12) & 0xFFFFFFFFFi64), v24, v25, v26);
      if( !v27 || (_MMPTE *)(*(_QWORD *)(v28 + 8) | 0x8000000000000000ui64) != v19 )
        goto LABEL_55;
      if( v40 < 0 )
      {
LABEL_47:
        if( v10 )
          MiUnlockPageTableInternal(v4, (UINT64)v10);
        v32 = v49;
LABEL_50:
        MiUnlockWorkingSetShared(v4, WsIrql);
        return(unsigned int)v32;
      }
      v29 = MiCopyOnWrite(rcx0, (UINT64 *)v5, -1i64, 0i64);
      if( v29 >= 0 )
        goto LABEL_44;
      if( v10 )
      {
        MiUnlockPageTableInternal(v4, (UINT64)v10);
        v10 = 0i64;
      }
      v12 = WsIrql;
      MiUnlockWorkingSetShared(v4, WsIrql);
      MiCopyOnWriteCheckConditions(v4, (unsigned int)v29);
      MiLockWorkingSetShared(v4);
      v9 = v40;
    }
    else
    {
      if( (v20 & 0x400) == 0 )
        goto LABEL_55;
      if( !MiIsPrototypePteVadLookup(v20) )
      {
        v30 = v20;
        if( qword_140C4DC80 && (v20 & 0x10) == 0 )
          v30 = v20 & ~qword_140C4DC80;
        if( (_MMPTE *)(v30 >> 16) != v19 )
        {
LABEL_55:
          v33 = 0;
          v32 = v49;
          goto LABEL_56;
        }
      }
      v12 = WsIrql;
      if( (int)MiMakeProtoLeafValid((MMPTE *)v5, 0x18ui64, WsIrql) < 0 && v20 == MI_READ_PTE_LOCK_FREE(v5) )
      {
        v32 = v49;
        if( v49 < 0 )
        {
          if( v10 )
            MiUnlockPageTableInternal(v4, (UINT64)v10);
          goto LABEL_50;
        }
        v36 = 1;
LABEL_45:
        v33 = 1;
        v34 = ((((unsigned __int64)*(unsigned __int8 *)(a2 + 34) << 31) | *(_DWORD *)(a2 + 52) & 0x7FFFFFFF) + 1) >> 31;
        *(_DWORD *)(a2 + 52) ^= (*(_DWORD *)(a2 + 52) ^ (((*(unsigned __int8 *)(a2 + 34) << 31) | *(_DWORD *)(a2 + 52) & 0x7FFFFFFF)
                                                       + 1)) & 0x7FFFFFFF;
        *(_BYTE *)(a2 + 34) = v34;
        if( v36 == 1 )
        {
          v37 = MiSwizzleInvalidPte(32i64);
          *(_QWORD *)v5 = v37;
          v33 = 1;
        }
LABEL_56:
        if( v10 )
          MiUnlockPageTableInternal(v4, (UINT64)v10);
        MiUnlockWorkingSetShared(v4, WsIrql);
        v35 = v43;
        if( v39 == 1 )
        {
          if( (_InterlockedExchangeAdd64((volatile signed __int64 *)(v43 + 1232), 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
            ExfTryToWakePushLock((volatile INT64 *)(v35 + 1232));
          KeAbPostRelease((PVOID)(v35 + 1232));
          KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
        }
        if( !v33 && v32 >= 0 )
          MiReturnFullProcessCommitment(v35, 1ui64);
        return 0i64;
      }
      v9 = v40;
      if( v10 )
      {
        MiUnlockPageTableInternal(v4, (UINT64)v10);
        v10 = 0i64;
      }
    }
  }
  MiGetNextPageTable(v5, v5, 0i64, v12, 0, &a6);
  if( v15 )
    v10 = (char *)MmGetPteBase() + ((v15 >> 9) & 0x7FFFFFFFF8i64);
  if( v5 == v15 )
    goto LABEL_12;
  if( v10 )
    MiUnlockPageTableInternal(v4, (UINT64)v10);
  MiUnlockWorkingSetShared(v4, v12);
  if( v9 < 0 )
    return(unsigned int)v49;
  v39 = 1;
  --*((_WORD *)CurrentThread + 243);
  v16 = v43;
  v17 = (volatile INT64 *)(v43 + 1232);
  ExAcquirePushLockExclusiveEx(v43 + 1232, 0i64);
  v18 = MiCommitPageTablesForVad(v3, rcx0, rcx0);
  if( v18 >= 0 )
  {
    v10 = (char *)MmGetPteBase() + (((unsigned __int64)v5 >> 9) & 0x7FFFFFFFF8i64);
    WsIrql = MiLockWorkingSetShared(v4);
    v13 = WsIrql;
    v14 = v5;
    goto LABEL_11;
  }
  if( (_InterlockedExchangeAdd64(v17, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
    ExfTryToWakePushLock(v17);
  KeAbPostRelease((PVOID)v17);
  KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
  if( v49 >= 0 )
    MiReturnFullProcessCommitment(v16, 1ui64);
  return(unsigned int)v18;
}

Referenced by:

MiCopyToCfgBitMap