MiIdentifyPfn
INT64 __fastcall MiIdentifyPfn(_MMPFN *a1, UINT64 *a2){
WCHAR *v2;
__int128 v3;
__int128 v6;
__m128i v7;
signed __int64 v8;
int v9;
UINT64 v10;
unsigned int v11;
bool v12;
unsigned __int64 v13;
unsigned __int64 v14;
_MMPFN *BaseResidentPage;
INT64 v16;
unsigned int v17;
__int64 PfnPageSizeIndex;
int v19;
unsigned __int64 v20;
__int64 v21;
__int64 v22;
INT64 v23;
UINT64 v24;
INT64 result;
unsigned __int64 v26;
unsigned __int64 v27;
__int64 v28;
UNICODE_STRING *v29;
int v30;
UINT64 v31;
UINT64 *v32;
__int64 v33;
__int64 v34;
unsigned __int64 v35;
unsigned __int64 v36;
int v37;
int v38;
int v39;
unsigned __int64 v40;
__int64 v41;
__int64 v42;
signed __int32 v43;
bool v44;
signed __int32 v45;
unsigned __int64 v46;
__int16 v47;
unsigned __int64 v48;
__int64 v49;
unsigned __int64 v50;
int v51;
INT64 v52;
unsigned __int64 v53;
unsigned int v54;
unsigned __int64 PteBase;
unsigned __int64 v56;
unsigned int SystemRegionType;
__int64 v58;
UINT64 TopLevelPfn;
UINT64 v60;
int v61;
_MMPTE *PteLimit;
unsigned __int64 v63;
unsigned __int64 v64;
UINT64 v65;
UINT64 v66;
char *v67;
char *v68;
int v69;
__int64 v70;
__int64 v71;
__int128 *v72;
__int64 v73;
bool v74;
char SpinCount[12];
UINT64 v76;
INT64 a1a[2];
__int128 v78;
__m128i v79;
__int64 v80;
__int128 v81[2];
v3 = *(_OWORD *)a1;
v6 = *((_OWORD *)a1 + 1);
*(_QWORD *)&SpinCount[4] = a1;
v7 = *((__m128i *)a1 + 2);
*(_OWORD *)a1a = v3;
v78 = v6;
v79 = v7;
v8 = (a1 - MmGetPfnDb()) / 48;
v80 = v8;
a2[1] = v8;
*(_DWORD *)SpinCount = _mm_cvtsi128_si32(_mm_srli_si128(v7, 2));
v9 = SpinCount[0] & 7;
LOBYTE(v11) = _mm_cvtsi128_si32(_mm_srli_si128(v7, 3));
v12 = (v11 & 8) != 0;
v74 = v12;
if( (v11 & 8) != 0 )
v11 = 5;
else
v11 = (unsigned __int8)v11;
v13 = v79.m128i_u64[1];
v10 = *a2 & 0xFFFFFFFFFFFFFF8Fui64 | (16i64 * (SpinCount[0] & 7));
v14 = v10 ^ (v10 ^ ((unsigned __int64)v11 << 57)) & 0xE00000000000000i64;
*a2 = v14;
if( (v13 & 0x1000000000i64) == 0 )
{
v28 = v9;
v29 = (UNICODE_STRING *)0x140000000i64;
switch( v28 )
{
case 0i64:
case 1i64:
case 5i64:
return 1i64;
case 2i64:
case 3i64:
case 4i64:
if( v79.m128i_i16[0] )
{
v14 |= 0x100ui64;
*a2 = v14;
}
if( (*((_QWORD *)&v78 + 1) & 0x4000000000000000i64) != 0 )
{
LOBYTE(v37) = MI_PFN_IS_PROTO((UNICODE_STRING *)a1a, (UNICODE_STRING *)0x140000000i64, v12, v2);
if( !v37 )
a2[2] = (((a1a[1] << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16) & 0xFFFFFFFFFFFFF000ui64;
*a2 = v14 & 0xFFFFFFFFFFFFFFF0ui64;
return 1i64;
}
MiIsActivePfnCold((INT64)a1a);
if( v38 )
{
v14 |= 0x80ui64;
LABEL_33:
*a2 = v14;
}
LABEL_34:
LOBYTE(v30) = MI_PFN_IS_PROTO((UNICODE_STRING *)a1a, v29, v12, v2);
if( v30 )
{
v33 = v78;
if( (v78 & 0x400) != 0 )
{
if( qword_140C4DC80 && (v78 & 0x10) == 0 )
v33 = v78 & ~qword_140C4DC80;
v41 = v33 >> 16;
v42 = *(_QWORD *)v41;
*(_DWORD *)SpinCount = 0;
if( _interlockedbittestandset((volatile signed __int32 *)(v42 + 72), 0x1Fu) )
{
LOBYTE(v31) = -1;
*(_DWORD *)SpinCount = ExpWaitForSpinLockExclusiveAndAcquire((RTL_BITMAP *)(v42 + 72), v31, v32);
}
v43 = *(_DWORD *)(v42 + 72);
while( (v43 & 0xBFFFFFFF) != 0x80000000 )
{
if( (v43 & 0x40000000) == 0 )
{
v45 = _InterlockedCompareExchange((volatile signed __int32 *)(v42 + 72), v43 | 0x40000000, v43);
v44 = v43 == v45;
v43 = v45;
if( !v44 )
continue;
}
KeYieldProcessorEx((UINT64 *)SpinCount);
v43 = *(_DWORD *)(v42 + 72);
}
if( (*(_QWORD *)(v42 + 64) & 0xFFFFFFFFFFFFFFF0ui64) != 0 )
{
a2[2] = *(_QWORD *)((*(_QWORD *)(v42 + 64) & 0xFFFFFFFFFFFFFFF0ui64) + 0x18);
*(_DWORD *)(v42 + 72) = 0;
a2[2] ^= (*((_DWORD *)a2 + 4) ^ (*(_DWORD *)(v42 + 56) >> 5)) & 1;
v46 = *(_QWORD *)(v41 + 8);
if( v46 )
{
v47 = *(_WORD *)(v41 + 34);
if( (v47 & 2) != 0 && (*(_DWORD *)(v42 + 56) & 0x4000000) != 0 )
{
*a2 ^= (*a2 ^ MiStartingOffset(v41, v46, 0xFFFFFFFF)) & 0x1FFFFFFFFFFFE00i64;
}
else
{
v48 = a1a[1] | 0x8000000000000000ui64;
if( (*(_DWORD *)(*(_QWORD *)v41 + 56i64) & 0x20) != 0 )
{
if( v48 < v46 || v48 >= v46 + 8i64 * *(unsigned int *)(v41 + 44) )
{
if( (v47 & 2) != 0 )
v49 = (v48 << 9) - (MiGetSharedProtos(*(_QWORD *)v41, 0xFFFFFFFF, v41)[9] << 9);
else
v49 = (v48 << 9) - (*(_QWORD *)(MiGetSubsectionDriverProtos((_QWORD *)v41) + 72) << 9);
}
else
{
v49 = (v48 << 9) - (v46 << 9);
}
v50 = ((unsigned __int64)*(unsigned int *)(v41 + 36) << 9) + (v49 & 0xFFFFFFFFFFFFF000ui64);
}
else
{
v50 = ((__int64)(v48 - v46) >> 3 << 12)
+ ((*(unsigned int *)(v41 + 36) | ((unsigned __int64)(*(_WORD *)(v41 + 32) & 0xFFC0) << 26)) << 12);
}
*a2 ^= (*a2 ^ v50) & 0x1FFFFFFFFFFFE00i64;
}
}
v51 = *(_DWORD *)(v42 + 56);
if( (v51 & 8) == 0 || (v51 & 1) != 0 )
*a2 = *a2 & 0xFFFFFFFFFFFFFFF0ui64 | 1;
else
*a2 = *a2 & 0xFFFFFFFFFFFFFFF0ui64 | 8;
}
else
{
*a2 = *a2 & 0xFFFFFFFFFFFFFE8Fui64 | 0x10;
ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)(v42 + 72));
}
}
else
{
v34 = a1a[1];
v35 = a1a[1] | 0x8000000000000000ui64;
a2[2] = a1a[1] | 0x8000000000000000ui64;
if( v34 > 0 )
{
a2[2] = v35 | 1;
v36 = *(_QWORD *)(v35 - 16);
if( v36 >= 0x1000000000000i64 )
v36 = 0xFFFFFFFFFFFFi64;
v14 = *a2 ^ (*a2 ^ (v36 << 9)) & 0x1FFFFFFFFFFFE00i64;
}
*a2 = v14 & 0xFFFFFFFFFFFFFFF0ui64 | 2;
}
return 1i64;
}
v52 = a1a[1];
v53 = a1a[1];
if( a1a[1] && ((v13 >> 60) & 7) != 1 )
v53 = a1a[1] | 0x8000000000000000ui64;
if( (unsigned int)MiGetSystemRegionType(v53) == 5 )
{
*a2 = (v14 ^ (v14 ^ ((v53 - 1432) << 9)) & 0x1FFFFFFFFFFFE00i64) & 0xFFFFFFFFFFFFFFF0ui64 | 3;
a2[2] = (__int64)(((_QWORD)MmGetPxeSelfRef() << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16;
return 1i64;
}
if( v53 == -8i64 )
{
*a2 = v14 & 0xFFFFFFFFFFFFFFF0ui64 | 5;
a2[2] = (UINT64)MmBadPointer;
return 1i64;
}
v76 = (v13 >> 60) & 7;
if( v76 != 1 )
{
v54 = 0;
PteBase = (unsigned __int64)MmGetPteBase();
if( v53 )
v56 = (__int64)((v53 << 25) - (PteBase << 25)) >> 16;
else
v56 = 0i64;
SystemRegionType = MiGetSystemRegionType(v56);
if( SystemRegionType == 5 )
{
a2[2] = v56;
*a2 = v14 & 0xFFFFFFFFFFFFFFF0ui64 | 5;
return 1i64;
}
a2[2] = v56 & 0xFFFFFFFFFFFFF000ui64;
if( (v79.m128i_i64[1] & 0xFFFFFFFFFi64) == 0xFFFFFFFFDi64 )
{
result = 1i64;
if( SystemRegionType == 9 )
*a2 = v14 & 0xFFFFFFFFFFFFFFF0ui64 | 6;
else
*a2 = v14 & 0xFFFFFFFFFFFFFFF0ui64 | 0xA;
return result;
}
if( v56 > 0x7FFFFFFEFFFFi64 )
{
if( v76 == 2 )
{
*a2 = v14 & 0xFFFFFFFFFFFFFFF0ui64 | 0xB;
return 1i64;
}
if( SystemRegionType == 1 )
{
v58 = *(_QWORD *)&SpinCount[4];
TopLevelPfn = MiGetTopLevelPfn(*(UINT64 *)&SpinCount[4]);
if( (*(_QWORD *)(TopLevelPfn + 24) & 0x4000000000000000i64) != 0 )
{
*a2 &= 0xFE000000000001FFui64;
v60 = *a2;
}
else
{
v60 = *a2 & 0xFF000000000001FFui64 | ((*(_QWORD *)TopLevelPfn & 0xFFFFFFFFFFE0000i64 | 0x1000000000000000ui64) >> 4);
*a2 = v60;
}
if( TopLevelPfn != v58 )
{
_InterlockedAnd64((volatile signed __int64 *)(TopLevelPfn + 24), 0x7FFFFFFFFFFFFFFFui64);
v60 = *a2;
}
*a2 = v60 & 0xFFFFFFFFFFFFFFF0ui64 | 7;
return 1i64;
}
if( SystemRegionType == 6 )
{
*a2 = v14 & 0xFFFFFFFFFFFFFFF0ui64 | 4;
return 1i64;
}
if( SystemRegionType <= 0xE )
{
v61 = 20992;
if( _bittest(&v61, SystemRegionType) )
{
*a2 = v14 & 0xFFFFFFFFFFFFFFF0ui64 | 6;
return 1i64;
}
}
}
if( (SpinCount[0] & 7) == 6 && ((a1a[0] & 1) == 0 || v74) )
{
PteLimit = MmGetPteLimit();
if( v56 > 0x7FFFFFFEFFFFi64 )
{
v63 = PteBase + (((unsigned __int64)qword_140C4F878 >> 9) & 0x7FFFFFFFF8i64);
v64 = v52 | 0x8000000000000000ui64;
if( v64 >= PteBase )
{
while( 1 )
{
if( v64 > (unsigned __int64)PteLimit )
goto LABEL_127;
if( v64 >= v63 && v64 <= PteBase + (((unsigned __int64)qword_140C4E0A8 >> 9) & 0x7FFFFFFFF8i64) )
break;
++v54;
v63 &= 0xFFFFFFFFFFFFF000ui64;
v64 = (__int64)((v64 << 25) - (PteBase << 25)) >> 16;
if( v64 < PteBase )
goto LABEL_127;
}
v65 = MiGetTopLevelPfn(*(UINT64 *)&SpinCount[4]);
v66 = *a2 & 0xFF000000000001FFui64 | ((*(_QWORD *)v65 & 0xFFFFFFFFFFE0000i64 | 0x1000000000000000ui64) >> 4);
*a2 = v66;
if( v65 != *(_QWORD *)&SpinCount[4] )
{
_InterlockedAnd64((volatile signed __int64 *)(v65 + 24), 0x7FFFFFFFFFFFFFFFui64);
v66 = *a2;
}
*a2 = v66 & 0xFFFFFFFFFFFFFFF0ui64 | 0xC;
return 1i64;
}
}
LABEL_127:
if( v56 < PteBase || v56 > (unsigned __int64)PteLimit )
{
*a2 = *a2 & 0xFFFFFFFFFFFFFFF0ui64 | 5;
return 1i64;
}
}
else
{
v67 = *(char **)&SpinCount[4];
v68 = *(char **)&SpinCount[4];
v69 = 0;
memset(v81, 0, sizeof(v81));
v70 = *(_QWORD *)(*(_QWORD *)&SpinCount[4] + 40i64);
if( (v70 & 0xFFFFFFFFFi64) != v80 )
{
do
{
v71 = v70 & 0xFFFFFFFFFi64;
v68 = (char *)MmGetPfnDb() + 48 * (v70 & 0xFFFFFFFFFi64);
if( (unsigned int)++v69 > 4 )
KeBugCheckEx(0x1Au, 0x9696ui64, *(ULONG_PTR *)&SpinCount[4], 0i64, 0i64);
LODWORD(v76) = 0;
*((_QWORD *)v81 + (unsigned int)(v69 - 1)) = v68;
while( _interlockedbittestandset64((volatile signed __int32 *)v68 + 6, 0x3Fui64) )
{
do
KeYieldProcessorEx(&v76);
while( *((__int64 *)v68 + 3) < 0 );
}
v70 = *((_QWORD *)v68 + 5);
}
while( (v70 & 0xFFFFFFFFFi64) != v71 );
v67 = *(char **)&SpinCount[4];
}
v72 = v81;
do
{
v73 = *(_QWORD *)v72;
if( !*(_QWORD *)v72 )
break;
if( (char *)v73 != v68 )
_InterlockedAnd64((volatile signed __int64 *)(v73 + 24), 0x7FFFFFFFFFFFFFFFui64);
++v54;
v72 = (__int128 *)((char *)v72 + 8);
}
while( v54 < 4 );
*a2 = *a2 & 0xFF000000000001FFui64 | ((*(_QWORD *)v68 & 0xFFFFFFFFFFE0000i64 | 0x1000000000000000ui64) >> 4);
if( v68 != v67 )
_InterlockedAnd64((volatile signed __int64 *)v68 + 3, 0x7FFFFFFFFFFFFFFFui64);
if( v56 < PteBase || v56 > (unsigned __int64)MmGetPteLimit() )
{
if( v56 < qword_140C4F878 || v56 > qword_140C4E0A8 )
*a2 &= 0xFFFFFFFFFFFFFFF0ui64;
else
*a2 = *a2 & 0xFFFFFFFFFFFFFFF0ui64 | 0xC;
return 1i64;
}
}
*a2 = *a2 & 0xFFFFFFFFFFFFFFF0ui64 | 3;
return 1i64;
}
LABEL_52:
*a2 = (v14 ^ (v14 ^ (MiGetLeafPfnBuddy(a1a) << 9)) & 0x1FFFFFFFFFFFE00i64) & 0xFFFFFFFFFFFFFFF0ui64 | 9;
return 1i64;
case 6i64:
if( (a1a[0] & 1) != 0 && !v12 && v79.m128i_i16[0] <= 1u )
goto LABEL_34;
v14 |= 0x100ui64;
goto LABEL_33;
case 7i64:
v14 |= 0x100ui64;
*a2 = v14;
LOBYTE(v39) = MI_PFN_IS_PROTO((UNICODE_STRING *)a1a, (UNICODE_STRING *)0x140000000i64, v12, v2);
if( !v39 )
a2[2] = (((a1a[1] << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16) & 0xFFFFFFFFFFFFF000ui64;
if( ((v13 >> 60) & 7) == 1 )
goto LABEL_52;
v40 = v14 & 0xFFFFFFFFFFFFFFF0ui64;
if( (v13 & 0xFFFFFFFFFi64) == 0xFFFFFFFFDi64 )
v40 = v14 & 0xFFFFFFFFFFFFFFF0ui64 | 0xA;
*a2 = v40;
return 1i64;
}
}
BaseResidentPage = MiGetBaseResidentPage(a1);
PfnPageSizeIndex = (unsigned int)MiGetPfnPageSizeIndex((INT64)BaseResidentPage);
if( v17 == 6 )
{
MiIsActivePfnCold(v16);
if( v19 )
*a2 |= 0x80ui64;
}
v20 = *(_QWORD *)(v16 + 8);
if( v20 && ((*(_QWORD *)(v16 + 40) >> 60) & 7) != 1 )
v20 |= 0x8000000000000000ui64;
if( (_MMPFN *)v16 != a1 )
_InterlockedAnd64((volatile signed __int64 *)(v16 + 24), 0x7FFFFFFFFFFFFFFFui64);
v21 = MiLargePageSizes[PfnPageSizeIndex];
v22 = v8 & ~(v21 - 1);
v23 = v22 + v21 - v8;
if( v17 == 6 )
{
v24 = *a2 & 0xFFFFFFFFFFFFFE8Fui64 | 0x160;
*a2 = v24;
if( v20 )
v20 += 8 * (v8 - v22);
if( (unsigned int)MiGetSystemRegionType(v20) == 5 )
{
*a2 = (v24 ^ (v24 ^ ((v20 - 1432) << 9)) & 0x1FFFFFFFFFFFE00i64) & 0xFFFFFFFFFFFFFFF0ui64 | 3;
result = v23;
a2[2] = (__int64)(((_QWORD)MmGetPxeSelfRef() << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16;
}
else
{
if( v20 )
v20 = (__int64)((v20 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16;
if( (unsigned int)MiGetSystemRegionType(v20) == 5 )
{
a2[2] = v20;
result = v23;
*a2 = v24 & 0xFFFFFFFFFFFFFFF0ui64 | 5;
}
else
{
a2[2] = v20 & 0xFFFFFFFFFFFFF000ui64;
v26 = v24 & 0xFFFFFFFFFFFFFFF0ui64 | 6;
v27 = v24 & 0xFFFFFFFFFFFFFFF0ui64 | 0xD;
if( v20 > 0x7FFFFFFEFFFFi64 )
v27 = v26;
result = v23;
*a2 = v27;
}
}
}
else
{
if( v17 == 5 )
v17 = 1;
result = v23;
*a2 = *a2 & 0xF1FFFFFFFFFFFF8Fui64 | (16i64 * v17) & 0xF1FFFFFFFFFFFFFFui64;
}
return result;
}Referenced by:
MiConvertPrivateToProto
MiCopyOnWrite
MiDeletePteRun
MiDemoteCombinedPte
MiIdentifyPfnWrapper
MiMakePageAvoidRead
MmSetPfnListInfo
MmTryIdentifyPage