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