MiCopyOnWrite

NTSTATUS __stdcall MiCopyOnWrite(UINT64 rcx0, INT64 *a2, UINT64 Page, INT64 a4){
  unsigned __int64 v4; 
  int v6; 
  _MMPFN *v7; 
  unsigned int v8; 
  __int64 Blink; 
  _BOOL4 v10; 
  NTSTATUS SystemRegionType; 
  VOID *v12; 
  VOID *v13; 
  int v14; 
  unsigned int v15; 
  int v16; 
  int v17; 
  unsigned int v19; 
  unsigned int v20; 
  unsigned __int64 v21; 
  UINT8 v22; 
  int v23; 
  char v24; 
  NTSTATUS WsleProtection; 
  UINT64 v26; 
  unsigned __int64 v27; 
  int v28; 
  signed __int32 v29; 
  UINT64 v30; 
  _MI_PARTITION *v31; 
  _MMPFN *PfnDb; 
  _MMVAD *Address; 
  unsigned int v34; 
  _MMPFN *v35; 
  volatile __int64 *v36; 
  _MMPTE *v37; 
  _MMPTE *v38; 
  unsigned __int64 *v39; 
  unsigned __int64 v40; 
  _ETHREAD *CurrentThread; 
  unsigned int PagePriorityThread; 
  int v43; 
  unsigned __int64 v44; 
  unsigned int v45; 
  UINT64 v46; 
  bool v47; 
  _MMSUPPORT_INSTANCE *v48; 
  UINT64 v49; 
  UINT64 v50; 
  _MMPTE *PxeUserLimit; 
  _EPROCESS *v52; 
  char v53; 
  _MI_PAGE_DELETE_RESULT v54; 
  _MMCLONE_DESCRIPTOR *CloneAddress; 
  ULONG_PTR v56; 
  _MMVAD **BugCheckParameter4; 
  int v58; 
  int v59; 
  _MMSUPPORT_INSTANCE *SessionVm; 
  UINT64 v62; 
  int v63; 
  int v64; 
  int v65; 
  UINT64 SpinCount; 
  char ControlArea[140]; 
  _MMSUPPORT_INSTANCE Vm; 
  __int128 v69; 
  __int128 v70; 
  __int128 v71; 
  __int128 v72; 
  __int128 v73; 
  __int128 v74; 
  __int128 v75; 
  __int128 v76; 
  __int128 v77; 
  __int64 v78; 

  v4 = *a2;
  HIWORD(Vm.PeakWorkingSetSize) = 0;
  *(_OWORD *)&ControlArea[52] = 0i64;
  v78 = 0i64;
  v69 = 0i64;
  v63 = a4;
  v70 = 0i64;
  *(_QWORD *)&ControlArea[20] = a2;
  v71 = 0i64;
  v72 = 0i64;
  v73 = 0i64;
  v74 = 0i64;
  v75 = 0i64;
  v76 = 0i64;
  v77 = 0i64;
  memset(&ControlArea[108], 0, 32);
  LOBYTE(v6) = MiPteInShadowRange((UINT64)a2);
  v65 = v6;
  v62 = v4;
  MiPteInShadowRange((UINT64)&v62);
  *(_QWORD *)&ControlArea[100] = (v4 >> 12) & 0xFFFFFFFFFi64;
  v7 = &MmGetPfnDb()[*(_QWORD *)&ControlArea[100]];
  *(_QWORD *)&ControlArea[4] = 0i64;
  v8 = 0;
  Blink = (__int64)v7->ListEntry.Blink;
  v10 = (v4 & 0x200) == 0;
  *(_QWORD *)&ControlArea[36] = Blink | 0x8000000000000000ui64;
  *(_QWORD *)&ControlArea[12] = KeGetCurrentThread()->ApcState.Process;
  SystemRegionType = MiGetSystemRegionType(rcx0);
  if( SystemRegionType == 1 )
  {
    SessionVm = MiGetSessionVm(1i64, (INT64)v12, 2);
    v15 = (v4 & 0x200) == 0;
    if( (v7->u4._bf_0 & 0x1000000000i64) == 0 && Blink > 0 )
      v15 = v14 | v10;
    v58 = v14;
  }
  else if( SystemRegionType == 12 )
  {
    v58 = 0;
    SessionVm = MiGetAnyMultiplexedVm(MiWorkingSetTypeSystemViews, v12);
    v15 = (v4 & 0x200) == 0;
    if( (v7->u4._bf_0 & 0x1000000000i64) == 0 && Blink > 0 )
      v15 = v16 | v10;
  }
  else
  {
    if( SystemRegionType == 9 || SystemRegionType == 14 )
      KeBugCheckEx(0x1Au, (PVOID)0x3300, (PVOID)rcx0, (PVOID)v4, (PVOID)2);
    if( SystemRegionType == 6 )
    {
      v58 = 0;
      SessionVm = MiGetAnyMultiplexedVm(MiWorkingSetTypePagedPool, v12);
      v15 = v17 | v10;
      if( (v7->u4._bf_0 & 0x1000000000i64) != 0 || Blink <= 0 )
        KeBugCheckEx(0x1Au, (PVOID)0x3300, (PVOID)rcx0, (PVOID)v4, 0i64);
    }
    else
    {
      if( SystemRegionType == 5 )
        KeBugCheckEx(0x1Au, (PVOID)0x3300, (PVOID)rcx0, (PVOID)v4, (PVOID)1);
      if( *(_QWORD *)(*(_QWORD *)&ControlArea[12] + 1248i64) )
        return -1073740748;
      v58 = 1;
      v15 = (v4 & 0x200) == 0;
      SessionVm = (_MMSUPPORT_INSTANCE *)(*(_QWORD *)&ControlArea[12] + 1664i64);
      if( (v7->u4._bf_0 & 0x1000000000i64) == 0 && Blink > 0 )
        v15 = v10 | 2;
      Vm.AgeDistribution[2] = *(_QWORD *)&ControlArea[12] + 1664i64;
      memset(&Vm.TrimmedPageCount, 0, 48);
      *(_QWORD *)&Vm.NextPageColor = rcx0;
      memset(&Vm.AgeDistribution[3], 0, 72);
      MiComputeFaultNode(&Vm, 0i64, (_CONTROL_AREA *)&ControlArea[4], v13, BugCheckParameter4);
      v8 = v19;
    }
  }
  v20 = 0;
  *(_QWORD *)&ControlArea[44] = *(_QWORD *)(*(&stru_140C4DB30 + 267) + 8i64 * SessionVm->PartitionId);
  HIDWORD(SpinCount) = (__int64)v7->ListEntry.Flink & 1;
  *(_QWORD *)&ControlArea[92] = (char *)MmGetPteBase() + ((rcx0 >> 9) & 0x7FFFFFFFF8i64);
  v21 = **(_QWORD **)&ControlArea[92];
  MiPteInShadowRange(*(UINT64 *)&ControlArea[92]);
  v22 = HIBYTE(v21) & 0xF | (16 * ((v21 >> 60) & 7));
  v64 = v63 & 1;
  if( (v63 & 1) != 0 || (HIBYTE(v21) & 0xF) == 10 )
  {
    v23 = v58;
  }
  else
  {
    v23 = v58;
    if( (HIBYTE(v21) & 0xF) == 9 )
    {
      v22 = (16 * ((v21 >> 60) & 7)) | 0xA;
    }
    else if( v58 != 1 && (*((_BYTE *)&v7->u3 + 3) & 8) != 0 )
    {
      v22 = (16 * ((v21 >> 60) & 7)) | 0xA;
    }
  }
  v24 = v22 & 0xF;
  if( (v22 & 0xF) == 10 )
    goto LABEL_37;
  if( v24 == 8 && v23 != 2 )
  {
    v20 = 1;
    if( (*(_DWORD *)(&v7->3 + 1) & 0x400i64) != 0 )
      v20 = 2;
  }
  WsleProtection = MiGetWsleProtection(rcx0, v22);
  if( !WsleProtection )
  {
LABEL_37:
    LODWORD(v27) = MI_READ_PTE_LOCK_FREE((INT64)&v7->OriginalPte.u.Hard);
    WsleProtection = (v27 >> 5) & 0x1F;
  }
  v28 = MmMakeProtectNotWriteCopy[WsleProtection];
  v59 = v28;
  if( Page == -1i64 )
  {
    MiInitializePageColorBase(SessionVm, v8, (_MI_COLOR_BASE *)&ControlArea[52]);
    v29 = _InterlockedExchangeAdd(*(volatile signed __int32 **)&ControlArea[52], 1u);
    LODWORD(v30) = MiGetPage(
                     *(ULONG_PTR **)&ControlArea[44],
                     *(_DWORD *)&ControlArea[60] & (unsigned int)v29 | *(_DWORD *)&ControlArea[64],
                     0i64);
    Page = v30;
    if( v30 == -1i64 )
      return -1073741801;
  }
  if( v20 )
  {
    if( v20 >= 2 )
    {
      v31 = *(_MI_PARTITION **)(*(&stru_140C4DB30 + 267) + 8 * (((unsigned __int64)v7->u4._bf_0 >> 39) & 0x3FF));
      MiReturnCommit(v31, 1ui64);
      if( v58 == 1 )
        _InterlockedDecrement64((volatile signed __int64 *)&v31->Vp.ProcessLockedFilePages);
      v28 = v59;
    }
    PfnDb = MmGetPfnDb();
    MiUnlockPageTableCharges((_DWORD)PfnDb + 48 * LODWORD(v7->u4._bf_0), 1u, v26);
  }
  else
  {
    PfnDb = MmGetPfnDb();
  }
  if( v28 == 24 )
  {
    Address = *(_MMVAD **)&ControlArea[4];
    LOBYTE(v28) = 1;
    LOBYTE(v59) = 1;
    if( *(_QWORD *)&ControlArea[4]
      || (Address = MiLocateAddress((VOID *)rcx0), (*(_QWORD *)&ControlArea[4] = Address) != 0i64) )
    {
      v34 = (Address->Core.u.LongFlags >> 7) & 0x1F;
      if( v34 >> 3 == 3 && (v34 & 7) != 0 )
      {
        LOBYTE(v28) = 25;
      }
      else if( v34 >> 3 == 1 )
      {
        LOBYTE(v28) = 9;
      }
      LOBYTE(v59) = v28;
    }
  }
  v35 = &PfnDb[Page];
  v35->OriginalPte.u.Long = MiSwizzleInvalidPte(32i64 * (v28 & 0x1F));
  if( v24 == 10 )
  {
    v38 = *(_MMPTE **)&ControlArea[20];
  }
  else
  {
    v36 = (volatile __int64 *)((char *)&stru_140C4DB30 + 6608);
    *(_QWORD *)&ControlArea[84] = 0i64;
    if( (SessionVm->Flags._bf_0 & 7) != 2 )
      v36 = (volatile __int64 *)&SessionVm[1].AgeDistribution[3];
    *(_QWORD *)&ControlArea[76] = v36;
    *(_QWORD *)&ControlArea[68] = 0i64;
    if( _InterlockedExchange64(v36, (__int64)&ControlArea[68]) )
      KxWaitForLockOwnerShip((INT64)&ControlArea[68]);
    ++SessionVm->WorkingSetPrivateSize;
    if( rcx0 < (unsigned __int64)MmGetPteBase() || rcx0 > (unsigned __int64)MmGetPteLimit() )
      ++SessionVm->WorkingSetLeafPrivateSize;
    KeReleaseInStackQueuedSpinLockFromDpcLevel((PKLOCK_QUEUE_HANDLE)&ControlArea[68]);
    v37 = *(_MMPTE **)&ControlArea[92];
    MiPteInShadowRange(*(UINT64 *)&ControlArea[92]);
    MiWriteValidPteVolatile(v37, 0x80000000ui64);
    v38 = *(_MMPTE **)&ControlArea[20];
    v62 = **(_QWORD **)&ControlArea[20];
  }
  v35->u3.ReferenceCount = 1;
  v39 = (unsigned __int64 *)((char *)&MmGetPteBase()->u.Long + (((unsigned __int64)v38 >> 9) & 0x7FFFFFFFF8i64));
  v40 = *v39;
  MiPteInShadowRange((UINT64)v39);
  *(_QWORD *)&ControlArea[28] = v40;
  MiPteInShadowRange((UINT64)&ControlArea[28]);
  v35->u4._bf_0 ^= (v35->u4._bf_0 ^ (v40 >> 12)) & 0xFFFFFFFFFi64;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  if( (CurrentThread->SameThreadApcFlags & 0x100) != 0 )
    PagePriorityThread = (CurrentThread->SameThreadApcFlags & 0xE00) >> 9;
  else
    PagePriorityThread = PsGetPagePriorityThread(CurrentThread);
  LODWORD(SpinCount) = 0;
  while( _interlockedbittestandset64((volatile signed __int32 *)&v35->u2, 0x3Fui64) )
  {
    do
      KeYieldProcessorEx(&SpinCount);
    while( v35->u2._bf_0 < 0 );
  }
  if( HIDWORD(SpinCount) )
    v35->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 |= 1ui64;
  *((_BYTE *)&v35->u3 + 2) |= 0x10u;
  if( v58 || (*((_BYTE *)&v7->u3 + 3) & 8) == 0 || v64 )
    *((_BYTE *)&v35->u3 + 3) &= ~8u;
  else
    *((_BYTE *)&v35->u3 + 3) |= 8u;
  v43 = *((unsigned __int8 *)&v7->u3 + 2) >> 6;
  if( *((unsigned __int8 *)&v35->u3 + 2) >> 6 != v43 )
    MiChangePageAttribute(v35, (_MI_PFN_CACHE_ATTRIBUTE)v43, 1ui64);
  MiSetPfnTbFlushStamp(v35, 0i64, 1ui64);
  v44 = v35->u2._bf_0 & 0xC000000000000001ui64;
  v35->PteLong = (unsigned __int64)v38;
  v35->u2._bf_0 = v44 | 1;
  *((_BYTE *)&v35->u3 + 3) ^= (*((_BYTE *)&v35->u3 + 3) ^ PagePriorityThread) & 7;
  *((_BYTE *)&v35->u3 + 2) = *(_BYTE *)(&v35->u3 + 1) & 0xF8 | 6;
  if( v15 >= 4 )
    MiIdentifyPfn(v35, (_MMPFN_IDENTITY *)&ControlArea[108]);
  _InterlockedAnd64(&v35->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
  if( v15 >= 4 )
  {
    *(_QWORD *)&ControlArea[132] |= 8ui64;
    Vm.WorkingSetPrivateSize = (unsigned __int64)&ControlArea[108];
    Vm.MaximumWorkingSetSize = 32i64;
    EtwTraceKernelEvent((__int64)&Vm.WorkingSetPrivateSize, 1u, 0x28000001u, 0x282u, 0x11401B02u);
  }
  __incgsdword(0x2E94u);
  v45 = 1;
  if( (v59 & 2) == 0 )
  {
    v45 = 9;
LABEL_88:
    v46 = rcx0;
    goto LABEL_89;
  }
  if( (MiFlags & 0x40000) != 0 )
    goto LABEL_88;
  v46 = rcx0;
  if( (MiFlags & 0x10000) == 0 )
  {
LABEL_89:
    if( v46 >= 0xFFFF800000000000ui64 )
      goto LABEL_92;
    goto LABEL_90;
  }
  if( rcx0 >= 0xFFFF800000000000ui64 )
  {
    v45 = 17;
    if( (v63 & 2) != 0 )
      v45 = 49;
    goto LABEL_89;
  }
LABEL_90:
  if( (*(_BYTE *)&KeGetCurrentThread()->ApcState.Process->Pcb.SecureState & 1) != 0 )
    v45 |= 0x10u;
LABEL_92:
  MiCopyPage(Page, *(UINT64 *)&ControlArea[100], 0i64, v45);
  if( *(&stru_140C4DB30 + 654) )
  {
    v47 = PagePriorityThread < *(&stru_140C4DB30 + 655);
    v48 = SessionVm;
    if( !v47 )
      MiLogPageAccess(SessionVm, v38);
  }
  else
  {
    v48 = SessionVm;
  }
  v49 = v62;
  if( (v15 & 1) == 0 )
  {
    if( (v62 & 0x8000000000000000ui64) != 0i64 || v58 != 1 )
      v49 = v62 | 0x42;
    v49 = v49 & 0xFFFFFFFFFFFFF5DFui64 | 0x820;
  }
  *(_QWORD *)&Vm.HardFaultCount = 20i64;
  v50 = v49 ^ (v49 ^ (Page << 12)) & 0xFFFFFFFFF000i64;
  WORD2(Vm.PeakWorkingSetSize) = 0;
  Vm.SelfmapLock = 0i64;
  *(_QWORD *)&Vm.Flags._bf_0 = 0i64;
  v62 = v50;
  LODWORD(Vm.PeakWorkingSetSize) = v58;
  MiInsertTbFlushEntry(
    (_MI_TB_FLUSH_LIST *)&Vm.PeakWorkingSetSize,
    (VOID *)(rcx0 & 0xFFFFFFFFFFFFF000ui64),
    1ui64,
    0i64);
  if( (v45 & 0x20) != 0 || (v50 & 0x42) == 0 )
  {
    MI_INTERLOCKED_EXCHANGE_PTE((INT64 *)v38, v50);
    MiFlushTbList((_MI_TB_FLUSH_LIST *)&Vm.PeakWorkingSetSize);
  }
  else
  {
    PxeUserLimit = MmGetPxeUserLimit();
    v38->u.Long = v50 & 0xFFFFFFFFFFFFFBFEui64 | 0x400;
    MiFlushTbList((_MI_TB_FLUSH_LIST *)&Vm.PeakWorkingSetSize);
    if( v38 >= MmGetPml4eBase()
      && v38 <= PxeUserLimit
      && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0
      && (v50 & 1) != 0 )
    {
      v50 |= 0x8000000000000000ui64;
    }
    v38->u.Long = v50;
  }
  v52 = *(_EPROCESS **)&ControlArea[12];
  if( v58 == 1 )
    _InterlockedExchangeAdd64((volatile signed __int64 *)(*(_QWORD *)&ControlArea[12] + 1272i64), 1ui64);
  *(_DWORD *)ControlArea = 0;
  while( _interlockedbittestandset64((volatile signed __int32 *)&v7->u2, 0x3Fui64) )
  {
    do
      KeYieldProcessorEx((UINT64 *)ControlArea);
    while( v7->u2._bf_0 < 0 );
  }
  if( !v58 && !v64 )
  {
    v53 = *((_BYTE *)&v7->u3 + 3);
    if( (v53 & 8) != 0 )
      *((_BYTE *)&v7->u3 + 3) = v53 & 0xF7;
  }
  MiDecrementShareCount(v7);
  _InterlockedAnd64(&v7->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
  if( (v15 & 2) != 0 )
  {
    v54 = MiDecrementCombinedPte((_MMPTE *)v48);
  }
  else
  {
    if( (v48->Flags._bf_0 & 7) != 0 )
      return 0;
    CloneAddress = MiLocateCloneAddress(v52, *(VOID **)&ControlArea[36]);
    if( !CloneAddress )
      return 0;
    v54 = MiDecrementCloneBlockReference((ULONG_PTR)CloneAddress, v56, (ULONG_PTR)v52);
  }
  if( v54 == PageStillReferenced )
    MiChargeCommit(*(_MI_PARTITION **)&ControlArea[44], 1ui64, 4ui64);
  return 0;
}

Referenced by:

MiCompleteProtoPteFault
MiCopyToUserVa
MiFaultInPagedPool
MiLockCode
MiLockDriverPageRange
MiLockPagedAddress
MiMakeDriverPagesPrivate
MiMakeProtoPrivate
MiPrepareImagePagesForHotPatch
MiProbeLeafPteAccess
MiSetProtectionOnSection
MiSplitPrivatePage
MiSplitReducedCommitClonePage
MiSystemFault
MiValidFault
MiValidVirtualizationFault
MiWalkVaRange
MmProtectPool
MmReplaceImportEntry