MmCopyVirtualMemory

INT64 __fastcall MmCopyVirtualMemory(_HHIVE *Hive, INT64 ControlSet, _LIST_ENTRY *DriverListHead){
  __int64 v3; 
  UINT8 *v4; 
  void *v5; 
  unsigned int v6; 
  ULONG_PTR v7; 
  unsigned __int64 v8; 
  int v9; 
  ULONG_PTR v10; 
  char NextEnclaveBoundary; 
  int v12; 
  unsigned __int8 v13; 
  unsigned __int64 v14; 
  UINT64 v15; 
  char i; 
  __int64 v17; 
  UINT8 *v18; 
  int v19; 
  _DWORD *v20; 
  unsigned __int8 v21; 
  int v22; 
  int v23; 
  UINT8 *v24; 
  unsigned __int64 v25; 
  int v26; 
  int v27; 
  bool v29; 
  char *v30; 
  int v31; 
  char *P; 
  int v33; 
  UINT64 ReturnedBytesTransferred; 
  UINT8 *dst; 
  unsigned __int64 v36; 
  unsigned __int64 v37; 
  ULONG_PTR BugCheckParameter1; 
  int v39; 
  size_t *v40; 
  ULONG_PTR v41; 
  unsigned __int64 v42; 
  char *v43; 
  unsigned __int64 v44; 
  void *Src; 
  int v46; 
  size_t v47; 
  __int64 v48; 
  size_t v49; 
  unsigned __int64 v50[5]; 
  _ETHREAD *CurrentThread; 
  __int64 v52; 
  __int64 v53; 
  PMDL v54; 
  _KAPC_STATE ApcState; 
  char MemoryDescriptorList[168]; 
  char v57[512]; 
  size_t Size; 
  char v59; 
  size_t *v60; 
  v4 = (UINT8 *)v3;
  v36 = v3;
  v41 = (ULONG_PTR)DriverListHead;
  v5 = (void *)ControlSet;
  v43 = (char *)ControlSet;
  BugCheckParameter1 = (ULONG_PTR)Hive;
  v50[3] = (unsigned __int64)Hive;
  v50[1] = ControlSet;
  v50[2] = (unsigned __int64)DriverListHead;
  v48 = v3;
  v47 = Size;
  v40 = v60;
  memset(&ApcState, 0, sizeof(ApcState));
  memset((INT64)MemoryDescriptorList, 0i64);
  ReturnedBytesTransferred = 0i64;
  if( !Size )
    return 0i64;
  *v40 = 0i64;
  v6 = 0;
  v44 = 0i64;
  v7 = BugCheckParameter1;
  if( !*(_QWORD *)(BugCheckParameter1 + 1264) )
    v6 = 1;
  Src = v5;
  dst = v4;
  v8 = Size;
  v42 = Size;
  v54 = (PMDL)MemoryDescriptorList;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  v31 = 0;
  P = 0i64;
  v50[4] = 0i64;
  v39 = 0;
  v49 = Size;
  v50[0] = Size;
LABEL_5:
  v9 = ((unsigned __int8)v6 ^ (unsigned __int8)(2 * v6)) & 2 ^ v6;
  if( (*(_BYTE *)(v7 + 992) & 1) != 0 )
    v9 |= 0x40u;
  v10 = v41;
  if( (*(_BYTE *)(v41 + 992) & 1) != 0 )
    v9 |= 0x80u;
  NextEnclaveBoundary = MiFindNextEnclaveBoundary(v7, (unsigned __int64)v5 + Size - v8, v8, &v49);
  v12 = 4 * (NextEnclaveBoundary & 3 | (4 * (MiFindNextEnclaveBoundary(v10, Size - v8 + v36, v8, v50) & 3)));
  v13 = v9 & 0xC3;
  v6 = v9 & 0xFFFFFFC3 | v12;
  if( ((v13 | (unsigned __int8)v12) & 0xC0) != 0 || (v6 & 0xC) != 0 )
    v6 &= ~2u;
  v14 = v8;
  v37 = v8;
  if( v49 < v8 )
  {
    v14 = v49;
    v37 = v49;
  }
  if( v50[0] < v14 )
  {
    v14 = v50[0];
    v37 = v50[0];
  }
LABEL_15:
  if( v14 >= 0x200 && (v6 & 2) != 0 )
  {
    v15 = 57344i64;
    v29 = Size <= 0xE000;
    goto LABEL_73;
  }
  v6 &= ~2u;
  if( v44 )
  {
    v15 = v14;
    if( v14 > v44 )
      v15 = v44;
    goto LABEL_20;
  }
  if( v14 > 0x200 )
  {
    v15 = 0x10000i64;
    if( v8 <= 0x10000 )
      v15 = v8;
    do
    {
      LODWORD(v30) = MiAllocatePool((struct _SLIST_ENTRY *)0x100);
      P = v30;
      if( v30 )
      {
        v44 = v15;
        goto LABEL_86;
      }
      v15 >>= 1;
    }
    while( v15 > 0x200 );
    P = v57;
    v15 = 512i64;
LABEL_86:
    v29 = v14 <= v15;
LABEL_73:
    if( !v29 )
      goto LABEL_20;
    goto LABEL_19;
  }
  P = v57;
LABEL_19:
  v15 = v14;
LABEL_20:
  for( i = v6; ; i = v6 )
  {
    v7 = BugCheckParameter1;
    if( !v14 )
    {
      v5 = v43;
      if( v8 )
        goto LABEL_5;
      if( v44 )
        ExFreePoolWithTag(P, 0);
      *v40 = Size;
      return 0i64;
    }
    v17 = v14;
    if( v14 >= v15 )
      v17 = v15;
    v15 = v17;
    v53 = v17;
    KiStackAttachProcess((_KPROCESS *)BugCheckParameter1, 0i64, &ApcState);
    v18 = (UINT8 *)Src;
    if( v59 && Src == v43 && ((unsigned __int64)&v43[Size] > 0x7FFFFFFF0000i64 || &v43[Size] < v43) )
      MEMORY[0x7FFFFFFF0000] = 0;
    v19 = i & 2;
    v33 = v19;
    v46 = v19;
    if( (i & 2) != 0 )
    {
      *(_QWORD *)MemoryDescriptorList = 0i64;
      *(_WORD *)&MemoryDescriptorList[8] = 8 * (((v15 + ((unsigned __int16)Src & 0xFFF) + 4095i64) >> 12) + 6);
      *(_WORD *)&MemoryDescriptorList[10] = 0;
      *(_QWORD *)&MemoryDescriptorList[32] = (unsigned __int64)Src & 0xFFFFFFFFFFFFF000ui64;
      *(_DWORD *)&MemoryDescriptorList[44] = (unsigned __int16)Src & 0xFFF;
      *(_DWORD *)&MemoryDescriptorList[40] = v15;
      v19 = i & 2;
    }
    v20 = (_DWORD *)((char *)CurrentThread + 116);
    v52 = (__int64)CurrentThread + 116;
    v21 = _bittestandset((signed __int32 *)CurrentThread + 29, 5u);
    if( v19 )
    {
      MmProbeAndLockPages((_MDL *)MemoryDescriptorList, v59, IoReadAccess);
      v22 = v31;
    }
    else
    {
      if( (v6 & 0x40) != 0 || (v6 & 0xC) == 8 )
      {
        v23 = VslDebugReadWriteSecureProcess(
                BugCheckParameter1,
                (INT64)v18,
                (INT64)P,
                v15,
                1u,
                &ReturnedBytesTransferred);
      }
      else
      {
        if( (v6 & 0xC) != 4 )
        {
          memmove((UINT8 *)P, v18, v15);
          v22 = v31;
          goto LABEL_40;
        }
        v23 = MiDbgReadWriteEnclave(v18, P, v15, 1ui64, &ReturnedBytesTransferred);
      }
      v31 = v23;
      v22 = v23;
    }
LABEL_40:
    if( !v21 )
      *v20 &= ~0x20u;
    if( v22 < 0 )
      break;
    if( v33 )
    {
      v24 = (UINT8 *)MmMapLockedPagesSpecifyCache((PMDL)MemoryDescriptorList, 0, MmCached, 0i64, 0, 0xC0000020);
      if( v24 )
        goto LABEL_45;
      MmUnlockPages((_MDL *)MemoryDescriptorList);
LABEL_87:
      v6 &= ~2u;
      KiUnstackDetachProcess(&ApcState, 0i64);
      v8 = v42;
      goto LABEL_15;
    }
    v24 = (UINT8 *)P;
LABEL_45:
    KiUnstackDetachProcess(&ApcState, 0i64);
    KiStackAttachProcess((_KPROCESS *)v41, 0i64, &ApcState);
    if( v59 && Src == v43 )
    {
      v25 = v36;
      if( Size + v36 > 0x7FFFFFFF0000i64 || Size + v36 < v36 )
        MEMORY[0x7FFFFFFF0000] = 0;
    }
    else
    {
      v25 = v36;
    }
    if( (v6 & 0x80u) != 0 || (v6 & 0x30) == 32 )
    {
      v27 = VslDebugReadWriteSecureProcess(v41, (INT64)dst, (INT64)P, v15, 0, &ReturnedBytesTransferred);
    }
    else
    {
      if( (v6 & 0x30) != 16 )
      {
        memmove(dst, v24, v15);
        v26 = 0;
        v31 = 0;
        ReturnedBytesTransferred = v15;
        goto LABEL_54;
      }
      v27 = MiDbgReadWriteEnclave(dst, P, v15, 0i64, &ReturnedBytesTransferred);
    }
    v31 = v27;
    v26 = v27;
LABEL_54:
    if( v26 == -1073741819 )
    {
      *v40 = (size_t)&dst[ReturnedBytesTransferred - v25];
      v26 = -2147483635;
      goto LABEL_79;
    }
    if( v26 < 0 )
      goto LABEL_79;
    KiUnstackDetachProcess(&ApcState, 0i64);
    if( v33 )
      MmUnlockPages((_MDL *)MemoryDescriptorList);
    v14 -= v15;
    v37 = v14;
    v8 = v42 - v15;
    v42 -= v15;
    Src = (char *)Src + v15;
    dst += v15;
  }
  if( v33 )
    goto LABEL_87;
  *v40 = Size - v14;
  v26 = -2147483635;
LABEL_79:
  KiUnstackDetachProcess(&ApcState, 0i64);
  if( v44 )
    ExFreePoolWithTag(P, 0);
  return(unsigned int)v26;
}

Referenced by:

KiTpWriteUmMemory
LpcpCopyRequestData
MiReadWriteVirtualMemory
NtQueryInformationProcess
NtQueryInformationThread
PsQueryProcessCommandLine