MiAddPagesToEnclave
NTSTATUS __stdcall MiAddPagesToEnclave(
INT64 rcx0,
UINT64 rdx0,
_MI_PARTITION *Partition,
_MMPTE *StartingPte,
_MMPTE *EndingPte,
UINT64 ProtectionMask){
_MI_PARTITION *v6;
int v7;
NTSTATUS result;
INT64 v11;
_MMSUPPORT_FULL *p_Vm;
_MI_PARTITION *v13;
UINT64 v14;
_MMPTE *v15;
_MMPTE *v16;
int v17;
union {unsigned __int64 Long;volatile unsigned __int64 VolatileLong;_MMPTE_HARDWARE Hard;_MMPTE_PROTOTYPE Proto;_MMPTE_SOFTWARE Soft;_MMPTE_TIMESTAMP TimeStamp;_MMPTE_TRANSITION Trans;_MMPTE_SUBSECTION Subsect;_MMPTE_LIST List;} v18;
union {unsigned __int64 Long;volatile unsigned __int64 VolatileLong;_MMPTE_HARDWARE Hard;_MMPTE_PROTOTYPE Proto;_MMPTE_SOFTWARE Soft;_MMPTE_TIMESTAMP TimeStamp;_MMPTE_TRANSITION Trans;_MMPTE_SUBSECTION Subsect;_MMPTE_LIST List;} v19;
int v20;
__int64 v21;
__int64 v22;
UINT64 v23;
int v24;
unsigned __int8 v25;
unsigned __int8 v26;
unsigned __int8 v27;
int v28;
unsigned __int8 v29;
__int64 v30;
char *v31;
UINT64 v32;
UINT8 v33;
_MI_PARTITION *v34;
unsigned __int64 v35;
int v36;
UINT64 v37;
INT64 v38;
UINT64 v39;
unsigned __int64 Long;
int v41;
INT64 v42;
INT64 v43;
UINT64 v44;
_KTBFLUSH_TYPE v45;
UINT64 PageType;
INT64 PageTypea;
unsigned __int8 v48;
UINT64 ReturnedError;
PVOID EnclaveAddress;
UINT64 PteFromCopyList;
__int64 v52;
__int64 v53;
UINT64 PageFrameIndex;
__int64 PteCopyList;
__int128 v56;
_MI_PARTITION *v57;
PVOID EnclaveControlAddress;
UINT8 WsIrql;
UINT64 v60;
v60 = rdx0;
v56 = 0i64;
PteCopyList = 0i64;
v6 = Partition;
v7 = *(_DWORD *)(rcx0 + 64);
LODWORD(ReturnedError) = 0;
if( (v7 & 2) != 0 && (*(_DWORD *)(rcx0 + 72) & 1) == 0 )
return -1073741800;
v11 = 0i64;
p_Vm = &KeGetCurrentThread()->ApcState.Process->Vm;
v13 = *(_MI_PARTITION **)(*(&stru_140C4DB30 + 267) + 8i64 * p_Vm->Instance.PartitionId);
v14 = *(_QWORD *)(rcx0 + 104);
v57 = v13;
if( v14 >= rdx0 || (v11 = rdx0 - v14, result = MiReserveEnclavePages(rcx0, (INT64)v13, rdx0 - v14), result >= 0) )
{
if( (*(_DWORD *)(rcx0 + 64) & 2) != 0 )
{
v22 = 0i64;
v53 = 0i64;
v16 = 0i64;
v21 = (_QWORD)MmGetPteBase() << 25;
}
else
{
v15 = MiReservePtes((_MI_SYSTEM_PTE_TYPE *)((char *)&stru_140C4DB30 + 4432), 1ui64);
v16 = v15;
if( !v15 )
{
LABEL_8:
v17 = -1073741670;
goto LABEL_57;
}
LODWORD(v18.Long) = MiMakeValidPte((_XSTATE_CONFIGURATION *)v15, *(&stru_140C4DB30 + 498), 536870913i64);
v19.Long = v18.Long;
LOBYTE(v20) = MiPteInShadowRange((UINT64)v16);
if( v20 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v19.Long & 1) != 0 )
v19.Long |= 0x8000000000000000ui64;
v16->u.Long = v19.Long;
v6 = Partition;
v21 = (_QWORD)MmGetPteBase() << 25;
v22 = (((_QWORD)v16 << 25) - v21) >> 16;
v53 = v22;
}
v23 = 20i64;
v52 = v21;
if( rdx0 <= 0x14 )
v23 = rdx0;
MiCreatePteCopyList(v23 + 1, v23 + 1, (_MMPTE_COPY_LIST *)&PteCopyList);
if( !HIDWORD(PteCopyList) )
goto LABEL_8;
v24 = 4;
v25 = ((unsigned int)EndingPte >> 1) & 2 | 0x35;
if( ((unsigned __int8)EndingPte & 2) == 0 )
v25 = ((unsigned int)EndingPte >> 1) & 2 | 0x31;
v26 = v25;
v27 = v25;
v28 = *(_DWORD *)(rcx0 + 64) & 2;
if( !v28 )
v24 = (int)EndingPte;
v29 = v27 | 0x40;
HIDWORD(ReturnedError) = v24;
if( !v28 )
v29 = v26;
v48 = v29;
EnclaveControlAddress = (PVOID)(((*(_QWORD *)(rcx0 + 80) << 25) - v21) >> 16);
v30 = (_QWORD)v6 << 25;
v31 = 0i64;
EnclaveAddress = (PVOID)((v30 - v21) >> 16);
MiLockWorkingSetShared();
WsIrql = v33;
v34 = Partition;
v35 = (unsigned __int64)Partition;
if( Partition > (_MI_PARTITION *)StartingPte )
{
LABEL_56:
LOBYTE(v32) = WsIrql;
MiUnlockWorkingSetShared(&p_Vm->Instance, v32);
v17 = 0;
goto LABEL_57;
}
while( 1 )
{
if( (v35 & 0x78) == 0 && (_MI_PARTITION *)v35 != v34 )
{
LOBYTE(v36) = MiWorkingSetIsContended((INT64)p_Vm);
if( v36 || (unsigned int)KeShouldYieldProcessor() )
goto LABEL_31;
if( !v31 )
goto LABEL_37;
if( (unsigned int)MiPageTableLockIsContended((__int64)p_Vm, (UINT64)v31) )
{
LABEL_31:
if( v31 )
{
MiUnlockPageTableInternal((INT64)p_Vm, (UINT64)v31);
v31 = 0i64;
}
LOBYTE(v37) = WsIrql;
MiUnlockWorkingSetShared(&p_Vm->Instance, v37);
MiLockWorkingSetShared();
}
}
if( v31 )
{
if( (v35 & 0xFFF) != 0 )
goto LABEL_38;
MiUnlockPageTableInternal((INT64)p_Vm, (UINT64)v31);
}
LABEL_37:
v31 = (char *)MmGetPteBase() + ((v35 >> 9) & 0x7FFFFFFFF8i64);
LODWORD(PageType) = 0;
MiMakeSystemAddressValid((VOID *)v35, 0i64, (*(_DWORD *)(rcx0 + 48) >> 12) & 0x3F, WsIrql, PageType);
LABEL_38:
if( (MI_READ_PTE_LOCK_FREE(v35) & 1) == 0 )
{
v38 = v11 - 1;
if( v11 != v60 )
v38 = v11;
--v60;
v11 = v38;
LODWORD(v39) = MiGetPageForEnclave(rcx0, v57);
PageFrameIndex = v39;
PteFromCopyList = (UINT64)MiGetPteFromCopyList((_MMPTE_COPY_LIST *)&PteCopyList, v39, 0xFFFFFFFFFFFFFFFFui64);
LODWORD(PageType) = v48;
v17 = KeAddEnclavePage(
EnclaveControlAddress,
(PVOID)v22,
(PVOID)((__int64)((PteFromCopyList << 25) - v21) >> 16),
EnclaveAddress,
PageType,
&ReturnedError);
Long = ZeroPte.u.Long;
LOBYTE(v41) = MiPteInShadowRange(PteFromCopyList);
if( v41 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (ZeroPte.u.Long & 1) != 0 )
Long = ZeroPte.u.Long | 0x8000000000000000ui64;
*(_QWORD *)PteFromCopyList = Long;
if( v17 < 0 )
{
MiReturnEnclavePage(PageFrameIndex);
if( v17 == -1073740657 )
v17 = -1073741823;
if( v31 )
MiUnlockPageTableInternal((INT64)p_Vm, (UINT64)v31);
LOBYTE(v44) = WsIrql;
MiUnlockWorkingSetShared(&p_Vm->Instance, v44);
LABEL_57:
MiReleasePteCopyList((_MMPTE_COPY_LIST *)&PteCopyList);
if( v16 )
MiReleasePtes((_MI_SYSTEM_PTE_TYPE *)((char *)&stru_140C4DB30 + 4432), v16, 1ui64, v45);
if( v11 )
MiReturnReservedEnclavePages(rcx0, v11);
return v17;
}
MiInitializeEnclavePfn(PageFrameIndex, (_MMPTE *)v35, HIDWORD(ReturnedError));
v42 = HIDWORD(ReturnedError);
LODWORD(v42) = HIDWORD(ReturnedError) | 0x80000000;
LODWORD(v43) = MiMakeValidPte((_XSTATE_CONFIGURATION *)v35, PageFrameIndex, v42);
LODWORD(PageTypea) = 0;
MiWriteEnclavePte(v35, v43, rcx0, 0i64, PageTypea);
v21 = v52;
}
EnclaveAddress = (char *)EnclaveAddress + 4096;
v35 += 8i64;
if( v35 > (unsigned __int64)StartingPte )
{
if( v31 )
MiUnlockPageTableInternal((INT64)p_Vm, (UINT64)v31);
goto LABEL_56;
}
v22 = v53;
v34 = Partition;
}
}
return result;
}Referenced by:
MiCommitEnclavePages