MiMoveDirtyBitsToPfns
INT64 __fastcall MiMoveDirtyBitsToPfns(UINT64 a1, UINT64 a2, INT64 a3, CHAR a4){
UINT64 v8;
_MMPTE *PteBase;
unsigned __int64 v10;
unsigned __int64 v11;
__int64 v12;
INT64 v13;
__int64 *i;
volatile signed __int32 *v15;
unsigned __int8 v16;
LONG *v17;
INT64 CurrentIrql;
struct _KPRCB *CurrentPrcb;
int v20;
INT64 v21;
__int64 v22;
int v23;
_MMPTE *v24;
unsigned __int64 v25;
unsigned __int64 v26;
CHAR *AnyMultiplexedVm;
int v28;
unsigned int v29;
_MMPTE *v30;
UINT64 v31;
UINT64 v32;
unsigned __int64 v33;
_MMPTE *v34;
unsigned __int64 v35;
__int64 v36;
unsigned __int64 VadMandatoryPageSize;
__int64 v38;
__int64 v39;
unsigned __int64 v40;
_MMPTE *v41;
_MMPTE *v42;
unsigned __int64 v43;
unsigned __int64 v44;
signed __int32 v45;
__int64 v46;
signed __int32 v47;
unsigned __int64 v48;
unsigned __int64 v49;
_BYTE *v50;
char v51;
int v52;
int v53;
__int64 v54;
unsigned __int64 v55;
_MMPTE *v56;
_MMPTE *v57;
int v58;
INT64 v59;
__int64 v60;
_MMPTE *v61;
unsigned int v62;
unsigned __int64 v63;
char v64;
__int64 v65;
unsigned int v66;
char v67;
unsigned __int64 v68;
unsigned __int64 v69;
UINT64 v70;
INT64 v71;
INT64 v72;
char *v73;
unsigned __int8 v74;
UINT64 v75;
INT64 v76;
__int64 v77;
unsigned __int64 v78;
unsigned __int64 v79;
_MMPTE *PteLimit;
unsigned __int64 v81;
__int64 v82;
unsigned __int64 v83;
INT64 v84;
UINT64 LeafVa;
INT64 v86;
_MMPTE *v87;
INT64 a5;
UINT64 v89;
INT64 a7;
UINT64 v91;
INT64 a9;
UINT64 SpinCount;
INT64 a11;
INT64 a12;
INT64 v96;
UINT64 v97;
unsigned __int64 *v98;
INT64 v99;
__int128 v100;
__int64 v101;
__int64 v102;
__int16 v103;
_BYTE v104[14];
__int64 v105;
CHAR *v106;
unsigned __int64 v107;
__int64 v108;
INT64(__fastcall *v109)(INT64);
__int128 *v110;
int v111;
__int16 v112;
__int16 v113;
__int64 v114;
__int64 v115;
__int64 Base;
INT64 result[20];
v96 = a3;
LOBYTE(a5) = a4;
v113 = 0;
v99 = 0i64;
memset((INT64)result, 0i64);
v89 = 0i64;
v8 = 0i64;
HIDWORD(a5) = 0;
PteBase = MmGetPteBase();
v10 = (unsigned __int64)PteBase + ((a1 >> 9) & 0x7FFFFFFFF8i64);
v11 = (unsigned __int64)PteBase + ((a2 >> 9) & 0x7FFFFFFFF8i64);
a9 = v11;
v12 = *((_QWORD *)KeGetCurrentThread() + 23);
v13 = v12 + 1664;
v101 = *(_QWORD *)(v12 + 1680);
a11 = v12 + 1664;
HIDWORD(SpinCount) = a4 & 1;
if( (a4 & 1) != 0 )
{
for( i = *(__int64 **)(a3 + 56); i; i = (__int64 *)*i )
{
if( (i[8] & 4) != 0 )
break;
}
v98 = (unsigned __int64 *)(i + 1);
}
else
{
v98 = 0i64;
}
v112 = 0;
v115 = 0i64;
Base = 0i64;
v15 = &dword_140C4F4C0;
v114 = 20i64;
v111 = 1;
v16 = *(_BYTE *)(v13 + 184) & 7;
if( v16 >= 6u )
{
CurrentIrql = KeGetCurrentIrql();
a7 = CurrentIrql;
__writecr8(2ui64);
}
else
{
if( v16 == 2 )
v17 = &dword_140C4F4C0;
else
v17 = (LONG *)(v13 + 192);
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
CurrentPrcb = KeGetCurrentPrcb();
if( *((_QWORD *)CurrentPrcb + 4247) && *((_BYTE *)CurrentPrcb + 32) <= 1u && *((_BYTE *)CurrentPrcb + 32) == 1 )
PteBase = MmGetPteBase();
_m_prefetchw(v17);
v20 = *v17 & 0x7FFFFFFF;
if( v20 != _InterlockedCompareExchange(v17, v20 + 1, v20) )
{
ExpWaitForSpinLockSharedAndAcquire((INT64 *)v17, CurrentIrql);
PteBase = MmGetPteBase();
}
v8 = 0i64;
if( v17[1] )
_InterlockedExchange(v17 + 1, 0);
a7 = CurrentIrql;
}
if( v10 > v11 )
goto LABEL_68;
v21 = (_QWORD)PteBase << 25;
a12 = (_QWORD)PteBase << 25;
v22 = (__int64)((v11 << 25) - ((_QWORD)PteBase << 25)) >> 16;
v23 = a5 & 2;
v102 = v22;
LODWORD(a5) = v23;
while( 2 )
{
if( v8 )
{
MiFlushTbList((__int64)&v111);
MiUnlockPageTableInternal(v13, v8);
v89 = 0i64;
if( MiWorkingSetIsContended(v13) || KeShouldYieldProcessor() )
{
MiUnlockWorkingSetShared(v13, CurrentIrql);
MiLockWorkingSetShared(v13);
}
v23 = a5;
}
if( v23 )
_InterlockedIncrement64((volatile signed __int64 *)(v101 + 616));
v100 = 0i64;
memset((INT64)v104, 0i64);
v24 = MmGetPteBase();
v103 = 2273;
v25 = (__int64)((v10 << 25) - v21) >> 16;
v26 = v25;
if( v25 >= (unsigned __int64)v24 )
{
PteLimit = MmGetPteLimit();
do
{
if( v26 > (unsigned __int64)PteLimit )
break;
v26 = (__int64)((v26 << 25) - v21) >> 16;
}
while( v26 >= (unsigned __int64)v24 );
v13 = a11;
}
if( v26 < 0xFFFF800000000000ui64 || v26 >= qword_140C4F878 && v26 <= qword_140C4E0A8 )
AnyMultiplexedVm = (CHAR *)(*((_QWORD *)KeGetCurrentThread() + 23) + 1664i64);
else
AnyMultiplexedVm = MiGetAnyMultiplexedVm(1i64);
v28 = MiFastLockLeafPageTable((INT64)AnyMultiplexedVm, v25);
if( v28 )
{
v29 = v28 - 1;
LODWORD(v100) = v28 - 1;
v30 = MmGetPteBase();
v31 = (UINT64)v30 + ((v25 >> 9) & 0x7FFFFFFFF8i64);
*((_QWORD *)&v100 + 1) = v31;
}
else
{
v103 |= 4u;
v110 = &v100;
v105 = 0i64;
v106 = AnyMultiplexedVm;
v104[0] = v104[0] & 0xE3 | 4;
v109 = MiGetNextPageTableTail;
v104[4] = a7;
v107 = v25;
v108 = v22;
MiWalkPageTables((INT64)&v103);
v29 = v100;
v31 = *((_QWORD *)&v100 + 1);
v30 = MmGetPteBase();
}
v32 = v31;
if( v31 )
{
v89 = (UINT64)v30 + ((v31 >> 9) & 0x7FFFFFFFF8i64);
if( v29 )
{
v32 = (UINT64)v30 + ((v31 >> 9) & 0x7FFFFFFFF8i64);
v81 = (unsigned __int64)v30 + ((v11 >> 9) & 0x7FFFFFFFF8i64);
if( v29 > 1 )
{
v82 = v29 - 1;
do
{
v32 = (UINT64)v30 + ((v32 >> 9) & 0x7FFFFFFFF8i64);
v81 = (unsigned __int64)v30 + ((v81 >> 9) & 0x7FFFFFFFF8i64);
--v82;
}
while( v82 );
}
v83 = v32 + 8;
v89 = (UINT64)v30 + ((v32 >> 9) & 0x7FFFFFFFF8i64);
if( ((v32 + 8) & 0xFFF) != 0 )
{
do
{
if( v83 > v81 )
break;
v84 = MI_READ_PTE_LOCK_FREE(v83);
v99 = v84;
if( (v84 & 1) == 0 )
break;
if( (v84 & 0x80u) == 0i64 )
break;
v83 += 8i64;
}
while( (v83 & 0xFFF) != 0 );
v30 = MmGetPteBase();
}
v33 = v83 - 8;
}
else
{
v33 = (v31 & 0xFFFFFFFFFFFFF000ui64) + 4088;
if( v33 > v11 )
v33 = v11;
}
}
else
{
v33 = v11;
}
if( !HIDWORD(SpinCount) )
goto LABEL_52;
HIDWORD(a5) = 1;
if( v10 >= (unsigned __int64)v30 )
{
v34 = MmGetPteLimit();
do
{
if( v10 > (unsigned __int64)v34 )
break;
v10 = (__int64)((v10 << 25) - a12) >> 16;
}
while( v10 >= (unsigned __int64)v30 );
v13 = a11;
}
v35 = (v10 >> 12) - (*(unsigned int *)(v96 + 24) | ((unsigned __int64)*(unsigned __int8 *)(v96 + 32) << 32));
VadMandatoryPageSize = MiGetVadMandatoryPageSize(v96);
if( VadMandatoryPageSize != 1 )
v35 /= VadMandatoryPageSize;
v40 = v33 + 8;
v41 = MmGetPteBase();
if( v33 + 8 >= (unsigned __int64)v41 )
{
v42 = MmGetPteLimit();
do
{
if( v40 > (unsigned __int64)v42 )
break;
v40 = (__int64)((v40 << 25) - v38) >> 16;
}
while( v40 >= (unsigned __int64)v41 );
v13 = a11;
}
if( v40 > (((*(unsigned int *)(v39 + 28) | ((unsigned __int64)*(unsigned __int8 *)(v39 + 33) << 32)) << 12) | 0xFFF) )
{
v43 = *v98;
}
else
{
v43 = (v40 >> 12) - v36;
if( VadMandatoryPageSize != 1 )
v43 /= VadMandatoryPageSize;
}
v44 = v43 - v35;
LODWORD(SpinCount) = 0;
KeGetCurrentIrql();
__writecr8(2ui64);
v45 = *(_DWORD *)(v39 + 48);
v46 = v39;
do
{
while( (v45 & 1) != 0 )
{
if( (v45 & 2) != 0 )
{
LODWORD(SpinCount) = 0;
do
{
KeYieldProcessorEx(&SpinCount);
v45 = *(_DWORD *)(v46 + 48);
}
while( (v45 & 1) != 0 );
}
else
{
v45 = _InterlockedCompareExchange((volatile signed __int32 *)(v46 + 48), v45 | 2, v45);
}
}
v47 = v45;
v45 = _InterlockedCompareExchange((volatile signed __int32 *)(v46 + 48), v45 & 0xFFFFFFFC | 1, v45);
}
while( v47 != v45 );
v11 = a9;
if( !v44 )
goto LABEL_52;
v48 = v35;
v49 = v35 & 7;
v50 = (_BYTE *)(v98[1] + (v48 >> 3));
if( v49 + v44 > 8 )
{
if( (_DWORD)v49 )
{
*v50++ &= byte_14001DA00[v49];
v44 -= (unsigned int)(8 - v49);
}
if( v44 > 8 )
{
memset((INT64)v50, 0i64);
v50 += v44 >> 3;
v44 &= 7u;
}
if( !v44 )
goto LABEL_51;
v51 = byte_14001A768[v44];
}
else
{
v51 = ~(byte_14001DA00[v44] << v49);
}
*v50 &= v51;
LABEL_51:
v11 = a9;
LABEL_52:
if( !v31 )
break;
if( v32 > v33 )
goto LABEL_59;
v52 = HIDWORD(SpinCount);
v53 = a5;
do
{
v54 = *(_QWORD *)v32;
v99 = v54;
if( (v54 & 1) == 0 || (v54 & 0x42) == 0 )
goto LABEL_57;
if( !v52 )
{
if( v53 && v54 < 0 )
goto LABEL_57;
LeafVa = MiGetLeafVa(v32);
if( (MiGetWsleContents(v86, LeafVa) & 0xF) == 9 )
goto LABEL_57;
}
v60 = *(_QWORD *)v32;
v61 = MmGetPteBase();
v91 = *(_QWORD *)v32 & 0xFFFFFFFFFFFFFFBDui64;
v62 = 0;
v63 = (__int64)((v32 << 25) - a12) >> 16;
if( v63 < (unsigned __int64)v61 )
goto LABEL_82;
v87 = MmGetPteLimit();
do
{
if( v63 > (unsigned __int64)v87 )
break;
++v62;
v63 = (__int64)((v63 << 25) - a12) >> 16;
}
while( v63 >= (unsigned __int64)v61 );
if( v62 )
{
MiRewritePteWithLockBit(*((_QWORD *)KeGetCurrentThread() + 23) + 1664i64, (volatile INT64 *)v32, v91);
MiInsertLargeTbFlushEntry((INT64)&v111, v62, v32);
}
else
{
LABEL_82:
*(_QWORD *)v32 = v91 ^ (v60 ^ v91) & 0xF00000000000000i64 ^ (v60 ^ v91 ^ (v60 ^ v91) & 0xF00000000000000i64) & 0x7000000000000000i64;
v64 = v112;
v65 = 1i64;
if( v111 != 1 && (v112 & 8) == 0 && v63 >= (unsigned __int64)v61 && v63 <= (unsigned __int64)MmGetPteLimit() )
{
v64 = v112 | 8;
LOBYTE(v112) = v112 | 8;
}
v66 = HIDWORD(v114);
if( !HIDWORD(v114) )
{
LABEL_98:
if( HIDWORD(v114) >= (unsigned int)v114 )
{
HIBYTE(v112) = 1;
}
else
{
while( 1 )
{
v77 = (unsigned __int64)(v65 - 1) > 0x3FF ? 1024i64 : v65;
v78 = v63 & 0xFFFFFFFFFFFFF000ui64 | ((_WORD)v77 - 1) & 0x3FF;
v65 -= v77;
v63 += v77 << 12;
result[v66 - 1] = v78;
v115 += v77;
v66 = HIDWORD(v114) + 1;
HIDWORD(v114) = v66;
if( v66 == (_DWORD)v114 && (v112 & 4) == 0 )
{
qsort((WCHAR *)&Base, v66, (const WCHAR *)8, MiTbFlushSort);
MiCompressTbFlushList((INT64)&v111);
v66 = HIDWORD(v114);
if( HIDWORD(v114) == (_DWORD)v114 )
break;
}
if( !v65 )
goto LABEL_90;
}
if( v65 )
{
HIBYTE(v112) = 1;
v115 = HIDWORD(v114);
}
}
goto LABEL_90;
}
v67 = v64 & 4;
if( v67
|| (v68 = result[(unsigned int)(HIDWORD(v114) - 1) - 1], (v68 & 0xC00) != 0)
|| (v69 = result[(unsigned int)(HIDWORD(v114) - 1) - 1] & 0x3FF,
(v68 & 0xFFFFFFFFFFFFF000ui64) + ((v69 + 1) << 12) != v63)
|| v69 + 1 <= v69
|| v69 + 1 > 0x3FF )
{
if( v67 )
goto LABEL_98;
v76 = result[(unsigned int)(HIDWORD(v114) - 1) - 1];
if( (v76 & 0xC00) != 0 )
goto LABEL_98;
if( (v76 & 0xFFFFFFFFFFFFF000ui64) != v63 + 4096 )
goto LABEL_98;
v79 = result[(unsigned int)(HIDWORD(v114) - 1) - 1] & 0x3FF;
if( v79 + 1 > 0x3FF || v79 + 1 <= v79 )
goto LABEL_98;
++v115;
result[(unsigned int)(HIDWORD(v114) - 1) - 1] = ((unsigned __int16)(v76 - 4096) ^ (unsigned __int16)(v76 - 4096 + 1)) & 0x3FF ^ (unsigned __int64)(v76 - 4096);
}
else
{
++v115;
result[(unsigned int)(HIDWORD(v114) - 1) - 1] = ((unsigned __int16)v68 ^ (unsigned __int16)(v68 + 1)) & 0x3FF ^ v68;
}
}
LABEL_90:
v70 = v91;
MiPteInShadowRange((UINT64)&v91);
v72 = 0i64;
v73 = (char *)MmGetPfnDb() + 48 * ((v70 >> 12) & 0xFFFFFFFFFi64);
LODWORD(v97) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)v73 + 6, 0x3Fui64) )
{
do
KeYieldProcessorEx(&v97);
while( *((__int64 *)v73 + 3) < 0 );
}
v74 = v73[34];
v75 = 0i64;
if( (v74 & 0x10) == 0 )
{
if( (!_bittest64((const signed __int64 *)v73 + 2, 0xAu) & (unsigned __int8)~(v74 >> 3)) != 0 )
{
v75 = MiCapturePageFileInfoInline((UINT64 *)v73 + 2, 1i64, 0i64);
v74 = v73[34];
}
v73[34] = v74 | 0x10;
if( v75 )
v72 = *(_QWORD *)(qword_140C4E388 + 8 * ((*((_QWORD *)v73 + 5) >> 39) & 0x3FFi64));
}
_InterlockedAnd64((volatile signed __int64 *)v73 + 3, 0x7FFFFFFFFFFFFFFFui64);
if( v75 )
MiReleasePageFileInfo(v72, v75, 1, v71, a5, v89, a7, v91, a9, SpinCount, a11, a12);
LABEL_57:
v32 += 8i64;
}
while( v32 <= v33 );
v13 = a11;
v11 = a9;
LABEL_59:
if( HIDWORD(a5) )
{
_InterlockedAnd((volatile signed __int32 *)(v96 + 48), 0xFFFFFFFC);
__writecr8(2ui64);
HIDWORD(a5) = 0;
}
v55 = v32;
v56 = MmGetPteBase();
if( v32 >= (unsigned __int64)v56 )
{
v57 = MmGetPteLimit();
do
{
if( v55 > (unsigned __int64)v57 )
break;
v55 = (__int64)((v55 << 25) - a12) >> 16;
}
while( v55 >= (unsigned __int64)v56 );
v13 = a11;
v11 = a9;
}
v21 = a12;
v10 = (unsigned __int64)v56 + ((v55 >> 9) & 0x7FFFFFFFF8i64);
v22 = v102;
v23 = a5;
if( v10 <= v11 )
{
v8 = v89;
LOBYTE(CurrentIrql) = a7;
continue;
}
break;
}
v15 = &dword_140C4F4C0;
LABEL_68:
MiFlushTbList((__int64)&v111);
if( HIDWORD(a5) )
MiUnlockVadCore(v96, 2u);
if( v89 )
MiUnlockPageTableInternal(v13, v89);
if( (*(_BYTE *)(v13 + 184) & 7u) < 6 )
{
v58 = *(_DWORD *)(v13 + 184);
if( (v58 & 0x8000000) != 0 || (v58 & 0x4000000) != 0 || (v58 & 0x10000000) != 0 )
{
MiPreUnlockWorkingSetShared(v13, a7);
LOBYTE(v58) = *(_BYTE *)(v13 + 184);
}
if( (v58 & 7) != 2 )
v15 = (volatile signed __int32 *)(v13 + 192);
MiCheckProcessShadow();
_InterlockedAnd(v15, 0xBFFFFFFF);
_InterlockedDecrement(v15);
}
v59 = (unsigned __int8)a7;
__writecr8((unsigned __int8)a7);
return v59;
}Referenced by:
MiBeginHoldingDirtyFaults
MiProcessVaRangesInfoClass
NtResetWriteWatch