MiBuildForkPte
_BOOL8 __fastcall MiBuildForkPte(
__int64 a1,
__int64 a2,
ULONG_PTR a3,
__int64 *a4,
__int64 a5,
__int64 *a6,
_QWORD *a7,
__int64 a8,
__int64 a9,
__int64 a10,
__int64 a11,
int a12,
unsigned __int8 a13,
_QWORD *a14,
_DWORD *a15){
__int64 v16;
unsigned __int64 v17;
unsigned __int64 ZeroCloneBlock;
INT64 v19;
INT64 v21;
int v22;
int v23;
__int64 *v24;
unsigned __int8 v25;
_QWORD *v26;
INT64 v27;
UNICODE_STRING *v28;
UINT8 v29;
WCHAR *v30;
char *v31;
int v32;
INT64 v33;
UINT8 WsleContents;
UNICODE_STRING *v35;
UINT8 v36;
PWCHAR v37;
int v38;
UINT64 v39;
__int64 v40;
_MI_PARTITION *v41;
unsigned __int64 v42;
INT64 v43;
_MI_PARTITION *v44;
_MI_PARTITION *v45;
signed __int32 v46;
_MI_PARTITION *v47;
UINT64 v48;
INT64 *SharedVm;
int v50;
BOOL v51;
int v52;
char v53;
__int64 v54;
CHAR *v55;
INT64 *v56;
_MI_PARTITION *v57;
_MI_PARTITION *v58;
int v59;
_MMVAD_SHORT *v60;
UINT64 v61;
unsigned __int64 *v62;
__int64 v63;
__int64 v64;
__int64 v65;
INT64 v66;
INT64 v67;
PVOID v68;
INT64 v69;
INT64 v70;
bool v71;
__int64 v72;
int WsleProtection;
__int64 v74;
__int64 v75;
INT64 v76;
__int64 v77;
__int64 v78;
volatile INT64 *v79;
INT64 v80;
__int64 v81;
INT64 PerSessionProtoPte;
__int64 v83;
UINT64 v84;
__int64 v85;
int v86;
INT64 v87;
INT64 v88;
INT64 v89;
INT64 v90;
unsigned int v91;
__int64 v92;
__int64 v93;
int v94;
volatile INT64 *v95;
INT64 v96;
_QWORD *v97;
CHAR v98;
volatile INT64 *v99;
_QWORD *v100;
__int64 v101;
INT64 v102;
volatile INT64 **a5a;
_QWORD *v104;
__int64 v105;
UINT64 *p_NewPage;
INT64 v107;
INT64 v108;
INT64 v109;
_DWORD *v110;
INT64 v111;
unsigned int v112;
CHAR a3a[4];
int v114;
int v115;
_MI_PARTITION *Partition;
INT64 a1a;
INT64 v118;
volatile INT64 *v119;
UINT64 NewPage;
PVOID VirtualAddress;
INT64 v122;
UINT64 SpinCount;
UINT64 v124;
INT64 v125;
INT64 v126[2];
INT64 v127[9];
v125 = 0i64;
v119 = 0i64;
*(_OWORD *)v126 = 0i64;
v16 = a2;
v111 = MI_READ_PTE_LOCK_FREE(a3);
v17 = v111;
if( !v111 )
{
if( a5 && *(int *)(a11 + 52) < 0 )
{
ZeroCloneBlock = MiFindZeroCloneBlock(a5, (*(_DWORD *)(a10 + 48) >> 7) & 0x1F);
if( ZeroCloneBlock )
{
MiIncreaseUsedPtesCount((PVOID)a8, 1ui64);
MiWriteSharedDemandZeroPte(v16, v19, ZeroCloneBlock, a4, a14);
}
}
return 0i64;
}
MiIncreaseUsedPtesCount((PVOID)a8, 1ui64);
v21 = v16 + 1664;
v112 = 0;
v22 = 0;
v23 = a12;
NewPage = -1i64;
v24 = a6;
v122 = a1 + 1664;
v25 = a13;
v118 = v16 + 1664;
for( *(_DWORD *)a3a = a12; ; v23 = *(_DWORD *)a3a )
{
v26 = a14;
if( v22 == 1 )
{
MiMakeSystemAddressValid(a3, 0i64, 0i64, v25, 1);
v27 = MI_READ_PTE_LOCK_FREE(a3);
v26 = a14;
v17 = v27;
v23 = *(_DWORD *)a3a;
v111 = v27;
}
if( (v17 & 1) != 0 )
{
v31 = (char *)MmGetPfnDb() + 48 * (((unsigned __int64)MI_READ_PTE_LOCK_FREE((INT64)&v111) >> 12) & 0xFFFFFFFFFi64);
if( v112
|| *((_WORD *)v31 + 16) > 1u && (LOBYTE(v32) = MI_PFN_IS_PROTO((UNICODE_STRING *)v31, v28, v29, v30), !v32)
|| (unsigned int)MI_IS_SOFTWARE_PTE_SHADOW_STACK((_QWORD *)v31 + 2) )
{
MiInitializePageColorBase(v122, 0i64, (INT64)v126);
v46 = _InterlockedExchangeAdd((volatile signed __int32 *)v126[0], 1u);
v47 = *(_MI_PARTITION **)(qword_140C4E388 + 8i64 * *(unsigned __int16 *)(v21 + 174));
Partition = v47;
if( NewPage != -1i64
|| (NewPage = MiGetPage(v47, HIDWORD(v126[1]) | (unsigned int)v46 & v126[1], 0i64), NewPage != -1i64) )
{
v84 = NewPage;
MiFinalizePageAttribute(
(_MMPFN *)((char *)MmGetPfnDb() + 48 * NewPage),
(_MI_PFN_CACHE_ATTRIBUTE)((unsigned __int8)v31[34] >> 6),
0i64);
MiDuplicateCloneLeaf((MMPTE *)a3, (MMPTE *)a4, v84, a13, 0x11u);
++*a7;
return 0i64;
}
MiFlushTbList(a9);
MiUnlockWorkingSetExclusive(v122, a13);
MiWaitForFreePage(Partition, v48);
SharedVm = MiGetSharedVm(v122);
v25 = ExAcquireSpinLockExclusive((PEX_SPIN_LOCK)SharedVm);
*((_DWORD *)SharedVm + 1) = 0;
v17 = v111;
a13 = v25;
LABEL_32:
v16 = a2;
goto LABEL_33;
}
VirtualAddress = (PVOID)((__int64)((a3 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16);
WsleContents = MiGetWsleContents(v33, (UINT64)VirtualAddress);
LOBYTE(v38) = MI_PFN_IS_PROTO((UNICODE_STRING *)v31, v35, v36, v37);
if( !v38 )
{
v125 = MI_READ_PTE_LOCK_FREE(v40 + (((unsigned __int64)v24 >> 9) & 0x7FFFFFFFF8i64));
v41 = (_MI_PARTITION *)((char *)MmGetPfnDb()
+ 48 * (((unsigned __int64)MI_READ_PTE_LOCK_FREE((INT64)&v125) >> 12) & 0xFFFFFFFFFi64));
v42 = *((_QWORD *)v31 + 5);
v112 = 0;
v114 = 0;
v43 = ZeroPte;
Partition = v41;
v44 = *(_MI_PARTITION **)(qword_140C4E388 + 8 * ((v42 >> 39) & 0x3FF));
a1a = (INT64)v44;
if( *(_MI_PARTITION **)(qword_140C4E388 + 8i64 * *(unsigned __int16 *)(v118 + 174)) != v44 )
{
if( (a3a[0] & 1) != 0 )
{
if( !(unsigned int)MiChargeCommit(v44, 1ui64, 0i64) )
goto LABEL_86;
v44 = (_MI_PARTITION *)a1a;
v114 = 1;
}
if( !(unsigned int)MiGetCrossPartitionCloneCharges((INT64)v44) )
{
MiWriteUselessChildPte((UINT64 *)a4);
v51 = 0;
*a15 = 1;
if( !v114 )
goto LABEL_145;
v57 = (_MI_PARTITION *)a1a;
goto LABEL_46;
}
v41 = Partition;
v112 = 1;
}
if( (WsleContents & 0xF) != 8 || (unsigned int)MiLockPageTablePage((_MMPFN *)v41, 3i64) )
{
LODWORD(SpinCount) = 0;
v58 = Partition;
while( _interlockedbittestandset64((volatile signed __int32 *)v58 + 6, 0x3Fui64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( *((__int64 *)v58 + 3) < 0 );
}
*((_QWORD *)v58 + 3) ^= (*((_QWORD *)v58 + 3) ^ (*((_QWORD *)v58 + 3) + 1i64)) & 0x3FFFFFFFFFFFFFFFi64;
_InterlockedAnd64((volatile signed __int64 *)v58 + 3, 0x7FFFFFFFFFFFFFFFui64);
if( (v111 & 0x42) != 0 )
{
if( (*(_DWORD *)(a10 + 48) & 0x300000) == 3145728 )
{
LOBYTE(v59) = MI_PFN_IS_PROTO(
(UNICODE_STRING *)v31,
(UNICODE_STRING *)0x3FFFFFFFFFFFFFFFi64,
a10,
(PWCHAR)v44);
if( !v59 )
MiCaptureWriteWatchDirtyBit((_EPROCESS *)a1, VirtualAddress, v60);
}
HIDWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)v31 + 6, 0x3Fui64) )
{
do
KeYieldProcessorEx((UINT64 *)((char *)&SpinCount + 4));
while( *((__int64 *)v31 + 3) < 0 );
}
v61 = MiCaptureDirtyBitToPfn((INT64)v31);
v111 &= 0xFFFFFFFFFFFFFFBDui64;
v43 = v61;
}
else
{
LODWORD(v124) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)v31 + 6, 0x3Fui64) )
{
do
KeYieldProcessorEx(&v124);
while( *((__int64 *)v31 + 3) < 0 );
}
}
v62 = (unsigned __int64 *)(v31 + 16);
v63 = *((_QWORD *)v31 + 2);
if( (v63 & 2) != 0 )
{
v64 = *((_QWORD *)v31 + 2);
if( qword_140C4DC80 && (v63 & 0x10) == 0 )
v64 = ~qword_140C4DC80 & v63;
v43 = MiTransferSoftwarePte(
*((_QWORD *)v31 + 2),
*(_QWORD *)(a1a + 8i64 * ((unsigned __int16)v63 >> 12) + 6944),
HIDWORD(v64));
*v62 = v63 & 0xFFFFFFFFFFFFFFFDui64;
}
*((_QWORD *)v31 + 1) = a6;
*((_QWORD *)v31 + 5) |= 0x8000000000000000ui64;
v65 = *((_QWORD *)v31 + 5);
*((_QWORD *)v31 + 5) = v65 ^ (v65 ^ ((unsigned __int64)MI_READ_PTE_LOCK_FREE((INT64)&v125) >> 12)) & 0xFFFFFFFFFi64;
MI_MAKE_PROTECT_WRITE_COPY((_MMPTE *)(v31 + 16));
Partition = (_MI_PARTITION *)(*v62 >> 5);
_InterlockedAnd64((volatile signed __int64 *)v31 + 3, 0x7FFFFFFFFFFFFFFFui64);
if( v43 )
MiReleasePageFileInfo(
a1a,
v43,
1,
v66,
(INT64)a5a,
(INT64)v104,
v105,
(INT64)p_NewPage,
v107,
v108,
v109,
(INT64)v110);
v67 = v111;
if( (v111 & 0x800) != 0 )
{
v67 = v111 & 0xFFFFFFFFFFFFF5FFui64 | 0x200;
v111 = v67;
}
MiWriteValidPteNewProtection((INT64 *)a3, v67);
MiInsertTbFlushEntry(a9, (UINT64)VirtualAddress, 1i64, 0i64);
*a6 = 0i64;
*a6 = v67;
v68 = VirtualAddress;
a6[1] = v112;
a6[3] = 2i64;
MiSetWsleProtection(v69, (UINT64)v68);
v70 = MiSwizzleInvalidPte((*((_QWORD *)v31 + 1) << 16) | 0x400i64);
v111 = v70;
if( (a3a[0] & 1) != 0 )
{
v70 |= 8ui64;
v71 = v114 == 0;
a6[2] = 1i64;
v111 = v70;
if( v71 )
++a14[1];
else
++*a14;
_InterlockedExchangeAdd64((volatile signed __int64 *)(a1a + 7624), 1ui64);
v72 = a6[2];
}
else
{
v72 = 0i64;
}
a6[2] = v72 & 0x7FFFFFFFFFFFFFFi64 | ((unsigned __int64)(unsigned int)Partition << 59);
*a4 = v70;
_InterlockedExchangeAdd64((volatile signed __int64 *)(a1 + 1272), 0xFFFFFFFFFFFFFFFFui64);
MiUpdateWorkingSetPrivateSize(v122, (UINT64)VirtualAddress, -1i64, 0i64);
LABEL_77:
v51 = 1;
goto LABEL_145;
}
v45 = (_MI_PARTITION *)a1a;
if( v112 == 1 )
MiReturnCrossPartitionCloneCharges(a1a);
if( v114 )
MiReturnCommit(v45, 1ui64);
v24 = a6;
v21 = v118;
v25 = a13;
v112 = 1;
goto LABEL_32;
}
WsleProtection = MiGetWsleProtection(v39, WsleContents);
if( WsleProtection )
{
v76 = MiSwizzleInvalidPte(32 * (WsleProtection & 0x1F | 0xFFFFFFFFF8000020ui64));
v111 = v76;
}
else
{
v80 = MiSwizzleInvalidPte((v74 << 16) | 0x400);
v111 = v80;
v76 = v80;
if( (v75 & v78) != 0 )
goto LABEL_88;
if( v77 > 0 )
{
v76 = v80 | 0x800;
v111 = v80 | 0x800;
}
}
if( (v75 & v78) == 0 && v77 > 0 )
{
if( !(unsigned int)MiIncrementCombinedPte(v118, (INT64)v79) )
{
LABEL_86:
MiWriteUselessChildPte((UINT64 *)a4);
*a15 = 1;
LABEL_144:
v51 = 0;
goto LABEL_145;
}
v81 = v76;
goto LABEL_96;
}
LABEL_88:
if( !(unsigned int)MiReferenceCloneProto(v118, v79, a3a[0], a14, &v119) )
goto LABEL_86;
v81 = v76;
if( v119 )
{
v81 = v76 | 8;
v111 = v76 | 8;
}
else if( !MiIsPrototypePteVadLookup(*((_QWORD *)v31 + 2))
&& (*(_BYTE *)(a10 + 48) & 0x70) == 32
&& !MiIsVadLargePrivate(a10) )
{
PerSessionProtoPte = MiMakePerSessionProtoPte(a1, a2);
if( PerSessionProtoPte )
{
v111 = PerSessionProtoPte;
v81 = PerSessionProtoPte;
}
}
LABEL_96:
v83 = v81;
goto LABEL_143;
}
if( (v17 & 0x400) != 0 )
{
if( MI_PROTO_FORMAT_COMBINED(v17) )
{
if( !(unsigned int)MiIncrementCombinedPte(v21, (INT64)v99) )
goto LABEL_86;
v101 = v17;
}
else
{
if( !(unsigned int)MiReferenceCloneProto(v21, v99, v98, v100, &v119) )
goto LABEL_86;
v101 = v17;
if( v119 )
{
if( *((_QWORD *)v119 + 2) >> 59 != 24 )
{
v101 = v17 | 8;
v111 = v17 | 8;
}
}
else if( !MiIsPrototypePteVadLookup(v17) && (*(_BYTE *)(a10 + 48) & 0x70) == 32 && !MiIsVadLargePrivate(a10) )
{
v102 = MiMakePerSessionProtoPte(a1, v16);
if( v102 )
{
v111 = v102;
v101 = v102;
}
}
}
v83 = v101;
LABEL_143:
*a4 = v83;
goto LABEL_144;
}
if( (v17 & 0x800) == 0 )
break;
v110 = a15;
v109 = (INT64)v26;
LOBYTE(v108) = a13;
LODWORD(v107) = v23;
p_NewPage = &NewPage;
v105 = a9;
v104 = a7;
a5a = (volatile INT64 **)v24;
MiHandleForkTransitionPte();
if( v50 )
{
v51 = v50 != 1;
goto LABEL_145;
}
v25 = a13;
LABEL_33:
v22 = 1;
}
v51 = 0;
Partition = (_MI_PARTITION *)((v17 >> 5) & 0x1F);
if( !IS_PTE_NOT_DEMAND_ZERO(v17) )
{
if( (v17 & 2) != 0 )
{
v17 &= ~2ui64;
v111 = v17;
}
if( !(unsigned int)MI_IS_SOFTWARE_PTE_SHADOW_STACK(&v111) )
{
if( a5 )
{
v95 = (volatile INT64 *)MiFindZeroCloneBlock(a5, v94);
v119 = v95;
if( v95 )
{
MiWriteSharedDemandZeroPte(v16, v96, (UINT64)v95, a4, v97);
goto LABEL_145;
}
}
}
LABEL_123:
*a4 = v17;
goto LABEL_145;
}
if( v52 == 16 )
{
if( (v17 & 2) != 0 )
{
v17 &= ~2ui64;
v111 = v17;
}
goto LABEL_123;
}
if( (v52 & 0xFFFFFFF8) == 16 || (unsigned int)MI_IS_SOFTWARE_PTE_SHADOW_STACK(&v111) )
{
MiFlushTbList(a9);
v55 = (CHAR *)v122;
MiUnlockWorkingSetExclusive(v122, a13);
v127[1] = 4096i64;
v127[0] = (__int64)((a3 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16;
MiPrefetchVirtualMemory(1ui64, (INT64)v127, v55, 45i64);
v56 = MiGetSharedVm((INT64)v55);
v25 = ExAcquireSpinLockExclusive((PEX_SPIN_LOCK)v56);
*((_DWORD *)v56 + 1) = 0;
v21 = v118;
a13 = v25;
goto LABEL_33;
}
v85 = *(unsigned __int16 *)(v54 + 1838);
v86 = 0;
v112 = 0;
v115 = 0;
v87 = *(_QWORD *)(qword_140C4E388 + 8 * v85);
if( *(_QWORD *)(qword_140C4E388 + 8i64 * *(unsigned __int16 *)(v118 + 174)) == v87 )
{
LABEL_108:
MI_MAKE_PROTECT_WRITE_COPY((_MMPTE *)&v111);
v89 = v111;
if( (v111 & 2) != 0 )
{
MiReleasePageFileInfo(
v87,
v111 & 0xFFFFFFFFFFFFFFFBui64,
1,
v88,
(INT64)a5a,
(INT64)v104,
v105,
(INT64)p_NewPage,
v107,
v108,
v109,
(INT64)v110);
v89 &= ~2ui64;
v111 = v89;
}
*v24 = 0i64;
*v24 = v89;
v24[1] = v112;
v24[3] = 2i64;
v90 = MiSwizzleInvalidPte(((_QWORD)v24 << 16) | 0x400i64);
v114 = 0;
v111 = v90;
*(_QWORD *)a3 = v90;
if( (a3a[0] & 1) != 0 )
{
v91 = (unsigned int)Partition;
if( (_DWORD)Partition != 24 )
v111 |= 8ui64;
v71 = v115 == 0;
v24[2] = 1i64;
if( v71 )
++a14[1];
else
++*a14;
_InterlockedExchangeAdd64((volatile signed __int64 *)(v87 + 7624), 1ui64);
v92 = v24[2];
}
else
{
if( v112 == 1 )
v24[1] = 1i64;
v24[2] = 0i64;
v91 = (unsigned int)Partition;
v92 = 0i64;
}
v93 = v111;
v24[2] = v92 & 0x7FFFFFFFFFFFFFFi64 | ((unsigned __int64)v91 << 59);
*a4 = v93;
_InterlockedExchangeAdd64((volatile signed __int64 *)(a1 + 1272), 0xFFFFFFFFFFFFFFFFui64);
goto LABEL_77;
}
if( (v53 & 1) != 0 )
{
if( !(unsigned int)MiChargeCommit((_MI_PARTITION *)v87, 1ui64, 0i64) )
{
MiWriteUselessChildPte((UINT64 *)a4);
*a15 = 1;
goto LABEL_145;
}
v86 = 1;
v115 = 1;
}
if( (unsigned int)MiGetCrossPartitionCloneCharges(v87) )
{
v112 = 1;
goto LABEL_108;
}
MiWriteUselessChildPte((UINT64 *)a4);
*a15 = 1;
if( v86 )
{
v57 = (_MI_PARTITION *)v87;
LABEL_46:
MiReturnCommit(v57, 1ui64);
}
LABEL_145:
if( NewPage != -1i64 )
MiLockAndInsertPageInFreeList((_MMPFN *)((char *)MmGetPfnDb() + 48 * NewPage));
return v51;
}Referenced by:
MiCloneVads