MiIdentifyPfn
VOID __stdcall MiIdentifyPfn(_MMPFN *EntryPfn, _MMPFN_IDENTITY *PfnIdentity){
wchar_t *v2;
_LIST_ENTRY ListEntry;
__int128 v6;
__m128i v7;
signed __int64 v8;
int v9;
unsigned __int64 v10;
unsigned int v11;
bool v12;
unsigned __int64 v13;
unsigned __int64 v14;
_MMPFN *BaseResidentPage;
_MMPFN *v16;
unsigned int v17;
__int64 PfnPageSizeIndex;
unsigned __int64 PteLong;
__int64 v20;
unsigned __int64 v21;
unsigned __int64 v22;
unsigned __int64 v23;
__int64 v24;
_UNICODE_STRING *v25;
int v26;
__int64 v27;
wchar_t *Buffer;
unsigned __int64 v29;
unsigned __int64 v30;
int v31;
int v32;
unsigned __int64 v33;
__int64 v34;
_CONTROL_AREA *v35;
signed __int32 ControlAreaLock;
bool v37;
signed __int32 v38;
_MMPTE *v39;
__int16 v40;
__int64 v41;
unsigned __int64 v42;
__int64 v43;
unsigned __int64 v44;
union {unsigned int LongFlags;_MMSECTION_FLAGS Flags;} v45;
wchar_t *v46;
UINT64 v47;
unsigned int v48;
unsigned __int64 PteBase;
unsigned __int64 v50;
unsigned int SystemRegionType;
_MMPFN *v52;
_MMPFN *v53;
unsigned __int64 v54;
int v55;
_MMPTE *PteLimit;
unsigned __int64 v57;
unsigned __int64 v58;
_MMPFN *TopLevelPfn;
unsigned __int64 v60;
_MMPFN *v61;
_MMPFN *v62;
int v63;
__int64 bf_0;
__int64 v65;
__int128 *v66;
_MMPFN *v67;
bool v68;
char SpinCount[12];
UINT64 v70;
_UNICODE_STRING antNameA;
__int128 v72;
__m128i v73;
__int64 v74;
__int128 v75[2];
ListEntry = EntryPfn->ListEntry;
v6 = *((_OWORD *)&EntryPfn->3 + 1);
*(_QWORD *)&SpinCount[4] = EntryPfn;
v7 = *(__m128i *)&EntryPfn->u3.ReferenceCount;
antNameA = (_UNICODE_STRING)ListEntry;
v72 = v6;
v73 = v7;
v8 = EntryPfn - MmGetPfnDb();
v74 = v8;
*((_QWORD *)PfnIdentity + 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;
v68 = v12;
if( (v11 & 8) != 0 )
v11 = 5;
else
v11 = (unsigned __int8)v11;
v13 = v73.m128i_u64[1];
v10 = *(_QWORD *)PfnIdentity & 0xFFFFFFFFFFFFFF8Fui64 | (16i64 * (SpinCount[0] & 7));
v14 = v10 ^ (v10 ^ ((unsigned __int64)v11 << 57)) & 0xE00000000000000i64;
*(_QWORD *)PfnIdentity = v14;
if( (v13 & 0x1000000000i64) != 0 )
{
BaseResidentPage = MiGetBaseResidentPage(EntryPfn);
PfnPageSizeIndex = (unsigned int)MiGetPfnPageSizeIndex((INT64)BaseResidentPage);
if( v17 == 6 && MiIsActivePfnCold((INT64)v16) )
*(_QWORD *)PfnIdentity |= 0x80ui64;
PteLong = v16->PteLong;
if( PteLong && (((unsigned __int64)v16->u4._bf_0 >> 60) & 7) != 1 )
PteLong |= 0x8000000000000000ui64;
if( v16 != EntryPfn )
_InterlockedAnd64(&v16->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
v20 = v8 & ~(MiLargePageSizes[PfnPageSizeIndex] - 1);
if( v17 == 6 )
{
v21 = *(_QWORD *)PfnIdentity & 0xFFFFFFFFFFFFFE8Fui64 | 0x160;
*(_QWORD *)PfnIdentity = v21;
if( PteLong )
PteLong += 8 * (v8 - v20);
if( MiGetSystemRegionType(PteLong) == 5 )
{
*(_QWORD *)PfnIdentity = (v21 ^ (v21 ^ ((PteLong - 1432) << 9)) & 0x1FFFFFFFFFFFE00i64) & 0xFFFFFFFFFFFFFFF0ui64 | 3;
*((_QWORD *)PfnIdentity + 2) = (__int64)(((_QWORD)MmGetPxeSelfRef() << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16;
}
else
{
if( PteLong )
PteLong = (__int64)((PteLong << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16;
if( MiGetSystemRegionType(PteLong) == 5 )
{
*((_QWORD *)PfnIdentity + 2) = PteLong;
*(_QWORD *)PfnIdentity = v21 & 0xFFFFFFFFFFFFFFF0ui64 | 5;
}
else
{
*((_QWORD *)PfnIdentity + 2) = PteLong & 0xFFFFFFFFFFFFF000ui64;
v22 = v21 & 0xFFFFFFFFFFFFFFF0ui64 | 6;
v23 = v21 & 0xFFFFFFFFFFFFFFF0ui64 | 0xD;
if( PteLong > 0x7FFFFFFEFFFFi64 )
v23 = v22;
*(_QWORD *)PfnIdentity = v23;
}
}
}
else
{
if( v17 == 5 )
v17 = 1;
*(_QWORD *)PfnIdentity = *(_QWORD *)PfnIdentity & 0xF1FFFFFFFFFFFF8Fui64 | (16i64 * v17) & 0xF1FFFFFFFFFFFFFFui64;
}
return;
}
v24 = v9;
v25 = (_UNICODE_STRING *)0x140000000i64;
switch( v24 )
{
case 0i64:
case 1i64:
case 5i64:
return;
case 2i64:
case 3i64:
case 4i64:
if( v73.m128i_i16[0] )
{
v14 |= 0x100ui64;
*(_QWORD *)PfnIdentity = v14;
}
if( (*((_QWORD *)&v72 + 1) & 0x4000000000000000i64) == 0 )
{
if( !MiIsActivePfnCold((INT64)&antNameA) )
goto LABEL_34;
v14 |= 0x80ui64;
goto LABEL_33;
}
LOBYTE(v31) = MI_PFN_IS_PROTO(&antNameA, (_UNICODE_STRING *)0x140000000i64, v12, v2);
if( !v31 )
*((_QWORD *)PfnIdentity + 2) = ((((__int64)antNameA.Buffer << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16) & 0xFFFFFFFFFFFFF000ui64;
*(_QWORD *)PfnIdentity = v14 & 0xFFFFFFFFFFFFFFF0ui64;
return;
case 6i64:
if( (antNameA.Length & 1) == 0 || v12 || v73.m128i_i16[0] > 1u )
{
v14 |= 0x100ui64;
LABEL_33:
*(_QWORD *)PfnIdentity = v14;
}
LABEL_34:
LOBYTE(v26) = MI_PFN_IS_PROTO(&antNameA, v25, v12, v2);
if( v26 )
{
v27 = v72;
if( (v72 & 0x400) != 0 )
{
if( *(&stru_140C4DB30 + 42) && (v72 & 0x10) == 0 )
v27 = v72 & ~*(&stru_140C4DB30 + 42);
v34 = v27 >> 16;
v35 = *(_CONTROL_AREA **)v34;
*(_DWORD *)SpinCount = 0;
if( _interlockedbittestandset(&v35->ControlAreaLock, 0x1Fu) )
*(_DWORD *)SpinCount = ExpWaitForSpinLockExclusiveAndAcquire((INT64 *)&v35->ControlAreaLock, 0xFFu);
ControlAreaLock = v35->ControlAreaLock;
while( (ControlAreaLock & 0xBFFFFFFF) != 0x80000000 )
{
if( (ControlAreaLock & 0x40000000) == 0 )
{
v38 = _InterlockedCompareExchange(&v35->ControlAreaLock, ControlAreaLock | 0x40000000, ControlAreaLock);
v37 = ControlAreaLock == v38;
ControlAreaLock = v38;
if( !v37 )
continue;
}
KeYieldProcessorEx((UINT64 *)SpinCount);
ControlAreaLock = v35->ControlAreaLock;
}
if( (v35->FilePointer.Value & 0xFFFFFFFFFFFFFFF0ui64) != 0 )
{
*((_QWORD *)PfnIdentity + 2) = *(_QWORD *)((v35->FilePointer.Value & 0xFFFFFFFFFFFFFFF0ui64) + 0x18);
v35->ControlAreaLock = 0;
*((_QWORD *)PfnIdentity + 2) ^= (PfnIdentity[4] ^ (v35->u.LongFlags >> 5)) & 1;
v39 = *(_MMPTE **)(v34 + 8);
if( v39 )
{
v40 = *(_WORD *)(v34 + 34);
if( (v40 & 2) != 0 && (v35->u.LongFlags & 0x4000000) != 0 )
{
LODWORD(v41) = MiStartingOffset((_SUBSECTION *)v34, v39, 0xFFFFFFFFui64);
*(_QWORD *)PfnIdentity ^= (*(_QWORD *)PfnIdentity ^ v41) & 0x1FFFFFFFFFFFE00i64;
}
else
{
v42 = (unsigned __int64)antNameA.Buffer | 0x8000000000000000ui64;
if( (*(_DWORD *)(*(_QWORD *)v34 + 56i64) & 0x20) != 0 )
{
if( v42 < (unsigned __int64)v39 || v42 >= (unsigned __int64)&v39[*(unsigned int *)(v34 + 44)] )
{
if( (v40 & 2) != 0 )
v43 = (v42 << 9)
- ((__int64)MiGetSharedProtos(*(_CONTROL_AREA **)v34, 0xFFFFFFFFui64, (_SUBSECTION *)v34)[3].Children[0] << 9);
else
v43 = (v42 << 9) - ((__int64)MiGetSubsectionDriverProtos((_SUBSECTION *)v34)->SubsectionBase << 9);
}
else
{
v43 = (v42 << 9) - ((_QWORD)v39 << 9);
}
v44 = ((unsigned __int64)*(unsigned int *)(v34 + 36) << 9) + (v43 & 0xFFFFFFFFFFFFF000ui64);
}
else
{
v44 = ((__int64)(v42 - (_QWORD)v39) >> 3 << 12)
+ ((*(unsigned int *)(v34 + 36) | ((unsigned __int64)(*(_WORD *)(v34 + 32) & 0xFFC0) << 26)) << 12);
}
*(_QWORD *)PfnIdentity ^= (*(_QWORD *)PfnIdentity ^ v44) & 0x1FFFFFFFFFFFE00i64;
}
}
v45.LongFlags = (unsigned int)v35->u;
if( (v45.LongFlags & 8) == 0 || (v45.LongFlags & 1) != 0 )
*(_QWORD *)PfnIdentity = *(_QWORD *)PfnIdentity & 0xFFFFFFFFFFFFFFF0ui64 | 1;
else
*(_QWORD *)PfnIdentity = *(_QWORD *)PfnIdentity & 0xFFFFFFFFFFFFFFF0ui64 | 8;
}
else
{
*(_QWORD *)PfnIdentity = *(_QWORD *)PfnIdentity & 0xFFFFFFFFFFFFFE8Fui64 | 0x10;
ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)&v35->ControlAreaLock);
}
}
else
{
Buffer = antNameA.Buffer;
v29 = (unsigned __int64)antNameA.Buffer | 0x8000000000000000ui64;
*((_QWORD *)PfnIdentity + 2) = (unsigned __int64)antNameA.Buffer | 0x8000000000000000ui64;
if( (__int64)Buffer > 0 )
{
*((_QWORD *)PfnIdentity + 2) = v29 | 1;
v30 = *(_QWORD *)(v29 - 16);
if( v30 >= 0x1000000000000i64 )
v30 = 0xFFFFFFFFFFFFi64;
v14 = *(_QWORD *)PfnIdentity ^ (*(_QWORD *)PfnIdentity ^ (v30 << 9)) & 0x1FFFFFFFFFFFE00i64;
}
*(_QWORD *)PfnIdentity = v14 & 0xFFFFFFFFFFFFFFF0ui64 | 2;
}
return;
}
v46 = antNameA.Buffer;
v47 = (UINT64)antNameA.Buffer;
if( antNameA.Buffer && ((v13 >> 60) & 7) != 1 )
v47 = (unsigned __int64)antNameA.Buffer | 0x8000000000000000ui64;
if( MiGetSystemRegionType(v47) == 5 )
{
*(_QWORD *)PfnIdentity = (v14 ^ (v14 ^ ((v47 - 1432) << 9)) & 0x1FFFFFFFFFFFE00i64) & 0xFFFFFFFFFFFFFFF0ui64 | 3;
*((_QWORD *)PfnIdentity + 2) = (__int64)(((_QWORD)MmGetPxeSelfRef() << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16;
return;
}
if( v47 == -8i64 )
{
*(_QWORD *)PfnIdentity = v14 & 0xFFFFFFFFFFFFFFF0ui64 | 5;
*((_QWORD *)PfnIdentity + 2) = MmBadPointer;
return;
}
v70 = (v13 >> 60) & 7;
if( v70 == 1 )
goto LABEL_52;
v48 = 0;
PteBase = (unsigned __int64)MmGetPteBase();
if( v47 )
v50 = (__int64)((v47 << 25) - (PteBase << 25)) >> 16;
else
v50 = 0i64;
SystemRegionType = MiGetSystemRegionType(v50);
if( SystemRegionType == 5 )
{
*((_QWORD *)PfnIdentity + 2) = v50;
*(_QWORD *)PfnIdentity = v14 & 0xFFFFFFFFFFFFFFF0ui64 | 5;
return;
}
*((_QWORD *)PfnIdentity + 2) = v50 & 0xFFFFFFFFFFFFF000ui64;
if( (v73.m128i_i64[1] & 0xFFFFFFFFFi64) == 0xFFFFFFFFDi64 )
{
if( SystemRegionType == 9 )
*(_QWORD *)PfnIdentity = v14 & 0xFFFFFFFFFFFFFFF0ui64 | 6;
else
*(_QWORD *)PfnIdentity = v14 & 0xFFFFFFFFFFFFFFF0ui64 | 0xA;
return;
}
if( v50 <= 0x7FFFFFFEFFFFi64 )
goto LABEL_118;
if( v70 == 2 )
{
*(_QWORD *)PfnIdentity = v14 & 0xFFFFFFFFFFFFFFF0ui64 | 0xB;
return;
}
if( SystemRegionType != 1 )
{
if( SystemRegionType == 6 )
{
*(_QWORD *)PfnIdentity = v14 & 0xFFFFFFFFFFFFFFF0ui64 | 4;
return;
}
if( SystemRegionType <= 0xE )
{
v55 = 20992;
if( _bittest(&v55, SystemRegionType) )
{
*(_QWORD *)PfnIdentity = v14 & 0xFFFFFFFFFFFFFFF0ui64 | 6;
return;
}
}
LABEL_118:
if( (SpinCount[0] & 7) == 6 && ((antNameA.Length & 1) == 0 || v68) )
{
PteLimit = MmGetPteLimit();
if( v50 > 0x7FFFFFFEFFFFi64 )
{
v57 = PteBase + ((*(&stru_140C4DB30 + 937) >> 9) & 0x7FFFFFFFF8i64);
v58 = (unsigned __int64)v46 | 0x8000000000000000ui64;
if( v58 >= PteBase )
{
while( v58 <= (unsigned __int64)PteLimit )
{
if( v58 >= v57 && v58 <= PteBase + ((*(&stru_140C4DB30 + 175) >> 9) & 0x7FFFFFFFF8i64) )
{
TopLevelPfn = MiGetTopLevelPfn(*(_MMPFN **)&SpinCount[4], &PteLimit->u.Long);
v60 = *(_QWORD *)PfnIdentity & 0xFF000000000001FFui64 | ((TopLevelPfn->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 & 0xFFFFFFFFFFE0000i64 | 0x1000000000000000ui64) >> 4);
*(_QWORD *)PfnIdentity = v60;
if( TopLevelPfn != *(_MMPFN **)&SpinCount[4] )
{
_InterlockedAnd64(&TopLevelPfn->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
v60 = *(_QWORD *)PfnIdentity;
}
*(_QWORD *)PfnIdentity = v60 & 0xFFFFFFFFFFFFFFF0ui64 | 0xC;
return;
}
++v48;
v57 &= 0xFFFFFFFFFFFFF000ui64;
v58 = (__int64)((v58 << 25) - (PteBase << 25)) >> 16;
if( v58 < PteBase )
break;
}
}
}
if( v50 < PteBase || v50 > (unsigned __int64)PteLimit )
{
*(_QWORD *)PfnIdentity = *(_QWORD *)PfnIdentity & 0xFFFFFFFFFFFFFFF0ui64 | 5;
return;
}
}
else
{
v61 = *(_MMPFN **)&SpinCount[4];
v62 = *(_MMPFN **)&SpinCount[4];
v63 = 0;
memset(v75, 0, sizeof(v75));
bf_0 = *(_QWORD *)(*(_QWORD *)&SpinCount[4] + 40i64);
if( (bf_0 & 0xFFFFFFFFFi64) != v74 )
{
do
{
v65 = bf_0 & 0xFFFFFFFFFi64;
v62 = &MmGetPfnDb()[bf_0 & 0xFFFFFFFFFi64];
if( (unsigned int)++v63 > 4 )
KeBugCheckEx(0x1Au, (PVOID)0x9696, *(PVOID *)&SpinCount[4], 0i64, 0i64);
LODWORD(v70) = 0;
*((_QWORD *)v75 + (unsigned int)(v63 - 1)) = v62;
while( _interlockedbittestandset64((volatile signed __int32 *)&v62->u2, 0x3Fui64) )
{
do
KeYieldProcessorEx(&v70);
while( v62->u2._bf_0 < 0 );
}
bf_0 = v62->u4._bf_0;
}
while( (bf_0 & 0xFFFFFFFFFi64) != v65 );
v61 = *(_MMPFN **)&SpinCount[4];
}
v66 = v75;
do
{
v67 = *(_MMPFN **)v66;
if( !*(_QWORD *)v66 )
break;
if( v67 != v62 )
_InterlockedAnd64(&v67->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
++v48;
v66 = (__int128 *)((char *)v66 + 8);
}
while( v48 < 4 );
*(_QWORD *)PfnIdentity = *(_QWORD *)PfnIdentity & 0xFF000000000001FFui64 | ((v62->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 & 0xFFFFFFFFFFE0000i64 | 0x1000000000000000ui64) >> 4);
if( v62 != v61 )
_InterlockedAnd64(&v62->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
if( v50 < PteBase || v50 > (unsigned __int64)MmGetPteLimit() )
{
if( v50 < *(&stru_140C4DB30 + 937) || v50 > *(&stru_140C4DB30 + 175) )
*(_QWORD *)PfnIdentity &= 0xFFFFFFFFFFFFFFF0ui64;
else
*(_QWORD *)PfnIdentity = *(_QWORD *)PfnIdentity & 0xFFFFFFFFFFFFFFF0ui64 | 0xC;
return;
}
}
*(_QWORD *)PfnIdentity = *(_QWORD *)PfnIdentity & 0xFFFFFFFFFFFFFFF0ui64 | 3;
return;
}
v52 = *(_MMPFN **)&SpinCount[4];
v53 = MiGetTopLevelPfn(*(_MMPFN **)&SpinCount[4], (UINT64 *)0xFFFFFFFFFi64);
if( (v53->u2._bf_0 & 0x4000000000000000i64) != 0 )
{
*(_QWORD *)PfnIdentity &= 0xFE000000000001FFui64;
v54 = *(_QWORD *)PfnIdentity;
}
else
{
v54 = *(_QWORD *)PfnIdentity & 0xFF000000000001FFui64 | ((v53->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 & 0xFFFFFFFFFFE0000i64 | 0x1000000000000000ui64) >> 4);
*(_QWORD *)PfnIdentity = v54;
}
if( v53 != v52 )
{
_InterlockedAnd64(&v53->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
v54 = *(_QWORD *)PfnIdentity;
}
*(_QWORD *)PfnIdentity = v54 & 0xFFFFFFFFFFFFFFF0ui64 | 7;
return;
case 7i64:
v14 |= 0x100ui64;
*(_QWORD *)PfnIdentity = v14;
LOBYTE(v32) = MI_PFN_IS_PROTO(&antNameA, (_UNICODE_STRING *)0x140000000i64, v12, v2);
if( !v32 )
*((_QWORD *)PfnIdentity + 2) = ((((__int64)antNameA.Buffer << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16) & 0xFFFFFFFFFFFFF000ui64;
if( ((v13 >> 60) & 7) == 1 )
{
LABEL_52:
*(_QWORD *)PfnIdentity = (v14 ^ (v14 ^ (MiGetLeafPfnBuddy(&antNameA) << 9)) & 0x1FFFFFFFFFFFE00i64) & 0xFFFFFFFFFFFFFFF0ui64 | 9;
}
else
{
v33 = v14 & 0xFFFFFFFFFFFFFFF0ui64;
if( (v13 & 0xFFFFFFFFFi64) == 0xFFFFFFFFDi64 )
v33 = v14 & 0xFFFFFFFFFFFFFFF0ui64 | 0xA;
*(_QWORD *)PfnIdentity = v33;
}
return;
}
}Referenced by:
MiConvertPrivateToProto
MiCopyOnWrite
MiDeletePteRun
MiDemoteCombinedPte
MiIdentifyPfnWrapper
MiMakePageAvoidRead
MmSetPfnListInfo
MmTryIdentifyPage