MiSplitPrivatePage
INT64 __fastcall MiSplitPrivatePage(UINT64 rcx0, INT64 a2){
__int64 v3;
INT64 v4;
signed __int64 v5;
__int64 v6;
ULONG_PTR v7;
int v8;
__int64 v9;
char *v10;
unsigned int v11;
char v12;
UINT8 v13;
UINT64 v14;
unsigned __int64 v15;
ULONG_PTR v16;
volatile INT64 *v17;
int v18;
_MMPTE *v19;
INT64 v20;
_MMPFN *UsedPtesHandle;
__int16 v22;
unsigned __int64 v23;
UNICODE_STRING *v24;
UINT8 v25;
PWCHAR v26;
int v27;
__int64 v28;
int v29;
__int64 v30;
int v32;
int v33;
unsigned __int64 v34;
ULONG_PTR v35;
int v36;
INT64 v37;
int v38;
int v39;
__int64 v40;
int a6;
_ETHREAD *CurrentThread;
ULONG_PTR v43;
_MMPTE *ProtoPteAddress;
void *ContainingSubsection[11];
UINT8 WsIrql;
int v49;
a6 = 0;
v3 = a2;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v43 = *((_QWORD *)CurrentThread + 23);
v4 = v43 + 1664;
v38 = MiVadPureReserve(a2);
v5 = (signed __int64)MmGetPteBase() + ((rcx0 >> 9) & 0x7FFFFFFFF8i64);
ContainingSubsection[0] = *(void **)(v6 + 72);
v8 = MiChargeFullProcessCommitment(v7, 1ui64);
v9 = v8;
v10 = 0i64;
v11 = (*(_DWORD *)(v3 + 48) >> 12) & 0x3F;
v49 = v8;
v36 = 0;
v39 = 0;
v12 = MiLockWorkingSetShared(v43 + 1664);
WsIrql = v12;
v40 = v9;
while( 1 )
{
v13 = v12;
v14 = v5;
if( v38 )
break;
LABEL_11:
MiMakeSystemAddressValid(v14, 0i64, v11, v13, 0);
LABEL_12:
ProtoPteAddress = MiGetProtoPteAddress((_MMVAD *)v3, rcx0 >> 12, 0i64, (_SUBSECTION **)ContainingSubsection);
v19 = ProtoPteAddress;
v37 = MI_READ_PTE_LOCK_FREE(v5);
v20 = v37;
if( !v37 )
{
if( v40 < 0 )
goto LABEL_47;
UsedPtesHandle = MiGetUsedPtesHandle(rcx0);
MiIncreaseUsedPtesCount(UsedPtesHandle, 1ui64);
if( v38 )
{
if( !v19
|| (v22 = MI_READ_PTE_LOCK_FREE((INT64)MmGetPteBase() + (((unsigned __int64)v19 >> 9) & 0x7FFFFFFFF8i64)),
(v22 & 1) == 0)
&& (v22 & 0x3E0) == 0 )
{
v36 = 1;
LABEL_44:
v32 = v49;
goto LABEL_45;
}
}
v37 = MiSwizzleInvalidPte(-4294966240i64);
v20 = v37;
*(_QWORD *)v5 = v37;
v3 = a2;
v19 = ProtoPteAddress;
}
if( (v20 & 1) != 0 )
{
v23 = MI_READ_PTE_LOCK_FREE((INT64)&v37);
LOBYTE(v27) = MI_PFN_IS_PROTO((UNICODE_STRING *)MmGetPfnDb() + 3 * ((v23 >> 12) & 0xFFFFFFFFFi64), v24, v25, v26);
if( !v27 || (_MMPTE *)(*(_QWORD *)(v28 + 8) | 0x8000000000000000ui64) != v19 )
goto LABEL_55;
if( v40 < 0 )
{
LABEL_47:
if( v10 )
MiUnlockPageTableInternal(v4, (UINT64)v10);
v32 = v49;
LABEL_50:
MiUnlockWorkingSetShared(v4, WsIrql);
return(unsigned int)v32;
}
v29 = MiCopyOnWrite(rcx0, (UINT64 *)v5, -1i64, 0i64);
if( v29 >= 0 )
goto LABEL_44;
if( v10 )
{
MiUnlockPageTableInternal(v4, (UINT64)v10);
v10 = 0i64;
}
v12 = WsIrql;
MiUnlockWorkingSetShared(v4, WsIrql);
MiCopyOnWriteCheckConditions(v4, (unsigned int)v29);
MiLockWorkingSetShared(v4);
v9 = v40;
}
else
{
if( (v20 & 0x400) == 0 )
goto LABEL_55;
if( !MiIsPrototypePteVadLookup(v20) )
{
v30 = v20;
if( qword_140C4DC80 && (v20 & 0x10) == 0 )
v30 = v20 & ~qword_140C4DC80;
if( (_MMPTE *)(v30 >> 16) != v19 )
{
LABEL_55:
v33 = 0;
v32 = v49;
goto LABEL_56;
}
}
v12 = WsIrql;
if( (int)MiMakeProtoLeafValid((MMPTE *)v5, 0x18ui64, WsIrql) < 0 && v20 == MI_READ_PTE_LOCK_FREE(v5) )
{
v32 = v49;
if( v49 < 0 )
{
if( v10 )
MiUnlockPageTableInternal(v4, (UINT64)v10);
goto LABEL_50;
}
v36 = 1;
LABEL_45:
v33 = 1;
v34 = ((((unsigned __int64)*(unsigned __int8 *)(a2 + 34) << 31) | *(_DWORD *)(a2 + 52) & 0x7FFFFFFF) + 1) >> 31;
*(_DWORD *)(a2 + 52) ^= (*(_DWORD *)(a2 + 52) ^ (((*(unsigned __int8 *)(a2 + 34) << 31) | *(_DWORD *)(a2 + 52) & 0x7FFFFFFF)
+ 1)) & 0x7FFFFFFF;
*(_BYTE *)(a2 + 34) = v34;
if( v36 == 1 )
{
v37 = MiSwizzleInvalidPte(32i64);
*(_QWORD *)v5 = v37;
v33 = 1;
}
LABEL_56:
if( v10 )
MiUnlockPageTableInternal(v4, (UINT64)v10);
MiUnlockWorkingSetShared(v4, WsIrql);
v35 = v43;
if( v39 == 1 )
{
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)(v43 + 1232), 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((volatile INT64 *)(v35 + 1232));
KeAbPostRelease((PVOID)(v35 + 1232));
KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
}
if( !v33 && v32 >= 0 )
MiReturnFullProcessCommitment(v35, 1ui64);
return 0i64;
}
v9 = v40;
if( v10 )
{
MiUnlockPageTableInternal(v4, (UINT64)v10);
v10 = 0i64;
}
}
}
MiGetNextPageTable(v5, v5, 0i64, v12, 0, &a6);
if( v15 )
v10 = (char *)MmGetPteBase() + ((v15 >> 9) & 0x7FFFFFFFF8i64);
if( v5 == v15 )
goto LABEL_12;
if( v10 )
MiUnlockPageTableInternal(v4, (UINT64)v10);
MiUnlockWorkingSetShared(v4, v12);
if( v9 < 0 )
return(unsigned int)v49;
v39 = 1;
--*((_WORD *)CurrentThread + 243);
v16 = v43;
v17 = (volatile INT64 *)(v43 + 1232);
ExAcquirePushLockExclusiveEx(v43 + 1232, 0i64);
v18 = MiCommitPageTablesForVad(v3, rcx0, rcx0);
if( v18 >= 0 )
{
v10 = (char *)MmGetPteBase() + (((unsigned __int64)v5 >> 9) & 0x7FFFFFFFF8i64);
WsIrql = MiLockWorkingSetShared(v4);
v13 = WsIrql;
v14 = v5;
goto LABEL_11;
}
if( (_InterlockedExchangeAdd64(v17, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock(v17);
KeAbPostRelease((PVOID)v17);
KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
if( v49 >= 0 )
MiReturnFullProcessCommitment(v16, 1ui64);
return(unsigned int)v18;
}Referenced by:
MiCopyToCfgBitMap