MiCopyPagesIntoEnclave

NTSTATUS __stdcall MiCopyPagesIntoEnclave(
        PVOID TargetProcess,
        INT64 PreviousMode,
        VOID *BaseAddress,
        VOID *Buffer,
        UINT64 BufferSize,
        UINT64 Win32ProtectionMask,
        UINT64 *BytesWritten,
        UINT64 *ReturnedError){
  UINT64 v10; 
  VOID *Pool; 
  unsigned int ProtectionMask; 
  int v13; 
  int v15; 
  int v16; 
  unsigned __int64 v17; 
  _MMPTE *PteAddress; 
  _MMPTE *v19; 
  _EPROCESS *v20; 
  INT64 v21; 
  int v22; 
  unsigned __int64 v23; 
  unsigned int v24; 
  char v25; 
  unsigned __int64 v26; 
  _BYTE *v27; 
  INT64 v28; 
  INT64 v29; 
  char *v30; 
  signed __int64 v31; 
  UINT64 v32; 
  UINT64 v33; 
  unsigned __int64 Long; 
  int v35; 
  INT64 v36; 
  INT64 v37; 
  UINT64 BugCheckOnFailure; 
  UINT64 Priority; 
  char v40; 
  _MMPTE *PointerPte; 
  int PageType; 
  unsigned int PageType_4; 
  char *EnclaveAddress; 
  UINT64 PteFromCopyList; 
  _MI_PARTITION *VmPartition; 
  __int64 EnclaveControlAddress; 
  UINT64 v50; 
  _MMPTE *v51; 
  _MMPTE_COPY_LIST PteCopyList[4]; 
  __int64 v53; 
  _KAPC_STATE ApcState; 
  _MDL MemoryDescriptorList[4]; 
  UINT64 *v56; 

  EnclaveAddress = (char *)Buffer;
  v40 = (char)BaseAddress;
  v10 = BufferSize;
  memset(&ApcState, 0, sizeof(ApcState));
  *(_OWORD *)PteCopyList = 0i64;
  v53 = 0i64;
  memset(MemoryDescriptorList, 0i64, 0xB8u);
  Pool = 0i64;
  ProtectionMask = MiMakeProtectionMask((unsigned int)BytesWritten & 0x5FFFFFFF);
  if( (ProtectionMask & 7) == 0 || ProtectionMask > 7 || (ProtectionMask & 5) == 5 )
    return -1073741755;
  if( (ProtectionMask & 2) != 0 )
  {
    if( (KeGetCurrentThread()->ApcState.Process->MitigationFlags & 0x100) != 0
      && (*(_DWORD *)&KeGetCurrentThread()[1].gapD8[8] & 0x40000) == 0 )
    {
      return -1073740284;
    }
    v13 |= 4u;
  }
  v15 = v13 | 2;
  if( (ProtectionMask & 4) == 0 )
    v15 = v13;
  PageType = (32 * (*(_DWORD *)(PreviousMode + 64) & 2)) | v15 | 1;
  v16 = ProtectionMask & 2 | 4;
  if( (*(_DWORD *)(PreviousMode + 72) & 1) == 0 )
    v16 = ProtectionMask;
  PageType_4 = v16;
  PteAddress = MiGetPteAddress(Buffer);
  PointerPte = PteAddress;
  v19 = &PteAddress[v17 - 1];
  v51 = v19;
  if( v17 > 0x14 )
    v17 = 20i64;
  MiCreatePteCopyList(v17 + 1, v17 + 1, PteCopyList);
  if( !PteCopyList[1] )
    return -1073741670;
  if( (BufferSize & 0xFFF) == 0 || (Pool = MiAllocatePool(256i64, 0x10000ui64, 0x44456D4Dui64)) != 0i64 )
  {
    VmPartition = MiGetVmPartition((char *)TargetProcess + 1664, v20);
    v22 = 0;
    *ReturnedError = 0i64;
    EnclaveControlAddress = (__int64)((*(_QWORD *)(PreviousMode + 80) << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16;
    while( PteAddress <= v19 )
    {
      v23 = ((char *)v19 - (char *)PteAddress + 8) >> 3;
      v24 = 16;
      if( v23 < 0x10 )
        v24 = v23;
      v25 = v40;
      if( v40 == 1 )
      {
        if( v24 )
        {
          v26 = ((unsigned __int64)v24 << 12) + v10;
          if( v26 > 0x7FFFFFFF0000i64 || v26 < v10 )
            MEMORY[0x7FFFFFFF0000] = 0;
        }
        v25 = 1;
      }
      if( Pool )
      {
        memmove(Pool, (const VOID *)v10, v24 << 12);
        v27 = Pool;
      }
      else if( v25 == 1 )
      {
        MemoryDescriptorList[0].Next = 0i64;
        MemoryDescriptorList[0].Size = 8 * (((((unsigned __int64)v24 << 12) + (v10 & 0xFFF) + 4095) >> 12) + 6);
        MemoryDescriptorList[0].MdlFlags = 0;
        MemoryDescriptorList[0].StartVa = (void *)(v10 & 0xFFFFFFFFFFFFF000ui64);
        MemoryDescriptorList[0].ByteOffset = v10 & 0xFFF;
        MemoryDescriptorList[0].ByteCount = v24 << 12;
        MmProbeAndLockPages(MemoryDescriptorList, 0, IoReadAccess);
        LODWORD(Priority) = -1073741824;
        LODWORD(BugCheckOnFailure) = 0;
        v27 = MmMapLockedPagesSpecifyCache(MemoryDescriptorList, 0, MmCached, 0i64, BugCheckOnFailure, Priority);
        if( !v27 )
          goto LABEL_19;
      }
      else
      {
        v27 = (_BYTE *)v10;
      }
      v50 = ((unsigned __int64)v24 << 12) + v10;
      KiStackAttachProcess(TargetProcess, 0i64, &ApcState);
      v30 = EnclaveAddress;
      v31 = v27 - EnclaveAddress;
      while( v24 )
      {
        LODWORD(v32) = MiGetPageForEnclave(PreviousMode, VmPartition);
        v33 = v32;
        if( v32 == -1i64 )
        {
          v22 = -1073741801;
          goto LABEL_52;
        }
        PteFromCopyList = (UINT64)MiGetPteFromCopyList(PteCopyList, v32, 0xFFFFFFFFFFFFFFFFui64);
        LODWORD(BugCheckOnFailure) = PageType;
        v22 = KeAddEnclavePage(
                (PVOID)EnclaveControlAddress,
                &v30[v31],
                (PVOID)((__int64)((PteFromCopyList << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16),
                v30,
                BugCheckOnFailure,
                v56);
        Long = ZeroPte.u.Long;
        LOBYTE(v35) = MiPteInShadowRange(PteFromCopyList);
        if( v35 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (ZeroPte.u.Long & 1) != 0 )
          Long = ZeroPte.u.Long | 0x8000000000000000ui64;
        *(_QWORD *)PteFromCopyList = Long;
        if( v22 < 0 )
        {
          MiReturnEnclavePage(v33);
LABEL_52:
          PteAddress = PointerPte;
          break;
        }
        MiInitializeEnclavePfn(v33, PointerPte, PageType_4);
        v36 = PageType_4;
        LODWORD(v36) = PageType_4 | 0x80000000;
        LODWORD(v37) = MiMakeValidPte((_XSTATE_CONFIGURATION *)PointerPte, v33, v36);
        LODWORD(BugCheckOnFailure) = 1;
        MiWriteEnclavePte((UINT64)PointerPte, v37, PreviousMode, 0i64, BugCheckOnFailure);
        v30 = EnclaveAddress + 4096;
        EnclaveAddress += 4096;
        PteAddress = ++PointerPte;
        --v24;
        *ReturnedError += 4096i64;
      }
      if( (MemoryDescriptorList[0].MdlFlags & 2) != 0 )
        MmUnlockPages((INT64)MemoryDescriptorList, v28, v29);
      KiUnstackDetachProcess(&ApcState, 0i64);
      v10 = v50;
      v19 = v51;
    }
  }
  else
  {
LABEL_19:
    v22 = -1073741670;
  }
  if( (MemoryDescriptorList[0].MdlFlags & 2) != 0 )
    MmUnlockPages((INT64)MemoryDescriptorList, (INT64)v20, v21);
  if( Pool )
    ExFreePoolWithTag(Pool, 0);
  MiReleasePteCopyList(PteCopyList);
  return v22;
}

Referenced by:

NtLoadEnclaveData