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