MiEmptyPageAccessLog

VOID __fastcall MiEmptyPageAccessLog(UINT64 *a1){
  UINT64 v1; 
  unsigned __int16 v2; 
  UINT64 *v3; 
  unsigned int v4; 
  __int64 v5; 
  unsigned int v6; 
  unsigned __int64 v7; 
  UINT64 *v8; 
  __int64 *v9; 
  _MMPTE *PteBase; 
  unsigned __int64 v11; 
  __int64 v12; 
  unsigned __int64 v13; 
  unsigned __int16 v14; 
  __int64 v15; 
  unsigned __int64 v16; 
  __int64 **v17; 
  unsigned __int64 v18; 
  __int64 *v19; 
  unsigned __int64 v20; 
  unsigned __int64 v21; 
  unsigned __int64 v22; 
  unsigned __int64 v23; 
  __int64 v24; 
  volatile signed __int64 *v25; 
  signed __int64 v26; 
  signed __int64 v27; 
  signed __int64 v28; 
  unsigned int v29; 
  unsigned __int64 v30; 
  __int64 *v31; 
  signed __int64 v32; 
  signed __int64 v33; 
  __int64 v34; 
  INT64 v35; 
  signed __int64 v36; 
  signed __int64 v37; 
  __int64 SharedProtos; 
  signed __int64 v39; 
  unsigned __int64 v40; 
  UINT64 *v41; 
  UINT64 *i; 
  ULONG_PTR BugCheckParameter4; 
  UINT64 *v44; 
  UINT64 v45; 
  UINT64 *P; 
  unsigned int v47; 
  int v48; 
  int v49; 
  unsigned __int64 v50; 
  P = a1;
  v1 = a1[7];
  v2 = 0;
  v48 = 0;
  v3 = a1;
  v49 = 3;
  v4 = 0;
  v45 = v1;
  if( v1 <= 1 || (*(_DWORD *)(v1 + 2172) & 0x1000) != 0 || (v5 = *(_QWORD *)(v1 + 1368)) == 0 )
    v6 = -1;
  else
    v6 = *(_DWORD *)(v5 + 8);
  v47 = v6;
  v7 = 0i64;
  while( 1 )
  {
    v8 = v3 + 9;
    v9 = (__int64 *)(v3[4] - 8);
    PteBase = MmGetPteBase();
    v44 = (UINT64 *)*v3;
    v11 = 0i64;
    if( v9 >= (__int64 *)v3 + 9 )
    {
      do
      {
        v12 = *v9;
        v13 = (unsigned __int64)*v9 >> 9;
        v14 = *v9 & 0x1FF;
        if( v14 )
        {
          if( v1 > 1 )
          {
            v18 = v12 >> 16;
            if( v14 == v2 )
            {
              v7 += (__int64)(v18 - v11) >> 3 << 12 << *(&v48 + ((v7 >> 10) & 1));
            }
            else
            {
              v19 = *(__int64 **)(v3[6] - 8 * (*v9 & 0x1FF));
              v20 = v19[1];
              v4 ^= ((unsigned __int16)v4 ^ (unsigned __int16)(32 * *(_DWORD *)(*v19 + 56))) & 0x400;
              if( (*(_DWORD *)(*v19 + 56) & 0x20) != 0 )
              {
                if( v18 < v20 || v18 >= v20 + 8i64 * *((unsigned int *)v19 + 11) )
                {
                  if( (*((_BYTE *)v19 + 34) & 2) != 0 )
                  {
                    SharedProtos = (__int64)MiGetSharedProtos(*v19, v6, *(_QWORD *)(v3[6] - 8 * (*v9 & 0x1FF)));
                    v6 = v47;
                    PteBase = MmGetPteBase();
                  }
                  else
                  {
                    SharedProtos = MiGetSubsectionDriverProtos(*(_QWORD **)(v3[6] - 8 * (*v9 & 0x1FF)));
                  }
                  v21 = (v18 << 9) - (*(_QWORD *)(SharedProtos + 72) << 9);
                }
                else
                {
                  v21 = (v18 << 9) - (v20 << 9);
                }
                v22 = ((unsigned __int64)*((unsigned int *)v19 + 9) << 9) + (v21 & 0xFFFFFFFFFFFFF000ui64);
              }
              else
              {
                if( v20 )
                  v34 = (__int64)(v18 - v20) >> 3 << 12;
                else
                  v34 = 0i64;
                v22 = ((*((unsigned int *)v19 + 9) | ((unsigned __int64)((_WORD)v19[4] & 0xFFC0) << 26)) << 12) + v34;
              }
              v2 = v14;
              v23 = v22 << *((_BYTE *)&v48 + 4 * ((v4 >> 10) & 1));
              HIDWORD(v50) = HIDWORD(v23);
              LODWORD(v50) = v14 | v4 & 0x400 | v23 & 0xFFFFFA00;
              v7 = v50;
            }
            v3 = P;
            v11 = v18;
            *v9 = v7;
            *(_DWORD *)v9 ^= ((unsigned __int16)v7 ^ (unsigned __int16)((_WORD)v13 << 9)) & 0x200;
          }
        }
        else
        {
          v15 = ((v12 >> 16 << 25) - ((_QWORD)PteBase << 25)) >> 16;
          *v9 = v15;
          *(_DWORD *)v9 = v15 ^ ((unsigned __int16)v15 ^ (unsigned __int16)((_WORD)v13 << 9)) & 0x200;
        }
        --v9;
      }
      while( v9 >= (__int64 *)v8 );
    }
    if( v1 > 1 )
      break;
LABEL_14:
    MiQueuePageAccessLog((PSLIST_ENTRY)v3);
    P = v44;
    v3 = v44;
    if( !v44 )
      return;
    v6 = v47;
    v2 = 0;
  }
  v16 = v3[6] - 8;
  v17 = (__int64 **)(v3[5] + 8);
  if( (unsigned __int64)v17 > v16 )
    goto LABEL_12;
  do
  {
    v24 = **v17;
    v25 = (volatile signed __int64 *)(v24 + 64);
    _m_prefetchw((const void *)(v24 + 64));
    v26 = *(_QWORD *)(v24 + 64);
    if( (v26 & 0xF) != 0 )
    {
      do
      {
        v27 = _InterlockedCompareExchange64(v25, v26 - 1, v26);
        if( v26 == v27 )
          break;
        v26 = v27;
      }
      while( (v27 & 0xF) != 0 );
    }
    v28 = v26;
    v29 = v26 & 0xF;
    v30 = v28 & 0xFFFFFFFFFFFFFFF0ui64;
    if( v29 > 1 )
      goto LABEL_29;
    if( v29 )
    {
      ObReferenceObjectExWithTag((PVOID)v30, 0xFui64);
      _m_prefetchw((const void *)v25);
      v36 = *v25;
      while( (v36 & 0xF) == 0 )
      {
        if( v30 != (v36 & 0xFFFFFFFFFFFFFFF0ui64) )
          break;
        v37 = v36;
        v36 = _InterlockedCompareExchange64(v25, v36 + 15, v36);
        if( v37 == v36 )
          goto LABEL_29;
      }
      ObpTraceObjectDereferenceIfActive(v30 - 48, (_BYTE *)0xF, 1953261124i64, v35, BugCheckParameter4);
      v39 = _InterlockedExchangeAdd64((volatile signed __int64 *)(v30 - 48), 0xFFFFFFFFFFFFFFF1ui64) - 15;
      if( v39 <= 0 )
      {
        if( *(_QWORD *)(v30 - 40) )
          KeBugCheckEx(
            0x18u,
            ObTypeIndexTable[(unsigned __int8)ObHeaderCookie ^ *(unsigned __int8 *)(v30 - 24) ^ (unsigned __int64)(unsigned __int8)((unsigned __int16)(v30 - 48) >> 8)],
            v30,
            6ui64,
            *(_QWORD *)(v30 - 40));
        if( v39 < 0 )
          KeBugCheckEx(0x18u, 0i64, v30, 5ui64, v39);
        ObpDeferObjectDeletion(v30 - 48);
      }
LABEL_29:
      if( v30 )
        goto LABEL_30;
    }
    v40 = ExAcquireSpinLockShared((PEX_SPIN_LOCK)(v24 + 72));
    v30 = ObFastReferenceObjectLocked((_EX_FAST_REF *)(v24 + 64));
    ExReleaseSpinLockSharedFromDpcLevel((PEX_SPIN_LOCK)(v24 + 72));
    __writecr8(v40);
LABEL_30:
    v31 = *(__int64 **)(v30 + 24);
    _m_prefetchw((const void *)v25);
    v32 = *v25;
    if( (v30 ^ *v25) >= 0xF )
    {
LABEL_38:
      ObDereferenceObjectDeferDelete((PVOID)v30);
    }
    else
    {
      while( 1 )
      {
        v33 = v32;
        v32 = _InterlockedCompareExchange64(v25, v32 + 1, v32);
        if( v33 == v32 )
          break;
        if( (v30 ^ v32) >= 0xF )
          goto LABEL_38;
      }
    }
    *v17++ = v31;
  }
  while( (unsigned __int64)v17 <= v16 );
  v1 = v45;
LABEL_12:
  if( ObReferenceObjectSafeWithTag((PVOID)v1, 0x746C6644ui64) )
  {
    v3 = P;
    goto LABEL_14;
  }
  ExFreePoolWithTag(P, 0);
  v41 = v44;
  for( i = v44; v41; i = v41 )
  {
    v41 = (UINT64 *)*v41;
    ExFreePoolWithTag(i, 0);
  }
}

Referenced by:

MiAllocateAccessLog
MiDrainSystemAccessLog
MiTrimOrAgeWorkingSet
MmDeleteProcessAddressSpace
MmOutSwapProcess