MiCopyPage
VOID __stdcall MiCopyPage(UINT64 TargetPage, UINT64 SourcePage, _MMPTE_COPY_LIST *PteCopyList, UINT64 CopyFlags){
int v5;
_MMPFN *PfnDb;
char v8;
_UNICODE_STRING *v9;
_MMPFN *v10;
int v11;
unsigned int PagePrivilege;
wchar_t *v13;
int v14;
unsigned __int8 v15;
int v16;
int v17;
_MMPTE *PteBase;
UINT8 v19;
int v20;
NTSTATUS v21;
int v22;
unsigned __int8 CurrentIrql;
unsigned __int64 HyperSpace;
_MMPTE *PteFromCopyList;
_KTBFLUSH_TYPE v26;
unsigned __int64 Long;
_MMPTE *Pml4eBase;
_MMPTE *PxeUserLimit;
unsigned __int64 v30;
_MMPTE *v31;
unsigned __int8 v32;
_QWORD *MmInternal;
unsigned int VerifyType;
_UNICODE_STRING *Pfn1;
_LARGE_INTEGER ThawTimeout[2];
_KE_PRIVILEGED_PAGE_IDENTITY PrivilegedIdentity[4];
_MMPTE_COPY_LIST PteCopyLista[4];
__int64 v39;
int v42;
v39 = 0i64;
v5 = CopyFlags;
PfnDb = MmGetPfnDb();
v8 = 0;
*(_OWORD *)PteCopyLista = 0i64;
*(_OWORD *)PrivilegedIdentity = 0i64;
*(_OWORD *)&ThawTimeout[0].anonymous_0.LowPart = 0i64;
v9 = (_UNICODE_STRING *)&PfnDb[SourcePage];
Pfn1 = v9;
v10 = &PfnDb[TargetPage];
v11 = -1073741823;
v42 = CopyFlags & 4;
VerifyType = v42 != 0 ? 4 : 0;
PagePrivilege = MiGetPagePrivilege((ULONG_PTR)v9, CopyFlags & 4, PrivilegedIdentity);
v14 = 2;
v15 = PagePrivilege;
if( PagePrivilege )
{
if( (v5 & 0x12) != 0 )
{
v8 = 2;
v16 = v5 & 2;
}
else if( (MiFlags & 0x10000) == 0
|| (v5 & 8) != 0
|| (PagePrivilege & 1) == 0
|| (LOBYTE(v17) = MI_PFN_IS_PROTO(v9, (_UNICODE_STRING *)PagePrivilege, 2u, v13), v17) )
{
if( (MiFlags & 0x40000) == 0 || (v5 & 8) != 0 || (v8 = v14, (v15 & (unsigned __int8)v14) == 0) )
v8 = 4;
v16 = v14 & v5;
}
else
{
v8 = v14;
v16 = v14 & v5;
}
}
else
{
v16 = v5 & 2;
if( (v5 & 2) == 0 )
v8 = 4;
}
PteBase = MmGetPteBase();
if( ((unsigned __int8)v8 & (unsigned __int8)v14) != 0 )
{
v19 = 17;
if( (MiFlags & 0x40000) != 0 )
{
MiFlushEntireTbDueToAttributeChange();
PteBase = MmGetPteBase();
}
if( (MiFlags & 0x8000) == 0 )
goto LABEL_31;
if( v16 )
{
*(_OWORD *)&ThawTimeout[0].anonymous_0.LowPart = *(_OWORD *)PrivilegedIdentity;
}
else
{
ThawTimeout[0].QuadPart = (__int64)((v10->PteLong << 25) - ((_QWORD)PteBase << 25)) >> 16;
if( ThawTimeout[0].QuadPart < 0xFFFF800000000000ui64 )
{
v8 |= 8u;
ThawTimeout[1] = (_LARGE_INTEGER)KeGetCurrentThread()->ApcState.Process->Pcb.SecureState;
if( !v42 )
v19 = MiLockPageInline(v10);
MiMarkPfnVerified(v10, 4ui64);
MiAbortCombineScan(v10);
v20 = v42;
if( v42 )
goto LABEL_28;
_InterlockedAnd64(&v10->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
__writecr8(v19);
v19 = 17;
}
}
v20 = v42;
LABEL_28:
if( (v5 & 0x20) != 0 && !v20 )
v19 = MiLockPageInline(v10);
LABEL_31:
v21 = KeCopyPrivilegedPage((_LARGE_INTEGER *)TargetPage, ThawTimeout, SourcePage);
v11 = v21;
if( v21 < 0 )
KeBugCheckEx(0x1Au, (PVOID)0x5150A, (PVOID)SourcePage, (PVOID)TargetPage, (PVOID)v21);
if( v19 != 17 )
{
_InterlockedAnd64(&v10->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
__writecr8(v19);
}
if( (MiFlags & 0x40000) != 0
&& !v16
&& (v10->PteLong | 0x8000000000000000ui64) < (unsigned __int64)&MmGetPteBase()[0x800000000i64] )
{
v11 = (unsigned int)KeSetPagePrivilege((_PREFIX_TABLE *)TargetPage, (_STRING *)ThawTimeout, 4);
if( v11 < 0 )
KeBugCheckEx(0x1Au, (PVOID)0x5150D, (PVOID)SourcePage, (PVOID)TargetPage, 0i64);
}
}
if( (((unsigned __int64)Pfn1[2].Buffer >> 60) & 7) == 3 )
{
if( v16 )
MiClearPfnImageVerified(Pfn1, VerifyType);
if( (v8 & 4) == 0 && (((unsigned __int64)v10->u4._bf_0 >> 60) & 7) != 3 )
MiMarkPfnVerified(v10, VerifyType);
}
if( v11 < 0 )
{
v22 = LOBYTE(Pfn1[2].MaximumLength) >> 6;
if( *((unsigned __int8 *)&v10->u3 + 2) >> 6 != v22 )
MiChangePageAttribute(v10, (_MI_PFN_CACHE_ATTRIBUTE)v22, 0i64);
if( !PteCopyList )
{
PteCopyList = PteCopyLista;
if( (v5 & 1) == 0 || (MiCreatePteCopyList(2ui64, 2ui64, PteCopyLista), !PteCopyLista[1]) )
{
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
LOBYTE(PteCopyLista[2]) = CurrentIrql;
HyperSpace = (unsigned __int64)MiAllocateHyperSpace();
PteCopyLista[0] = 0;
v39 = (__int64)MmGetPteBase() + ((HyperSpace >> 9) & 0x7FFFFFFFF8i64);
PteCopyLista[1] = 2;
BYTE1(PteCopyLista[2]) = 1;
}
}
PteFromCopyList = MiGetPteFromCopyList(PteCopyList, TargetPage, SourcePage);
KeCopyPage((PVOID)((__int64)(((_QWORD)PteFromCopyList << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16));
Long = ZeroPte.u.Long;
Pml4eBase = MmGetPml4eBase();
PxeUserLimit = MmGetPxeUserLimit();
if( PteFromCopyList >= Pml4eBase
&& PteFromCopyList <= PxeUserLimit
&& (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0
&& (ZeroPte.u.Long & 1) != 0 )
{
Long = ZeroPte.u.Long | 0x8000000000000000ui64;
}
PteFromCopyList->u.Long = Long;
v30 = ZeroPte.u.Long;
v31 = PteFromCopyList + 1;
if( v31 >= Pml4eBase
&& v31 <= PxeUserLimit
&& (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0
&& (ZeroPte.u.Long & 1) != 0 )
{
v30 = ZeroPte.u.Long | 0x8000000000000000ui64;
}
v31->u.Long = v30;
if( PteCopyList == PteCopyLista )
{
v32 = *((_BYTE *)PteCopyList + 8);
if( v32 == 17 )
{
MiReleasePtes(
(_MI_SYSTEM_PTE_TYPE *)((char *)&stru_140C4DB30 + 4432),
*((_MMPTE **)PteCopyList + 2),
2ui64,
v26);
}
else
{
MmInternal = KeGetCurrentPrcb()->MmInternal;
if( MmInternal )
{
MmInternal[1543] = 0i64;
v32 = *((_BYTE *)PteCopyList + 8);
}
__writecr8(v32);
}
}
}
}Referenced by:
MiCopyFileOnlyGlobalSubsectionPage
MiCopyHeaderIfResident
MiCopyOnWrite
MiDuplicateCloneLeaf
MiFillPerSessionProtos
MiIdealClusterPage
MiMigratePfn
MiPrivateFixup
MiReplaceTransitionPage
MiSplitDirectMapPage
MiSwapNumaStandbyPage
MiSwapStackPageNoDpc
MiTradeActivePage