MiReplacePageOfProtoPool

VOID __fastcall MiReplacePageOfProtoPool(
        _MMPTE *ProtoPoolVa,
        UINT64 OldProtoPoolPage,
        UINT64 NewProtoPoolPage,
        _MMPTE *MappingToNewProtoPage){
  unsigned int v6; 
  unsigned int m; 
  int v8; 
  char *v9; 
  unsigned int v10; 
  unsigned int v11; 
  unsigned int v12; 
  unsigned int v13; 
  char *v14; 
  __int64 j; 
  unsigned __int64 v16; 
  unsigned int v17; 
  _MMPFN *PfnDb; 
  __int64 v19; 
  unsigned int v20; 
  signed __int32 *v21; 
  int v22; 
  int v23; 
  unsigned int k; 
  int v25; 
  _MMPTE *v26; 
  _MMPTE *v27; 
  _MMPFN *v28; 
  char v29; 
  bool v30; 
  _MMPFN *v31; 
  _MMPFN *v32; 
  __int64 bf_0; 
  unsigned __int64 v34; 
  int v35; 
  unsigned int v36; 
  __int64 v37; 
  _MMPTE *v38; 
  unsigned int v39; 
  unsigned int v40; 
  unsigned int v41; 
  unsigned int v42; 
  _QWORD *v43; 
  __int64 n; 
  unsigned __int64 v45; 
  unsigned int v46; 
  __int64 v47; 
  UINT64 v48; 
  unsigned __int64 v49; 
  __int64 v50; 
  _MMPFN *v51; 
  signed __int32 *v52; 
  unsigned int SizeOfBitMap; 
  unsigned int v54; 
  unsigned int v55; 
  int v56; 
  UINT64 SpinCount; 
  char *i; 
  _MMPTE *v59; 
  UINT64 v60; 
  UINT64 v61; 
  _RTL_BITMAP v62; 
  UINT64 v63; 
  __int128 v64; 
  __int128 v65; 
  __int128 v66; 
  signed __int32 v67[16]; 

  *(&v62.SizeOfBitMap + 1) = 0;
  v63 = OldProtoPoolPage;
  v61 = NewProtoPoolPage;
  v59 = ProtoPoolVa;
  v62.Buffer = (unsigned int *)v67;
  v62.SizeOfBitMap = 512;
  v64 = 0i64;
  v65 = 0i64;
  v66 = 0i64;
  memset(v67, 0i64, sizeof(v67));
  if( !MiGetPrototypePteRanges((UINT64)ProtoPoolVa, &v62) )
    return;
  v6 = 0;
  KeCopyPage(MappingToNewProtoPage);
  m = 0;
  v8 = (((unsigned __int8)((unsigned __int8)&v67[14] + 1) - 57) & 4) != 0i64 ? 0x20 : 0;
  v56 = v8;
  v9 = (char *)v67 - ((((unsigned __int8)((unsigned __int8)&v67[14] + 1) - 57) & 4) != 0i64 ? 4 : 0);
  for( i = v9; ; v9 = i )
  {
    v10 = m < v62.SizeOfBitMap ? m : 0;
    v11 = v62.SizeOfBitMap - 1;
    while( 1 )
    {
      v12 = v8 + v11;
      v13 = v8 + v10;
      if( v11 - v10 == -1 )
        goto LABEL_44;
      v14 = &v9[8 * ((unsigned __int64)v13 >> 6)];
      for( j = ~*(_QWORD *)v14 | ((1i64 << (v13 & 0x3F)) - 1); j == -1; j = ~*(_QWORD *)v14 )
      {
        v14 += 8;
        if( v14 > &v9[8 * ((unsigned __int64)v12 >> 6)] )
          goto LABEL_44;
      }
      _BitScanForward64(&v16, ~j);
      v17 = v16 + ((unsigned int)((v14 - v9) >> 3) << 6);
      if( v17 > v12 )
      {
LABEL_44:
        v17 = -1;
      }
      else if( v17 != -1 )
      {
        break;
      }
      if( !v10 )
        break;
      SizeOfBitMap = m + 1;
      if( m + 1 > v62.SizeOfBitMap )
        SizeOfBitMap = v62.SizeOfBitMap;
      v11 = SizeOfBitMap - 1;
      v10 = 0;
    }
    PfnDb = MmGetPfnDb();
    v19 = v17 - v8;
    if( v17 == -1 )
      v19 = 0xFFFFFFFFi64;
    if( (unsigned int)v19 < m || (_DWORD)v19 == -1 )
      break;
    if( (unsigned int)v19 < 0x200 )
    {
      v20 = v19;
      v21 = &v67[(unsigned __int64)(unsigned int)v19 >> 5];
      if( v21 != &v67[15] && (*v21 | *((_DWORD *)qword_140011CE0 + (v19 & 0x1F))) == -1 )
      {
        v20 = v19 - (v19 & 0x1F) + 32;
        for( ++v21; v21 < &v67[15] && *v21 == -1; ++v21 )
          v20 += 32;
      }
      while( v20 < 0x200 && _bittest(v67, v20) )
        ++v20;
      v22 = 0;
      if( v21 == &v67[15] )
        goto LABEL_27;
      v23 = v20 & 0x1F;
      if( (*v21 & ~*((_DWORD *)qword_140011CE0 + (v20 & 0x1F))) != 0 )
        goto LABEL_27;
      v22 = 32 - v23;
      if( v23 != 33 )
      {
        v52 = v21 + 1;
        while( v52 < &v67[15] && !*v52 )
        {
          ++v52;
          v22 += 32;
          if( v22 == -1 )
            goto LABEL_32;
        }
LABEL_27:
        for( k = v22 + v20; k < 0x200 && !_bittest(v67, k) && v22 != -1; ++k )
          ++v22;
      }
LABEL_32:
      if( v22 )
        goto LABEL_33;
      goto LABEL_81;
    }
    v22 = 0;
LABEL_81:
    v20 = 512;
LABEL_33:
    v25 = v20 - v19;
    v26 = &v59[v19];
    v27 = &MappingToNewProtoPage[v19];
    for( m = v19 + v22 + v25; v25; --v25 )
    {
      v28 = MiLockLeafPage(v26, v6);
      if( v28 )
      {
        v55 = v6 + 1;
        v29 = *((_BYTE *)&v28->u3 + 2);
        if( (v29 & 8) != 0 )
        {
          v6 = v55;
          goto LABEL_93;
        }
        if( (MI_READ_PTE_LOCK_FREE((INT64)v26) & 1) != 0 )
        {
          v6 = v55;
        }
        else
        {
          v30 = (v29 & 0x20) == 0;
          v6 = v55;
          if( !v30 )
            goto LABEL_93;
        }
      }
      else
      {
        _bittestandreset(v67, v19);
      }
      LODWORD(v19) = v19 + 1;
      v27->u.Long = v26->u.Long;
      ++v26;
      ++v27;
    }
    if( m >= 0x200 )
    {
      PfnDb = MmGetPfnDb();
      break;
    }
    v8 = (((unsigned __int8)((unsigned __int8)&v67[14] + 1) - 57) & 4) != 0i64 ? 0x20 : 0;
  }
  v31 = &PfnDb[v63];
  v32 = &PfnDb[v61];
  if( v6 )
  {
    MiLockNestedPageAtDpcInline(&PfnDb[v63]);
  }
  else
  {
    LODWORD(SpinCount) = 0;
    while( _interlockedbittestandset64((volatile signed __int32 *)&v31->u2, 0x3Fui64) )
    {
      do
        KeYieldProcessorEx(&SpinCount);
      while( v31->u2._bf_0 < 0 );
    }
  }
  if( v31->u3.ReferenceCount == 2
    && (bf_0 = v31->u2._bf_0, (unsigned __int16)bf_0 == (unsigned __int64)(v6 + 1))
    && (v34 = bf_0 & 0x3FFFFFFFFFFFFFFFi64, v34 < 0x10000) )
  {
    MiLockNestedPageAtDpcInline(v32);
    v32->u2._bf_0 = v34 | v32->u2._bf_0 & 0xC000000000000000ui64;
    _InterlockedAnd64(&v32->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
    v35 = 1;
  }
  else
  {
    _InterlockedAnd64(&v31->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
LABEL_93:
    v35 = 0;
  }
  v36 = 0;
  v37 = (__int64)i;
  v38 = v59;
  while( v6 )
  {
    v39 = v36 < v62.SizeOfBitMap ? v36 : 0;
    v40 = v62.SizeOfBitMap - 1;
    while( 1 )
    {
      HIDWORD(SpinCount) = 0;
      v41 = v56 + v40;
      v42 = v56 + v39;
      if( v40 - v39 == -1 )
        goto LABEL_72;
      v43 = (_QWORD *)(v37 + 8 * ((unsigned __int64)v42 >> 6));
      for( n = ~*v43 | ((1i64 << (v42 & 0x3F)) - 1); n == -1; n = ~*v43 )
      {
        if( (unsigned __int64)++v43 > v37 + 8 * ((unsigned __int64)v41 >> 6) )
          goto LABEL_72;
      }
      _BitScanForward64(&v45, ~n);
      v46 = v45 + ((unsigned int)(((__int64)v43 - v37) >> 3) << 6);
      HIDWORD(SpinCount) = v45;
      if( v46 > v41 )
      {
LABEL_72:
        v46 = -1;
      }
      else if( v46 != -1 )
      {
        break;
      }
      if( !v39 )
        break;
      v54 = v36 + 1;
      if( v36 + 1 > v62.SizeOfBitMap )
        v54 = v62.SizeOfBitMap;
      v40 = v54 - 1;
      v39 = 0;
    }
    v47 = v46 - v56;
    if( v46 == -1 )
      v47 = 0xFFFFFFFFi64;
    LODWORD(v48) = MI_READ_PTE_LOCK_FREE((INT64)&v38[v47]);
    v60 = v48;
    v49 = v48;
    if( (v48 & 1) != 0 )
    {
      MiPteInShadowRange((UINT64)&v60);
    }
    else if( *(&stru_140C4DB30 + 42) )
    {
      if( (v48 & 0x10) != 0 )
        v49 = v48 & 0xFFFFFFFFFFFFFFEFui64;
      else
        v49 = ~*(&stru_140C4DB30 + 42) & v48;
    }
    v50 = (v49 >> 12) & 0xFFFFFFFFFi64;
    v51 = MmGetPfnDb();
    if( v35 == 1 )
    {
      *((_QWORD *)&v66 + 1) = v51[v50].u4._bf_0 ^ (v61 ^ v51[v50].u4._bf_0) & 0xFFFFFFFFFi64;
      v51[v50].u4._bf_0 = *((_QWORD *)&v66 + 1);
    }
    --v6;
    _InterlockedAnd64(&v51[v50].u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
    v36 = v47 + 1;
  }
}

Referenced by:

No references.