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