MiDuplicateCloneLeaf
NTSTATUS __stdcall MiDuplicateCloneLeaf(
_MMPTE *PointerPte,
_MMPTE *PointerNewPte,
ULONG_PTR NewPage,
UINT8 WsIrql,
UINT8 PageIrql){
UINT64 v6;
INT64 v8;
unsigned __int64 Long;
unsigned __int64 v10;
__int64 v11;
_MMPFN *v12;
int v13;
unsigned __int64 v14;
_MMSUPPORT_SHARED *SharedVm;
__int64 v17;
__int64 v18;
UINT64 v19;
UINT64 v20;
INT64 v21;
char v22;
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;} v23;
int v24;
UINT64 v25;
unsigned __int64 v26;
unsigned __int8 v27;
int v28;
_ETHREAD *NewCacheAttributea;
int NewCacheAttribute;
_MMSUPPORT_FULL *p_Vm;
char PfnPriority;
INT64 v33;
INT64 v35;
v35 = *(_QWORD *)&NewPage;
v6 = *(_QWORD *)&NewPage;
LODWORD(v8) = MI_READ_PTE_LOCK_FREE((INT64)PointerPte);
Long = v8;
v33 = v8;
if( (v8 & 1) != 0 )
{
LODWORD(v10) = MI_READ_PTE_LOCK_FREE((INT64)&v33);
v11 = (v10 >> 12) & 0xFFFFFFFFFi64;
v12 = &MmGetPfnDb()[v11];
v13 = 1;
Long = v12->OriginalPte.u.Long;
}
else
{
v14 = v8;
if( *(&stru_140C4DB30 + 42) )
{
if( (v8 & 0x10) != 0 )
v14 = v8 & 0xFFFFFFFFFFFFFFEFui64;
else
v14 = v8 & ~*(&stru_140C4DB30 + 42);
}
v11 = (v14 >> 12) & 0xFFFFFFFFFi64;
v12 = &MmGetPfnDb()[v11];
if( (*(_BYTE *)(&v12->u3 + 1) & 0x20) != 0 )
{
p_Vm = &KeGetCurrentThread()->ApcState.Process->Vm;
_InterlockedAnd64(&v12->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
MiUnlockWorkingSetExclusive(&p_Vm->Instance, WsIrql);
NewCacheAttributea = (_ETHREAD *)KeGetCurrentThread();
++NewCacheAttributea->ActiveFaultCount;
--NewCacheAttributea->ActiveFaultCount;
SharedVm = MiGetSharedVm(&p_Vm->Instance);
ExAcquireSpinLockExclusive((INT64 *)&SharedVm->WorkingSetLock);
SharedVm->GoodCitizenWaiting = 0;
return 0;
}
v13 = 0;
}
v17 = (Long >> 5) & 0x1F;
v28 = MI_IS_SOFTWARE_PTE_SHADOW_STACK((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;} *)&v12->OriginalPte.u.Long);
v19 = v18 + 48 * v6;
if( v13 != 1 )
MiLockNestedPageAtDpcInline((_MMPFN *)(v18 + 48 * v6));
v20 = 129i64;
if( v13 != 1 )
v20 = 132i64;
MiCopyPage(v6, v11, 0i64, v20);
if( !v13 )
_InterlockedAnd64((volatile signed __int64 *)(v19 + 24), 0x7FFFFFFFFFFFFFFFui64);
PfnPriority = MiGetPfnPriority(v12);
NewCacheAttribute = *((unsigned __int8 *)&v12->u3 + 2) >> 6;
if( v13 == 1 )
{
LODWORD(v21) = MiMakeTransitionPte(v35, v17);
}
else
{
_InterlockedAnd64(&v12->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
__writecr8(PageIrql);
LODWORD(v21) = MiUpdateTransitionPteFrame(v33, v35);
}
v33 = v21;
v22 = v21;
v23.Long = v21;
LOBYTE(v24) = MiPteInShadowRange((UINT64)PointerNewPte);
if( v24 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v22 & 1) != 0 )
v23.Long |= 0x8000000000000000ui64;
PointerNewPte->u.Long = v23.Long;
LODWORD(v25) = MiVaToPfn(PointerNewPte);
MiInitializePfnForOtherProcess(v35, PointerPte, v25, 0x10ui64);
*(_QWORD *)(v19 + 16) = *(_QWORD *)(v19 + 16) & 0xFFFFFFFFFFFFFC1Fui64 | (32i64 * (unsigned int)v17);
v26 = MiLockPageInline((_MMPFN *)v19);
if( v28 )
*(_QWORD *)(v19 + 16) |= 0x4000000ui64;
v27 = *(_BYTE *)(v19 + 34);
if( v27 >> 6 != NewCacheAttribute )
{
MiChangePageAttribute((_MMPFN *)v19, (_MI_PFN_CACHE_ATTRIBUTE)NewCacheAttribute, 3ui64);
v27 = *(_BYTE *)(v19 + 34);
}
*(_BYTE *)(v19 + 35) ^= (PfnPriority ^ *(_BYTE *)(v19 + 35)) & 7;
*(_BYTE *)(v19 + 34) = v27 & 0xF8 | 6;
MiDecrementShareCount((_MMPFN *)v19);
_InterlockedAnd64((volatile signed __int64 *)(v19 + 24), 0x7FFFFFFFFFFFFFFFui64);
__writecr8(v26);
return 1;
}Referenced by:
MiBuildForkPte
MiHandleForkTransitionPte