MiHandleForkTransitionPte
NTSTATUS __stdcall MiHandleForkTransitionPte(
_EPROCESS *CurrentProcess,
_MMPTE *PointerPte,
_MMPTE *PointerNewPte,
_MMCLONE_BLOCK *ForkProtoPte,
UINT64 *PrivatePageCount,
_MI_TB_FLUSH_LIST *TbFlushList,
UINT64 *NewPage,
UINT64 CloneFlags,
UINT8 WsIrql,
_MI_CLONE_CHARGES *CommitBlock){
unsigned __int64 v10;
_MMPTE *v11;
__int64 v13;
unsigned int v14;
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;} v15;
unsigned int v16;
int v17;
__int64 v18;
__int64 v19;
_MI_PARTITION *v20;
__int64 v21;
__int64 v22;
_MMPFN *v24;
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;} v25;
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;} v26;
UINT64 v27;
__int64 v28;
signed __int32 v29;
__int64 v30;
UINT8 v31;
_MI_PARTITION *v32;
UINT64 v33;
_MMSUPPORT_SHARED *v34;
UINT8 v35;
__int64 v36;
int v37;
int v38;
__int64 v39;
int v40;
UINT8 v41;
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;} v42;
int v43;
__int64 v44;
INT64 v45;
unsigned __int64 v46;
unsigned __int64 v47;
_MMPFN *PfnDb;
_MMPFN *v49;
unsigned __int64 v50;
int v51;
unsigned __int64 Long;
int v53;
_MMPFN *v54;
_MMSUPPORT_SHARED *SharedVm;
UINT64 Flags;
int Color;
unsigned int Colora;
int Color_4;
int v60;
unsigned int Vm;
_MMSUPPORT_FULL *Vma;
INT64 v63;
__int64 v64;
ULONG_PTR *Partition;
__int128 ColorBase;
__int64 v67;
__int64 bf_0;
_QWORD *v72;
_DWORD *v73;
v10 = (unsigned __int64)PrivatePageCount;
v11 = PointerNewPte;
v63 = 0i64;
ColorBase = 0i64;
v13 = MiSwizzleInvalidPte(((_QWORD)PrivatePageCount << 16) | 0x400i64);
v15.Long = ZeroPte.u.Long;
v16 = v14;
v67 = v13;
v17 = v14;
v19 = *(unsigned __int16 *)(v18 + 1838);
bf_0 = ZeroPte.u.Hard._bf_0;
Color_4 = v14;
v60 = v14;
v20 = *(_MI_PARTITION **)(*(&stru_140C4DB30 + 267) + 8 * v19);
v22 = *(unsigned __int16 *)(v21 + 1838);
v64 = (__int64)v20;
Partition = *(ULONG_PTR **)(*(&stru_140C4DB30 + 267) + 8 * v22);
if( Partition != (ULONG_PTR *)v20 )
{
if( (WsIrql & 1) != 0 )
{
if( !MiChargeCommit(v20, v14 + 1, 0i64) )
{
MiWriteUselessChildPte(&ForkProtoPte->ProtoPte.u.Long);
*v73 = 1;
return 1;
}
v17 = 1;
v60 = 1;
}
if( MiGetCrossPartitionCloneCharges((INT64)v20) )
{
v16 = 1;
Color_4 = 1;
goto LABEL_12;
}
MiWriteUselessChildPte(&ForkProtoPte->ProtoPte.u.Long);
*v73 = 1;
if( v17 )
MiReturnCommit(v20, 1ui64);
return 1;
}
while( 1 )
{
LABEL_12:
v24 = MiLockTransitionLeafPage((ULONG_PTR)v11, 0i64);
if( !v24 )
goto LABEL_22;
LODWORD(v25.Long) = MI_READ_PTE_LOCK_FREE((INT64)v11);
v26.Long = v25.Long;
v27 = 0i64;
v28 = (v25.Long >> 5) & 0x1F;
Vm = v28;
if( !v24->u3.ReferenceCount
&& (v28 & 0xFFFFFFF8) != 16
&& !(unsigned int)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;} *)&v24->OriginalPte.u.Long) )
{
break;
}
Color = *((unsigned __int8 *)&v24->u3 + 2) >> 6;
Vma = &CurrentProcess->Vm;
if( *(_QWORD *)CloneFlags != -1i64 )
{
if( v17 )
{
MiReturnCommit(v20, 1ui64);
LODWORD(v27) = 0;
v17 = 0;
}
if( v16 )
{
MiReturnCrossPartitionCloneCharges((_MI_CROSS_PARTITION_CHARGES *)v20);
LODWORD(v27) = 0;
}
v16 = v27;
v54 = &MmGetPfnDb()[*(_QWORD *)CloneFlags];
MiLockNestedPageAtDpcInline(v54);
MiFinalizePageAttribute(v54, (_MI_PFN_CACHE_ATTRIBUTE)Color, 1ui64);
_InterlockedAnd64(&v54->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
if( (*(_BYTE *)(&v24->u3 + 1) & 0x20) != 0
&& (MiFlushTbList((_MI_TB_FLUSH_LIST *)NewPage), (*(_BYTE *)(&v24->u3 + 1) & 8) != 0) )
{
_InterlockedAnd64(&v24->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
MiUnlockWorkingSetExclusive(&Vma->Instance, (UINT8)CommitBlock);
KeDelayExecutionThread(0, 0, (_LARGE_INTEGER *)&Interval);
SharedVm = MiGetSharedVm(&Vma->Instance);
ExAcquireSpinLockExclusive((INT64 *)&SharedVm->WorkingSetLock);
SharedVm->GoodCitizenWaiting = 0;
}
else if( MiDuplicateCloneLeaf(
PointerNewPte,
&ForkProtoPte->ProtoPte,
*(_QWORD *)CloneFlags,
(UINT8)CommitBlock,
2u) )
{
*(_QWORD *)CloneFlags = -1i64;
++*(_QWORD *)TbFlushList;
return 1;
}
LABEL_22:
if( v17 )
MiReturnCommit(v20, 1ui64);
if( v16 )
MiReturnCrossPartitionCloneCharges((_MI_CROSS_PARTITION_CHARGES *)v20);
return 0;
}
_InterlockedAnd64(&v24->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
MiInitializePageColorBase(&CurrentProcess->Vm.Instance, v27, (_MI_COLOR_BASE *)&ColorBase);
v29 = _InterlockedExchangeAdd((volatile signed __int32 *)ColorBase, 1u);
Colora = HIDWORD(ColorBase) | v29 & DWORD2(ColorBase);
LODWORD(v30) = MiGetPage(Partition, Colora, 0i64);
*(_QWORD *)CloneFlags = v30;
if( v30 == -1 )
{
v31 = (unsigned __int8)CommitBlock;
v32 = (_MI_PARTITION *)Partition;
do
{
MiFlushTbList((_MI_TB_FLUSH_LIST *)NewPage);
MiUnlockWorkingSetExclusive(&Vma->Instance, v31);
MiWaitForFreePage(v32, v33);
v34 = MiGetSharedVm(&Vma->Instance);
v35 = ExAcquireSpinLockExclusive((INT64 *)&v34->WorkingSetLock);
v34->GoodCitizenWaiting = 0;
LODWORD(Flags) = 1;
v31 = v35;
MiMakeSystemAddressValid(PointerNewPte, 0i64, 0i64, v35, Flags);
LODWORD(v36) = MiGetPage((ULONG_PTR *)&v32->Core.PartitionId, Colora, 0i64);
*(_QWORD *)CloneFlags = v36;
}
while( v36 == -1 );
v13 = v67;
v15.Long = bf_0;
v20 = (_MI_PARTITION *)v64;
v16 = Color_4;
v17 = v60;
LOBYTE(CommitBlock) = v31;
v10 = (unsigned __int64)PrivatePageCount;
}
v11 = PointerNewPte;
if( (MI_READ_PTE_LOCK_FREE((INT64)PointerNewPte) & 0x401) != 0 )
goto LABEL_22;
}
*(_QWORD *)v10 = v27;
LOBYTE(v37) = MiPteInShadowRange(v10);
if( v37 )
{
v40 = v38;
if( (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v26.Long & 1) != 0 )
v26.Long |= v39;
}
else
{
v40 = 0;
}
*(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;} *)v10 = (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;})v26.Long;
if( v40 )
MiWritePteShadow();
MI_MAKE_PROTECT_WRITE_COPY((_MMPTE *)v10);
v41 = 1;
*(_QWORD *)(v10 + 8) = v16;
*(_QWORD *)(v10 + 24) = 2i64;
if( (WsIrql & 1) != 0 )
{
*(_QWORD *)(v10 + 16) = 1i64;
if( v17 )
++*v72;
else
++v72[1];
_InterlockedExchangeAdd64((volatile signed __int64 *)&v20->Vp.SharedCommit, 1ui64);
v42.Long = *(unsigned __int64 *)(v10 + 16);
}
else
{
v42.Long = 0i64;
}
*(_QWORD *)(v10 + 16) = v42.Long & 0x7FFFFFFFFFFFFFFi64 | ((unsigned __int64)Vm << 59);
if( (v24->OriginalPte.u.Long & 2) != 0 )
{
v15.Long = (unsigned __int64)v24->OriginalPte.u;
if( (*(_BYTE *)(&v24->u3 + 1) & 7) == 3 )
{
MiUnlinkPageFromList(v24, 0i64);
v43 = 1;
}
else
{
v43 = 0;
}
v24->OriginalPte.u.Long &= ~2ui64;
if( v43 )
MiInsertPageInList(v24, 8ui64, v41);
}
v24->PteLong = v10;
v24->u4._bf_0 |= 0x8000000000000000ui64;
MI_MAKE_PROTECT_WRITE_COPY(&v24->OriginalPte);
v44 = v24->u4._bf_0;
v64 = v44 & 0xFFFFFFFFFi64;
LODWORD(v45) = MI_READ_PTE_LOCK_FREE((INT64)MmGetPteBase() + ((v10 >> 9) & 0x7FFFFFFFF8i64));
v63 = v45;
LODWORD(v46) = MI_READ_PTE_LOCK_FREE((INT64)&v63);
v24->u4._bf_0 = v44 ^ (v44 ^ (v46 >> 12)) & 0xFFFFFFFFFi64;
LODWORD(v47) = MI_READ_PTE_LOCK_FREE((INT64)&v63);
PfnDb = MmGetPfnDb();
v49 = &PfnDb[(v47 >> 12) & 0xFFFFFFFFFi64];
MiLockNestedPageAtDpcInline(v49);
v49->u2._bf_0 ^= (v49->u2._bf_0 ^ (v49->u2._bf_0 + 1)) & 0x3FFFFFFFFFFFFFFFi64;
_InterlockedAnd64(&v49->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
v50 = v13;
LOBYTE(v51) = MiPteInShadowRange((UINT64)PointerNewPte);
if( v51 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v13 & 1) != 0 )
v50 = v13 | 0x8000000000000000ui64;
PointerNewPte->u.Long = v50;
_InterlockedAnd64(&v24->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
if( v15.Long )
{
Long = v15.Long & 0xFFFFFFFFFFFFFFFBui64;
if( (v15.Long & 4) == 0 )
Long = v15.Long;
MiReleasePageFileInfo(v20, (_MMPTE)Long, 1ui64);
}
if( (WsIrql & 1) != 0 && Vm != 24 )
v13 |= 8ui64;
LOBYTE(v53) = MiPteInShadowRange((UINT64)ForkProtoPte);
if( v53 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v13 & 1) != 0 )
v13 |= 0x8000000000000000ui64;
ForkProtoPte->ProtoPte.u.Long = v13;
MiLockAndDecrementShareCount(&PfnDb[v64], 0i64);
_InterlockedExchangeAdd64((volatile signed __int64 *)&CurrentProcess->NumberOfPrivatePages, 0xFFFFFFFFFFFFFFFFui64);
return 2;
}Referenced by:
MiBuildForkPte