MiWalkPageTablesRecursively
INT64 __fastcall MiWalkPageTablesRecursively(INT64 a1, UINT64 a2, INT64 r8_0){
INT64 v4;
int v5;
int v6;
int v8;
UINT64 *v9;
UINT64 v10;
int v11;
_MMPTE *PteBase;
INT64 v13;
MMPTE *v14;
MMPTE *v15;
INT64 *SharedVm;
__int64 v17;
__int64 v18;
unsigned __int64 v19;
unsigned __int16 **v20;
__int64 v21;
unsigned __int16 *v22;
unsigned int v23;
char v24;
char v25;
__int64(__fastcall *v26)(INT64);
char v27;
int v28;
INT64 v29;
LONG *v30;
_MMPTE *v31;
char v32;
struct _KPRCB *CurrentPrcb;
bool v34;
__int64 v35;
_MMPTE *Pml4eBase;
_MMPTE *Pml4eLimit;
__int64 v38;
int v39;
CHAR *PageTableLockBuffer;
struct _KPRCB *v41;
int v42;
int v43;
int v44;
__int64 v45;
int v46;
int NextPageTablePte;
__int64 v48;
INT64 v49;
UINT64 *v50;
_MMPTE *v51;
__int16 v52;
__int16 v53;
char v54;
__int64 v55;
__int64 v56;
int v57;
__int64(__fastcall *v58)(INT64);
char v59;
int v60;
char v61;
__int64 v62;
unsigned __int64 v63;
int v64;
int v65;
__int16 v66;
UINT64 v67;
UINT64 *v68;
__int64 v69;
_MMPTE *v70;
__int64 v71;
UINT64 *v72;
UINT64 v73;
__int64 v74;
UINT64 *v75;
unsigned __int64 v76;
char *v77;
UINT64 v78;
__int64 v79;
UINT64 v80;
UINT64 *v81;
__int64 v82;
_MMPTE *v83;
UINT64 *v84;
__int64 v85;
UINT64 v86;
__int64 v87;
UINT64 *v88;
unsigned __int64 v89;
UINT64 v90;
INT64 *v91;
char v92;
__int64(__fastcall *v93)(INT64);
char v94;
char v95;
__int64 v97;
__int64 v98;
UINT64 v99;
__int64(__fastcall *v100)(INT64, UINT64, _QWORD);
INT64 *v101;
int a3;
INT64 v103;
int v104;
UINT64 *v105;
v104 = r8_0;
v4 = *(_QWORD *)(a1 + 24);
v100 = *(__int64(__fastcall **)(INT64, UINT64, _QWORD))(a1 + 152);
v5 = 0;
v6 = r8_0;
v103 = v4;
v98 = (int)r8_0;
v8 = 0;
v9 = (UINT64 *)(16i64 * (int)r8_0 + a1 + 80);
v97 = 16i64 * (int)r8_0;
v105 = v9;
if( a2 < *v9 )
a2 = *v9;
if( (_DWORD)r8_0 == 3 )
{
v10 = *(_QWORD *)(a1 + 136);
}
else
{
v10 = (a2 & 0xFFFFFFFFFFFFF000ui64) + 4088;
if( v10 > v9[1] )
v10 = v9[1];
}
v99 = v10;
v11 = 0;
if( a2 <= v10 )
{
while( 1 )
{
PteBase = MmGetPteBase();
if( v11 )
{
v11 = 0;
if( v8 >= 3 )
goto LABEL_28;
if( (*(_BYTE *)(a1 + 2) & 1) != 0 )
{
if( v6 != 3 )
goto LABEL_200;
v13 = *(_QWORD *)(a1 + 24);
if( (*(_BYTE *)a1 & 4) == 0 )
{
SharedVm = MiGetSharedVm(*(_QWORD *)(a1 + 24));
ExAcquireSpinLockExclusive((PEX_SPIN_LOCK)SharedVm);
*((_DWORD *)SharedVm + 1) = 0;
if( (*(_WORD *)a1 & 0x400) != 0 )
ExAcquireSpinLockExclusiveAtDpcLevel((INT64 *)&dword_140C4E05C);
goto LABEL_18;
}
v14 = (_MMPTE *)((char *)PteBase + ((a2 >> 9) & 0x7FFFFFFFF8i64));
MiLockWorkingSetShared(*(_QWORD *)(a1 + 24));
v15 = MiLockLowestValidPageTable(
v13,
(INT64 *)((__int64)(((_QWORD)v14 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16),
&v101);
if( v15 == v14 )
{
*(_QWORD *)(a1 + 48) = v14;
LABEL_18:
*(_BYTE *)(a1 + 2) &= ~1u;
goto LABEL_19;
}
MiUnlockPageTableInternal(v13, (UINT64)v15);
MiUnlockWorkingSetShared(*(_QWORD *)(a1 + 24), *(_BYTE *)(a1 + 6));
}
}
LABEL_19:
v17 = ++*(_QWORD *)(a1 + 144);
if( (*(_WORD *)a1 & 8) != 0 && (v17 & 0xF) == 0 )
{
v18 = *(_QWORD *)(a1 + 72);
v19 = *(_QWORD *)(v18 + 7104);
if( v19 < 0x420 )
{
v20 = (unsigned __int16 **)(v18 + 4200);
v21 = 0i64;
while( 1 )
{
v22 = *v20;
v23 = 0;
if( dword_140C4DC3C )
break;
LABEL_26:
++v21;
++v20;
if( v21 > 1 )
{
v8 = 4;
goto LABEL_28;
}
}
while( 1 )
{
v19 += *v22;
if( v19 >= 0x420 )
break;
++v23;
v22 += 8;
if( v23 >= dword_140C4DC3C )
goto LABEL_26;
}
}
}
if( (*(_WORD *)a1 & 2) == 0 || ((unsigned __int8)v17 & *(_BYTE *)(a1 + 5)) != 0 )
goto LABEL_90;
v29 = *(_QWORD *)(a1 + 24);
v30 = &dword_140C4F4C0;
if( (*(_BYTE *)(v29 + 184) & 7) != 2 )
v30 = (LONG *)(v29 + 192);
if( (*v30 & 0x40000000) != 0 )
{
LABEL_86:
v46 = MiYieldPageTableWalk(a1, 1i64);
if( v46 >= 3 )
v8 = v46;
goto LABEL_186;
}
if( (*(_BYTE *)a1 & 4) != 0 )
{
v31 = (_MMPTE *)((char *)MmGetPteBase() + ((a2 >> 9) & 0x7FFFFFFFF8i64));
v32 = *(_BYTE *)(v29 + 184) & 7;
a3 = 0;
if( v31 == MmGetPxeSelfRef() )
{
CurrentPrcb = KeGetCurrentPrcb();
if( v32 )
{
if( v32 == 7 )
{
v34 = *((_QWORD *)CurrentPrcb + 4523) == 0i64;
}
else
{
if( v32 == 5 )
v35 = *((_QWORD *)CurrentPrcb + 4520);
else
v35 = *((_QWORD *)CurrentPrcb + 4529);
v34 = v35 == 0;
}
}
else
{
v34 = *((_QWORD *)CurrentPrcb + 4526) == 0i64;
}
LABEL_63:
if( !v34 )
goto LABEL_86;
goto LABEL_64;
}
Pml4eBase = MmGetPml4eBase();
if( v32 )
goto LABEL_55;
Pml4eLimit = MmGetPml4eLimit();
if( v31 >= Pml4eBase && v31 <= Pml4eLimit )
{
v38 = *(_QWORD *)(*(_QWORD *)(*((_QWORD *)KeGetCurrentThread() + 23) + 1680i64) + 608i64);
if( v38 )
{
v39 = (*(_DWORD *)(v38 + 4i64 * (((unsigned int)v31 >> 3) & 0x1FF)) >> 30) & 1;
LABEL_62:
v34 = v39 == 0;
goto LABEL_63;
}
LABEL_55:
Pml4eLimit = MmGetPml4eLimit();
}
if( v32 && v31 >= Pml4eBase && v31 <= Pml4eLimit )
{
PageTableLockBuffer = MiGetPageTableLockBuffer(v29, (INT64)v31, &a3);
if( ((*(_DWORD *)PageTableLockBuffer >> a3) & 2) != 0 )
goto LABEL_86;
goto LABEL_64;
}
v39 = (*(_QWORD *)v31 >> 60) & 2;
goto LABEL_62;
}
LABEL_64:
if( (*(_WORD *)a1 & 0x400) != 0 && (dword_140C4E05C & 0x40000000) != 0 )
goto LABEL_86;
if( *(_BYTE *)(a1 + 6) < 2u )
{
v41 = KeGetCurrentPrcb();
v42 = *((_DWORD *)v41 + 3147);
if( (v42 & 1) != 0 )
{
v43 = 1;
if( *((_DWORD *)v41 + 8103) > 7u )
{
if( *((_BYTE *)v41 + 12585) )
{
v44 = 1;
LABEL_85:
if( v44 )
goto LABEL_86;
LABEL_89:
v6 = v104;
goto LABEL_90;
}
LABEL_80:
if( (v42 & 0x1E) != 0 )
{
v44 = 5;
goto LABEL_85;
}
if( *((_QWORD *)v41 + 1) != *((_QWORD *)v41 + 3) )
{
v44 = 6;
goto LABEL_85;
}
LABEL_84:
_disable();
*((_DWORD *)v41 + 7931) = 0;
*((_DWORD *)v41 + 8103) = 0;
KiResetGlobalDpcWatchdogProfiler((INT64)v41);
_enable();
v44 = 0;
goto LABEL_85;
}
}
else
{
v43 = 0;
if( (v42 & 0x1E) != 0 )
{
v44 = 2;
goto LABEL_85;
}
if( *((_BYTE *)v41 + 12585) )
{
v44 = 3;
goto LABEL_85;
}
v45 = *((_QWORD *)v41 + 2);
if( v45 && v45 != *((_QWORD *)v41 + 1) )
{
v44 = 4;
goto LABEL_85;
}
}
if( *((_DWORD *)v41 + 7931) <= 7u )
goto LABEL_89;
if( v43 )
goto LABEL_80;
goto LABEL_84;
}
LABEL_90:
if( (*(_BYTE *)a1 & 0x20) != 0 )
{
NextPageTablePte = MiGetNextPageTablePte(a1, (INT64 *)a2, (unsigned int)v6);
if( NextPageTablePte == 3 )
{
v8 = 3;
goto LABEL_186;
}
if( (*(_BYTE *)(a1 + 2) & 1) != 0 )
goto LABEL_186;
v48 = *(_QWORD *)(a1 + 64);
if( v48 && v48 == a2 )
{
*(_QWORD *)(a1 + 64) = 0i64;
LABEL_97:
v49 = v103;
LABEL_98:
v50 = v105;
goto LABEL_99;
}
}
else
{
NextPageTablePte = MiComputePxeWalkAction(a1, a2, (unsigned int)v6);
}
if( !NextPageTablePte )
goto LABEL_167;
if( NextPageTablePte == 1 || v6 <= ((*(unsigned __int8 *)(a1 + 2) >> 2) & 7) )
goto LABEL_97;
v58 = *(__int64(__fastcall **)(INT64))(a1 + 160);
v59 = *(_BYTE *)(a1 + 2) | 2;
*(_BYTE *)(a1 + 2) = v59;
if( v58 )
{
v60 = v58(a1);
v59 = *(_BYTE *)(a1 + 2);
LABEL_124:
v61 = v59 & 0xFD;
*(_BYTE *)(a1 + 2) = v61;
if( v60 >= 3 )
goto LABEL_160;
goto LABEL_125;
}
v60 = 0;
if( *(_BYTE *)(a1 + 6) != 17 )
goto LABEL_124;
v61 = v59 & 0xFD;
*(_BYTE *)(a1 + 2) = v61;
LABEL_125:
if( (v61 & 1) != 0 )
goto LABEL_160;
v51 = MmGetPteBase();
v62 = (_QWORD)v51 << 25;
v63 = (__int64)((a2 << 25) - ((_QWORD)v51 << 25)) >> 16;
if( v63 < *(_QWORD *)(a1 + 16i64 * v6 + 64) )
v63 = *(_QWORD *)(a1 + 16i64 * v6 + 64);
if( v63 > *(_QWORD *)(a1 + 16i64 * v6 + 72) )
{
v49 = v103;
v50 = v105;
LABEL_100:
v52 = *(_WORD *)a1;
v53 = *(_WORD *)a1 & 1;
if( !v53 && !v6 )
{
v54 = HIBYTE(*(_QWORD *)((char *)v51
+ ((((__int64)((a2 << 25) - ((_QWORD)v51 << 25)) >> 16) & 0xFFFFFFFFF000ui64) >> 9))) & 0xF;
if( v54 == 10 || v54 == 9 || v54 == 8 && v52 >= 0 )
goto LABEL_167;
}
v55 = *(_QWORD *)(a1 + 64);
if( v55 && v55 == *v50 )
*(_QWORD *)(a1 + 64) = 0i64;
v56 = *(_QWORD *)(a1 + 56);
if( v56 && v56 == *v50 )
*(_QWORD *)(a1 + 56) = 0i64;
if( v6 >= 1 && (*(_BYTE *)(v49 + 184) & 7) != 0 && !v53 || (v52 & 0x40) != 0 )
{
LABEL_167:
v8 = 0;
}
else
{
v57 = v100(a1, a2, (unsigned int)v6);
v8 = v57;
if( v57 == 1 )
{
v8 = 0;
goto LABEL_184;
}
if( v57 == 2 )
{
v8 = 0;
MiYieldPageTableWalk(a1, 1i64);
MiWaitForFreePage(*(_MI_PARTITION **)(a1 + 72), v78);
v11 = 1;
goto LABEL_184;
}
}
v79 = *(unsigned __int8 *)(a1 + 3);
*(_BYTE *)(a1 + 3) = 0;
a2 += 8 * v79 + 8;
if( v6 || (a2 & 0xFFF) == 0 )
{
v80 = a2;
if( (*(_WORD *)a1 & 0x4000) == 0 || (v81 = (UINT64 *)(a1 + v97 + 80), a2 > *v81) )
{
v81 = (UINT64 *)(v97 + a1 + 80);
*v81 = a2;
}
v82 = v6;
v83 = MmGetPteBase();
if( v6 < 3i64 )
{
v84 = v81 + 2;
v85 = 3i64 - v6;
do
{
v80 = (UINT64)v83 + ((v80 >> 9) & 0x7FFFFFFFF8i64);
*v84 = v80;
v84 += 2;
--v85;
}
while( v85 );
v82 = v6;
}
v86 = a2;
v87 = v82;
if( v82 )
{
v88 = v81 - 2;
do
{
v89 = (__int64)((v86 << 25) - ((_QWORD)v83 << 25)) >> 16;
if( (*(_WORD *)a1 & 0x4000) == 0 || (v86 = *v88, v89 > *v88) )
{
v86 = v89;
*v88 = v89;
}
v88 -= 2;
--v87;
}
while( v87 );
}
}
else
{
*(_QWORD *)(a1 + 80) = a2;
}
LABEL_184:
if( (*(_BYTE *)(a1 + 2) & 1) == 0 && v8 < 3 )
goto LABEL_187;
goto LABEL_186;
}
if( (*(_BYTE *)a1 & 4) != 0 )
{
MiLockPageTableInternal(v103, a2, 0i64);
MiUnlockPageTableInternal(v103, (UINT64)v51 + ((a2 >> 9) & 0x7FFFFFFFF8i64));
*(_QWORD *)(a1 + 48) = a2;
}
v64 = 0;
v65 = MiWalkPageTablesRecursively(a1, (__int64)((a2 << 25) - ((_QWORD)v51 << 25)) >> 16, (unsigned int)(v104 - 1));
v50 = v105;
v8 = v65;
if( *v105 != a2 )
{
LOBYTE(v64) = (*v105 & 0xFFF) == 0;
v66 = *(_WORD *)a1 & 0x4000;
if( v66 && a2 < *v105 )
{
if( (*(_BYTE *)(a1 + 2) & 1) == 0 && (unsigned int)MiYieldPageTableWalk(a1, 1i64) == 4 )
v8 = 4;
a2 = *v50;
goto LABEL_186;
}
v67 = a2;
*(_QWORD *)(a1 + 64) = a2;
if( !v66 || (v68 = (UINT64 *)(a1 + v97 + 80), a2 > *v68) )
{
v68 = (UINT64 *)(v97 + a1 + 80);
*v68 = a2;
}
v69 = v98;
if( v98 < 3 )
{
v70 = MmGetPteBase();
v71 = 3 - v98;
v72 = v68 + 2;
do
{
v67 = (UINT64)v70 + ((v67 >> 9) & 0x7FFFFFFFF8i64);
*v72 = v67;
v72 += 2;
--v71;
}
while( v71 );
v69 = v98;
v50 = v105;
}
v73 = a2;
v74 = v69;
if( v69 )
{
v75 = v68 - 2;
do
{
v76 = (__int64)((v73 << 25) - v62) >> 16;
if( (*(_WORD *)a1 & 0x4000) == 0 || (v73 = *v75, v76 > *v75) )
{
v73 = v76;
*v75 = v76;
}
v75 -= 2;
--v74;
}
while( v74 );
}
}
if( v8 < 3 && (*(_BYTE *)(a1 + 2) & 1) == 0 )
{
if( (*(_BYTE *)a1 & 4) != 0 )
{
if( v64
|| (v49 = v103,
v77 = (char *)MmGetPteBase() + ((a2 >> 9) & 0x7FFFFFFFF8i64),
!(unsigned int)MiLockPageTableInternal(v103, (UINT64)v77, (UINT8 *)1)) )
{
v60 = MiYieldPageTableWalk(a1, 1i64);
LABEL_160:
if( v60 == 4 )
v8 = 4;
v11 = 1;
goto LABEL_187;
}
MiUnlockPageTableInternal(v49, a2);
v6 = v104;
*(_QWORD *)(a1 + 48) = v77;
goto LABEL_98;
}
v6 = v104;
v49 = v103;
LABEL_99:
v51 = MmGetPteBase();
goto LABEL_100;
}
LABEL_186:
v11 = 1;
LABEL_187:
v6 = v104;
if( a2 > v99 )
{
LABEL_28:
v4 = v103;
break;
}
}
}
if( v6 != 3 )
{
LABEL_200:
v92 = *(_BYTE *)(a1 + 2);
if( (v92 & 1) != 0 )
return(unsigned int)v8;
v93 = *(__int64(__fastcall **)(INT64))(a1 + 160);
v94 = v92 | 2;
*(_BYTE *)(a1 + 2) = v94;
if( v93 )
{
v5 = v93(a1);
v94 = *(_BYTE *)(a1 + 2);
}
else if( *(_BYTE *)(a1 + 6) == 17 )
{
v95 = v94 & 0xFD;
LABEL_205:
*(_BYTE *)(a1 + 2) = v95;
return(unsigned int)v8;
}
v95 = v94 & 0xFD;
if( v5 == 4 )
v8 = 4;
goto LABEL_205;
}
v24 = *(_BYTE *)(a1 + 2);
v25 = v24;
if( (v24 & 1) == 0 && ((*(_BYTE *)a1 & 0x40) == 0 || v8 != 3) )
{
v26 = *(__int64(__fastcall **)(INT64))(a1 + 160);
v27 = v24 | 2;
*(_BYTE *)(a1 + 2) = v24 | 2;
if( v26 )
{
v28 = v26(a1);
v27 = *(_BYTE *)(a1 + 2);
}
else
{
v28 = 0;
}
v90 = *(_QWORD *)(a1 + 48);
v25 = v27 & 0xFD;
*(_BYTE *)(a1 + 2) = v25;
if( v90 )
{
MiUnlockPageTableInternal(v4, v90);
v25 = *(_BYTE *)(a1 + 2);
*(_QWORD *)(a1 + 48) = 0i64;
}
if( v28 == 4 )
v8 = 4;
}
if( (v25 & 1) != 0 )
{
if( (*(_BYTE *)a1 & 4) != 0 )
{
MiLockWorkingSetShared(v4);
*(_BYTE *)(a1 + 2) &= ~1u;
}
else
{
v91 = MiGetSharedVm(v4);
ExAcquireSpinLockExclusive((PEX_SPIN_LOCK)v91);
*((_DWORD *)v91 + 1) = 0;
if( (*(_WORD *)a1 & 0x400) != 0 )
ExAcquireSpinLockExclusiveAtDpcLevel((INT64 *)&dword_140C4E05C);
*(_BYTE *)(a1 + 2) &= ~1u;
}
}
return(unsigned int)v8;
}Referenced by:
MiWalkPageTables
MiWalkPageTablesRecursively