MiFlushDirtyBitsToPfn
void *__fastcall MiFlushDirtyBitsToPfn(unsigned __int64 a1, unsigned __int64 a2, __int64 a3){
void *v6;
_MMPTE *PteBase;
INT64 *v8;
unsigned __int64 v9;
INT64 v10;
char v11;
INT64 *v12;
UINT64 v13;
_MMPFN *v14;
__int64 v15;
INT64 v16;
unsigned __int64 v17;
char *v18;
unsigned __int64 v19;
__int64 v20;
unsigned __int64 v21;
__int64 v22;
INT64 v23;
unsigned __int64 v24;
_MMPFN *PfnDb;
__int64 v26;
unsigned int v27;
volatile signed __int32 *v28;
char i;
UINT64 v30;
unsigned int a6;
UINT64 SpinCount;
INT64 v33;
UINT64 v34;
int result;
__int16 result_4;
int v37;
__int64 v38;
__int64 v39;
a6 = 0;
v6 = (void *)memset((INT64)&result, 0i64);
if( !byte_140C4DC28 )
{
result = 1;
result_4 = 0;
v38 = 0i64;
v37 = 20;
v39 = 0i64;
PteBase = MmGetPteBase();
v8 = (INT64 *)((char *)PteBase + ((a1 >> 9) & 0x7FFFFFFFF8i64));
v9 = (unsigned __int64)PteBase + ((a2 >> 9) & 0x7FFFFFFFF8i64);
v33 = *(_QWORD *)(a3 + 184) + 1664i64;
v10 = v33;
v11 = MiLockWorkingSetShared(v33);
for( i = v11; (unsigned __int64)v8 <= v9; v11 = i )
{
MiGetNextPageTable((INT64)v8, v9, (INT64)&result, v11, 0, &a6);
v8 = v12;
if( !v12 )
break;
v13 = (UINT64)PteBase + (((unsigned __int64)v12 >> 9) & 0x7FFFFFFFF8i64);
v34 = v13;
if( a6 )
{
v19 = (unsigned __int64)PteBase + (((unsigned __int64)v12 >> 9) & 0x7FFFFFFFF8i64);
v20 = a6;
do
{
v13 = (UINT64)PteBase + ((v13 >> 9) & 0x7FFFFFFFF8i64);
--v20;
}
while( v20 );
v21 = 0x200000i64;
if( a6 > 1 )
{
v22 = a6 - 1;
do
{
v19 = (unsigned __int64)PteBase + ((v19 >> 9) & 0x7FFFFFFFF8i64);
v21 <<= 9;
--v22;
}
while( v22 );
}
v23 = MI_READ_PTE_LOCK_FREE(v19);
v30 = v23;
v24 = v23;
if( (v23 & 1) != 0 && (v23 & 0x42) != 0 )
{
MiPteInShadowRange((UINT64)&v30);
PfnDb = MmGetPfnDb();
v26 = 48 * ((v24 >> 12) & 0xFFFFFFFFFi64) + 24;
v27 = 0;
if( v21 )
{
v28 = (volatile signed __int32 *)((char *)PfnDb + v26);
do
{
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64(v28, 0x3Fui64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( *(__int64 *)v28 < 0 );
}
*((_BYTE *)v28 + 10) |= 0x10u;
_InterlockedAnd64((volatile signed __int64 *)v28, 0x7FFFFFFFFFFFFFFFui64);
v27 += 4096;
v28 += 12;
}
while( v27 < v21 );
v10 = v33;
}
PteBase = MmGetPteBase();
}
v8 = (INT64 *)((char *)PteBase + ((MiGetLeafVa(v19 + 8) >> 9) & 0x7FFFFFFFF8i64));
}
else
{
v14 = MmGetPfnDb();
v15 = (__int64)(((_QWORD)v12 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16;
do
{
v16 = MI_READ_PTE_LOCK_FREE((INT64)v8);
v30 = v16;
v17 = v16;
if( (v16 & 1) != 0 && (v16 & 0x42) != 0 )
{
MiPteInShadowRange((UINT64)&v30);
v18 = (char *)v14 + 48 * ((v17 >> 12) & 0xFFFFFFFFFi64);
HIDWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)v18 + 6, 0x3Fui64) )
{
do
KeYieldProcessorEx((UINT64 *)((char *)&SpinCount + 4));
while( *((__int64 *)v18 + 3) < 0 );
}
v18[34] |= 0x10u;
_InterlockedAnd64((volatile signed __int64 *)v18 + 3, 0x7FFFFFFFFFFFFFFFui64);
MiWriteValidPteNewProtection(v8, v30 & 0xFFFFFFFFFFFFFFBDui64);
MiInsertTbFlushEntry((INT64)&result, v15, 1i64, 0i64);
}
v15 += 4096i64;
++v8;
}
while( (v15 & 0x1FFFFF) != 0 && (unsigned __int64)v8 <= v9 );
MiFlushTbList((__int64)&result);
v13 = v34;
v10 = v33;
PteBase = MmGetPteBase();
}
MiUnlockPageTableInternal(v10, v13);
}
return(void *)MiUnlockWorkingSetShared(v10, v11);
}
return v6;
}Referenced by:
MmFlushVirtualMemory