MiDeleteValidSystemPage
CHAR __fastcall MiDeleteValidSystemPage(INT64 rcx0, MMPTE *a2, INT64 a3, INT64 a4){
INT64 v4;
ULONG_PTR v5;
_MMPTE *Pml4eBase;
unsigned __int64 PxeUserLimit;
__int64 v9;
__int64 v10;
_MMPFN *PfnDb;
__int64 v12;
UNICODE_STRING *v13;
UINT64 v14;
int v15;
__int64 v16;
__int64 v17;
INT64 v18;
__int64 v19;
int v20;
__int64 v21;
char *v22;
int v23;
__int64 v24;
__int64 v25;
char v26;
unsigned __int64 v27;
_ETHREAD *CurrentThread;
UINT64 v29;
unsigned int v30;
INT64 v31;
unsigned __int64 v32;
__int64 v33;
UINT64 v34;
int IsZero;
__int64 v36;
UINT64 v37;
ULONG_PTR BugCheckParameter4;
INT64 v40;
UINT64 v41;
INT64 a8;
INT64 a1;
INT64 a10;
INT64 v45;
INT64 a12;
UINT64 SpinCount;
int v49;
INT64 v50;
v50 = a4;
v49 = a3;
v4 = ZeroPte;
v5 = *(_QWORD *)a2;
a10 = 0i64;
Pml4eBase = MmGetPml4eBase();
PxeUserLimit = (unsigned __int64)MmGetPxeUserLimit();
if( a2 >= Pml4eBase && (unsigned __int64)a2 <= PxeUserLimit )
PxeUserLimit = (unsigned __int64)MmGetPxeUserLimit();
v9 = *(unsigned __int16 *)(rcx0 + 174);
a8 = v5;
v10 = *(_QWORD *)(qword_140C4E388 + 8 * v9);
if( &a8 < (INT64 *)Pml4eBase || (unsigned __int64)&a8 > PxeUserLimit )
PxeUserLimit = v5;
PfnDb = MmGetPfnDb();
v12 = 48 * ((PxeUserLimit >> 12) & 0xFFFFFFFFFi64);
v13 = *(UNICODE_STRING **)((char *)PfnDb + v12 + 40);
v14 = (UINT64)PfnDb + v12;
a1 = *(_QWORD *)(qword_140C4E388 + 8 * (((unsigned __int64)v13 >> 39) & 0x3FF));
LOBYTE(v15) = MI_PFN_IS_PROTO((UNICODE_STRING *)((char *)PfnDb + v12), v13, (UINT8)PfnDb, (PWCHAR)a4);
if( v15 )
{
if( (v16 & 0x1000000000i64) == 0 )
{
v21 = *(_QWORD *)(v14 + 8);
if( v21 > 0 )
a10 = v21 | 0x8000000000000000ui64;
}
v22 = (char *)MmGetPfnDb() + 48 * MiGetContainingPageTable((UINT64)a2);
LODWORD(SpinCount) = v23;
while( _interlockedbittestandset64((volatile signed __int32 *)(v14 + 24), 0x3Fui64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( *(__int64 *)(v14 + 24) < 0 );
}
if( (v5 & 0x42) != 0 )
v4 = MiCaptureDirtyBitToPfn(v14);
v24 = *(_QWORD *)(v14 + 16);
if( (v24 & 0x400) == 0 || (v5 & 0x200) != 0 )
{
v25 = v50;
v26 = v49;
++*(_QWORD *)(v50 + 24);
}
else
{
if( qword_140C4DC80 && (v24 & 0x10) == 0 )
v24 &= ~qword_140C4DC80;
v25 = v50;
v26 = v49;
if( (*(_DWORD *)(*(_QWORD *)(v24 >> 16) + 56i64) & 0x820) == 2080 )
++*(_QWORD *)(v50 + 24);
}
LABEL_45:
if( (v26 & 0x10) != 0 )
*(_BYTE *)(v14 + 35) &= ~8u;
v32 = ZeroPte;
if( a2 >= MmGetPml4eBase()
&& a2 <= MmGetPxeUserLimit()
&& (*(_DWORD *)(*((_QWORD *)KeGetCurrentThread() + 23) + 2172i64) & 0x1000) != 0
&& (ZeroPte & 1) != 0 )
{
v32 = ZeroPte | 0x8000000000000000ui64;
}
*(_QWORD *)a2 = v32;
if( (*(_BYTE *)(v14 + 34) & 7) != 6 )
MiBadShareCount((_MMPFN *)v14);
v33 = *(_QWORD *)(v14 + 24);
v34 = (v33 & 0x3FFFFFFFFFFFFFFFi64) - 1;
*(_QWORD *)(v14 + 24) = v33 ^ (v34 ^ v33) & 0x3FFFFFFFFFFFFFFFi64;
if( (v33 & 0x3FFFFFFFFFFFFFFFi64) == 1 )
IsZero = MiPfnShareCountIsZero(v14, v34);
else
IsZero = 2;
_InterlockedAnd64((volatile signed __int64 *)(v14 + 24), 0x7FFFFFFFFFFFFFFFui64);
HIDWORD(v41) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)v22 + 6, 0x3Fui64) )
{
do
KeYieldProcessorEx((UINT64 *)((char *)&v41 + 4));
while( *((__int64 *)v22 + 3) < 0 );
}
if( (v22[34] & 7) != 6 )
MiBadShareCount((_MMPFN *)v22);
v36 = *((_QWORD *)v22 + 3);
v37 = (v36 & 0x3FFFFFFFFFFFFFFFi64) - 1;
*((_QWORD *)v22 + 3) = v36 ^ (v37 ^ v36) & 0x3FFFFFFFFFFFFFFFi64;
if( (v36 & 0x3FFFFFFFFFFFFFFFi64) == 1 )
MiPfnShareCountIsZero((UINT64)v22, v37);
_InterlockedAnd64((volatile signed __int64 *)v22 + 3, 0x7FFFFFFFFFFFFFFFui64);
if( v4 )
MiReleasePageFileInfo(a1, v4, 1, v18, BugCheckParameter4, v40, v41, a8, a1, a10, v45, a12);
LOBYTE(CurrentThread) = a10;
if( a10 )
{
LODWORD(CurrentThread) = MiDecrementCombinedPte(rcx0, (_MMPTE *)a10);
IsZero = (int)CurrentThread;
}
if( IsZero == 3 )
++*(_QWORD *)(v25 + 8);
return(char)CurrentThread;
}
if( v14 != qword_140C4EAA0 )
{
if( (MMPTE *)(*(_QWORD *)(v14 + 8) | 0x8000000000000000ui64) != a2 )
KeBugCheckEx(0x1Au, 0x404ui64, (ULONG_PTR)a2, v5, *(_QWORD *)(v14 + 8));
++*(_QWORD *)(v18 + 24);
v22 = (char *)(v17 + 48 * (v19 & v16));
LODWORD(v41) = v20;
while( _interlockedbittestandset64((volatile signed __int32 *)(v14 + 24), 0x3Fui64) )
{
do
KeYieldProcessorEx(&v41);
while( *(__int64 *)(v14 + 24) < 0 );
}
*(_QWORD *)(v14 + 24) |= 0x4000000000000000ui64;
if( ((*(_QWORD *)(v14 + 40) >> 60) & 7) == 2 )
{
v29 = MiCaptureDirtyBitToPfn(v14);
v30 = *(unsigned __int16 *)(v14 + 32);
v4 = v29;
if( (!(_WORD)v30 || v30 > 2 && (v30 != 3 || (*(_BYTE *)(v14 + 34) & 8) == 0)) && a1 != v10 )
KeBugCheckEx(0x1Au, 0x406ui64, (ULONG_PTR)a2, v12 / 48, *(unsigned __int16 *)(v14 + 32));
*(_QWORD *)(v14 + 40) &= 0x8FFFFFFFFFFFFFFFui64;
}
v26 = v49;
if( (v49 & 4) != 0 && (unsigned int)MiIsPfnSystemCharged(v14) )
{
MiDriverPageIsDangling(v31);
*(_BYTE *)(v14 + 35) &= ~0x20u;
}
v25 = v50;
goto LABEL_45;
}
v27 = ZeroPte;
LODWORD(CurrentThread) = MiPteInShadowRange((UINT64)a2);
if( (_DWORD)CurrentThread )
{
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
if( (*(_DWORD *)(*((_QWORD *)CurrentThread + 23) + 2172i64) & 0x1000) != 0 && (ZeroPte & 1) != 0 )
v27 = ZeroPte | 0x8000000000000000ui64;
}
*(_QWORD *)a2 = v27;
return(char)CurrentThread;
}Referenced by:
MiDeleteKernelStack
MiDeleteSystemPagableVm
MiTerminateWsleCluster