MiUserFault

NTSTATUS __stdcall MiUserFault(UINT64 *FaultStatus){
  UINT64 v1; 
  __int64 v3; 
  unsigned int v4; 
  __int64 v5; 
  __int64 v6; 
  __int64 v7; 
  unsigned __int64 v8; 
  _QWORD *v9; 
  unsigned __int64 v10; 
  bool v11; 
  bool v12; 
  INT64 v13; 
  LONG *v14; 
  unsigned __int8 v15; 
  UINT8 CurrentIrql; 
  LONG *v17; 
  int v18; 
  __int64 v19; 
  _MMVAD_SHORT *Address; 
  int v21; 
  int valid; 
  __int64 v23; 
  INT64 v24; 
  INT64 v25; 
  _MMPTE *PteBase; 
  _MMPTE *PteLimit; 
  UINT64 v28; 
  int v29; 
  MMPTE *PxeUserLimit; 
  _MMPTE *Pml4eBase; 
  UINT64 v32; 
  _MMPTE *PxeSelfRef; 
  PVOID *v34; 
  MMPTE *v35; 
  unsigned __int64 v36; 
  bool v37; 
  INT64 v38; 
  __int64 v39; 
  int v40; 
  UINT64 v41; 
  UINT64 v42; 
  ULONG_PTR v43; 
  UINT64 v44; 
  INT64 v45; 
  unsigned __int64 v46; 
  unsigned __int64 v47; 
  UINT64 v48; 
  NTSTATUS v49; 
  BYTE v50; 
  NTSTATUS v51; 
  UINT64 v52; 
  INT64 v53; 
  UINT8 v54; 
  int v56; 
  UINT64 v57; 
  _MMPTE *v58; 
  unsigned __int64 v59; 
  void *v60; 
  RTL_BALANCED_NODE *v61; 
  unsigned __int64 v62; 
  __int64 v63; 
  unsigned __int64 v64; 
  unsigned __int64 v65; 
  unsigned __int64 v66; 
  unsigned __int64 v67; 
  __int64 v68; 
  __int64 v69; 
  _MMVAD *v70; 
  unsigned __int64 v71; 
  __int64 v72; 
  char v73; 
  _MMPFN *v74; 
  __int64 v75; 
  INT64 v76; 
  UINT64 v77; 
  INT64 v78; 
  UINT8 v79; 
  UINT8 BugCheckParameter4; 
  INT8 v81; 
  __int64 v82; 
  BYTE VirtualAddress; 
  int TrapInformation; 
  UINT64 ProtectCode; 
  MMPTE *WsIrql; 
  v1 = 0i64;
  TrapInformation = 0;
  WsIrql = 0i64;
  v3 = *((_QWORD *)KeGetCurrentThread() + 23);
  v4 = 3;
  v82 = v3;
  v5 = v3 + 1664;
  FaultStatus[7] = v3 + 1664;
  if( *(_DWORD *)(v3 + 2000) > 0x10u && (*(_DWORD *)(v3 + 2172) & 0x1000) == 0 )
  {
    v6 = *(_QWORD *)(qword_140C4E388 + 8i64 * *(unsigned __int16 *)(v3 + 1838));
    if( !*(_DWORD *)(v6 + 1160) || *(_QWORD *)(v6 + 1280) != v3 )
    {
      v7 = *(_QWORD *)(qword_140C4E388 + 8i64 * *(unsigned __int16 *)(v3 + 1838));
      v8 = *(_QWORD *)(v6 + 7488);
      if( (unsigned __int16)KeNumberNodes <= 1u
        || (v9 = (_QWORD *)(*(_QWORD *)(v7 + 16)
                          + 4544i64 * *(unsigned __int16 *)(*((_QWORD *)KeGetCurrentPrcb() + 24) + 146i64)),
            v10 = 16i64 * (v9[268] + v9[269]) + ((v9[134] + v9[135]) << 9) + ((*v9 + v9[1]) << 18) + v9[516] + v9[517],
            v10 < 0x420)
        && v8 >= v10 >> 4
        || !v10 )
      {
        v10 = *(_QWORD *)(v7 + 7104);
      }
      if( v10 < 0x420 && (v8 >= 0x4000 || v8 >= v10 >> 4) )
      {
        v12 = __OFSUB__(*(_BYTE *)(v3 + 640), 9);
        v11 = (char)(*(_BYTE *)(v3 + 640) - 9) < 0;
        *(_DWORD *)(v3 + 2000) = 0;
        v13 = (unsigned int)(v11 == v12) + 1;
LABEL_16:
        MiDelayFaultingThread(v13);
        goto LABEL_17;
      }
    }
  }
  if( dword_140C4EA8C )
  {
    v13 = 3i64;
    goto LABEL_16;
  }
LABEL_17:
  v14 = &dword_140C4F4C0;
  v15 = *(_BYTE *)(v5 + 184) & 7;
  if( v15 < 6u )
  {
    if( v15 == 2 )
      v17 = &dword_140C4F4C0;
    else
      v17 = (LONG *)(v5 + 192);
    CurrentIrql = KeGetCurrentIrql();
    __writecr8(2ui64);
    _m_prefetchw(v17);
    v18 = *v17 & 0x7FFFFFFF;
    if( v18 != _InterlockedCompareExchange(v17, v18 + 1, v18) )
      ExpWaitForSpinLockSharedAndAcquire((INT64 *)v17, CurrentIrql);
    if( v17[1] )
      _InterlockedExchange(v17 + 1, 0);
  }
  else
  {
    CurrentIrql = KeGetCurrentIrql();
    __writecr8(2ui64);
  }
  *((_BYTE *)FaultStatus + 68) = CurrentIrql;
  v19 = *((_QWORD *)KeGetCurrentThread() + 23);
  if( (*(_BYTE *)(v19 + 1848) & 7) != 2 )
    v14 = (LONG *)(v19 + 1856);
  if( (*(_BYTE *)(v19 + 1851) & 0x60) == 96 )
  {
    if( *((_QWORD *)v14 + 4) )
    {
      if( (unsigned __int64)FaultStatus < 0xFFFF800000000000ui64 )
      {
        Address = (_MMVAD_SHORT *)MiLocateAddress((UINT64)FaultStatus);
        if( !Address )
          goto LABEL_33;
        MiIsVadEligibleForCommitRelease(Address);
        if( v21 )
          goto LABEL_33;
      }
    }
  }
  if( *FaultStatus - 0x7FFFFFFF0000i64 <= 0xFFFF00000000FFFFui64 )
  {
    valid = -1073741819;
    goto LABEL_164;
  }
  v23 = *((_QWORD *)KeGetCurrentThread() + 23);
  if( *(_QWORD *)(v23 + 1240)
    && (unsigned int)MiWaitForRotateToComplete((PVOID)*FaultStatus, (unsigned __int8)FaultStatus + 56) == 1 )
  {
    goto LABEL_163;
  }
  v24 = *(_QWORD *)(v23 + 2552);
  if( v24 )
  {
    if( (unsigned int)MiCheckHoldFaultForHotPatch(v24, (INT64 *)FaultStatus) == 1 )
      goto LABEL_163;
  }
  v25 = FaultStatus[7];
  PteBase = MmGetPteBase();
  PteLimit = MmGetPteLimit();
  if( (*((_BYTE *)FaultStatus + 69) & 1) == 0 )
  {
    v28 = *FaultStatus;
    if( *FaultStatus < (unsigned __int64)PteBase || v28 > (unsigned __int64)PteLimit )
    {
      v29 = MiFastLockLeafPageTable(FaultStatus[7], v28);
      if( v29 )
      {
        v32 = FaultStatus[v29 + 3];
        FaultStatus[9] = v32;
        if( v29 == 1 )
          goto LABEL_82;
        MiUnlockPageTableInternal(v25, v32);
        FaultStatus[9] = 0i64;
      }
    }
  }
  valid = 0;
  if( (*((_BYTE *)FaultStatus + 69) & 1) == 0 )
  {
    PxeSelfRef = MmGetPxeSelfRef();
    FaultStatus[9] = (UINT64)PxeSelfRef;
    MiLockPageTableInternal(v25, (UINT64)PxeSelfRef, 0i64);
  }
  v34 = (PVOID *)(FaultStatus + 6);
  do
  {
    v35 = (MMPTE *)*v34;
    Pml4eBase = MmGetPml4eBase();
    v36 = *(_QWORD *)*v34;
    PxeUserLimit = MmGetPxeUserLimit();
    if( *v34 >= Pml4eBase && v35 <= PxeUserLimit )
    {
      PxeUserLimit = MmGetPxeUserLimit();
      Pml4eBase = MmGetPml4eBase();
    }
    if( (v36 & 1) != 0 )
    {
      if( (v36 & 0x80u) != 0i64 )
      {
        v42 = FaultStatus[2];
        if( (v42 & 1) == 0 || *(_BYTE *)(v42 & 0xFFFFFFFFFFFFFFFEui64) != 1 )
        {
          v43 = *FaultStatus;
          if( *FaultStatus >= (unsigned __int64)MmGetPteBase() && v43 <= (unsigned __int64)MmGetPteLimit() )
            KeBugCheckEx(0x50u, v43, FaultStatus[1], v42, 8ui64);
        }
        valid = MiLargePageFault((UINT64)FaultStatus, *v34, PxeUserLimit, v42);
        if( valid >= 0 )
          valid = -1073740748;
        goto LABEL_75;
      }
      v41 = FaultStatus[9];
      if( v41 && v35 != (MMPTE *)v41 )
      {
        MiLockPageTableInternal(v25, (UINT64)*v34, 0i64);
        MiUnlockPageTableInternal(v25, FaultStatus[9]);
        FaultStatus[9] = (UINT64)v35;
      }
    }
    else
    {
      if( v36 && (v36 & 0x400) == 0 )
      {
        if( (v36 & 0x800) != 0 )
        {
          v37 = ((v36 >> 5) & 0x1F) == 24;
        }
        else
        {
          v38 = MiSwizzleInvalidPte(512i64);
          v37 = v39 == v38;
        }
        if( v37 )
        {
          MiUnlockFaultPageTable((INT64)(FaultStatus + 7));
          valid = -1073741819;
          goto LABEL_164;
        }
      }
      MiInPagePageTable((INT64)FaultStatus, v4);
      valid = v40;
      if( v40 < 0 )
        goto LABEL_75;
      ++v4;
      ++v34;
    }
    --v34;
    --v4;
  }
  while( v4 );
  if( valid >= 0 )
    goto LABEL_79;
LABEL_75:
  v44 = FaultStatus[9];
  v45 = FaultStatus[7];
  if( v44 )
  {
    if( *((_WORD *)FaultStatus + 33) )
    {
      MiEmptyDeferredWorkingSetEntries((INT64)(FaultStatus + 7));
      v44 = FaultStatus[9];
    }
    MiUnlockPageTableInternal(v45, v44);
    *((_BYTE *)FaultStatus + 69) |= 2u;
    FaultStatus[9] = 0i64;
  }
LABEL_79:
  if( valid == -1073740748 )
  {
LABEL_163:
    valid = 0;
    goto LABEL_164;
  }
  if( valid < 0 )
    goto LABEL_164;
  PteLimit = MmGetPteLimit();
LABEL_82:
  v46 = FaultStatus[3];
  v47 = *(_QWORD *)v46;
  if( (*(_QWORD *)v46 & 1) != 0 )
  {
    valid = MiValidFault((UINT64)FaultStatus, (PVOID)v47, PxeUserLimit, Pml4eBase, BugCheckParameter4, v81);
    goto LABEL_164;
  }
  v48 = FaultStatus[1];
  if( (v48 & 2) != 0 && (*(_DWORD *)(v82 + 1124) & 0x10) != 0 && *FaultStatus < 0xFFFF800000000000ui64 )
    FaultStatus[1] = v48 & 0xFFFFFFFFFFFFFFFDui64;
  if( v47 )
  {
    TrapInformation = (v47 >> 5) & 0x1F;
    if( (v47 & 0x400) == 0 )
      goto LABEL_100;
    v62 = *(_QWORD *)v46;
    LODWORD(ProtectCode) = 0;
    v63 = (v62 >> 5) & 0x1F;
    if( (v62 & 0x400) == 0 )
      goto LABEL_140;
    v64 = v62;
    if( qword_140C4DC80 && (v62 & 0x10) == 0 )
      v64 = v62 & ~qword_140C4DC80;
    if( HIDWORD(v64) == 0xFFFFFFFF )
    {
      v65 = (unsigned __int64)MmGetPteBase();
      v66 = (__int64)((v46 << 25) - (v65 << 25)) >> 16;
      if( v66 <= 0x7FFFFFFEFFFFi64 )
      {
        if( (*(_DWORD *)(*((_QWORD *)KeGetCurrentThread() + 23) + 2172i64) & 1) == 0 )
        {
          v67 = v66 & 0xFFFFFFFFFFFFF000ui64;
          if( (v66 & 0xFFFFFFFFFFFFF000ui64) == 2147352576 )
          {
            v68 = ProtoPte;
            LODWORD(ProtectCode) = 1;
            goto LABEL_145;
          }
          if( v67 == qword_140C4DB88 && v67 )
          {
            v68 = qword_140C4DB80;
            LODWORD(ProtectCode) = 1;
            goto LABEL_145;
          }
        }
        v69 = *((_QWORD *)KeGetCurrentThread() + 23);
        v70 = *(_MMVAD **)(v69 + 2016);
        if( v70 )
        {
          v71 = v66 >> 12;
          if( v66 >> 12 < (*((unsigned int *)v70 + 6) | ((unsigned __int64)*((unsigned __int8 *)v70 + 32) << 32))
            || v71 > (*((unsigned int *)v70 + 7) | ((unsigned __int64)*((unsigned __int8 *)v70 + 33) << 32)) )
          {
            v70 = *(_MMVAD **)(v69 + 2008);
            if( v70 )
            {
              while( 1 )
              {
                if( v71 > (*((unsigned int *)v70 + 7) | ((unsigned __int64)*((unsigned __int8 *)v70 + 33) << 32)) )
                {
                  v70 = (_MMVAD *)*((_QWORD *)v70 + 1);
                }
                else
                {
                  if( v71 >= (*((unsigned int *)v70 + 6) | ((unsigned __int64)*((unsigned __int8 *)v70 + 32) << 32)) )
                  {
                    *(_QWORD *)(v69 + 2016) = v70;
                    goto LABEL_136;
                  }
                  v70 = *(_MMVAD **)v70;
                }
                if( !v70 )
                {
                  valid = -1073741819;
                  goto LABEL_164;
                }
              }
            }
            goto LABEL_33;
          }
LABEL_136:
          v68 = (__int64)MiCheckUserVirtualAddress((VOID *)v66, &ProtectCode, v70, v66);
          goto LABEL_145;
        }
LABEL_33:
        valid = -1073741819;
LABEL_164:
        v77 = FaultStatus[9];
        v78 = FaultStatus[7];
        if( v77 )
        {
          if( *((_WORD *)FaultStatus + 33) )
          {
            MiEmptyDeferredWorkingSetEntries((INT64)(FaultStatus + 7));
            v77 = FaultStatus[9];
          }
          MiUnlockPageTableInternal(v78, v77);
          *((_BYTE *)FaultStatus + 69) |= 2u;
          FaultStatus[9] = 0i64;
        }
        v79 = *((_BYTE *)FaultStatus + 68);
        if( (*((_BYTE *)FaultStatus + 69) & 1) != 0 )
          MiUnlockWorkingSetExclusive(v78, v79);
        else
          MiUnlockWorkingSetShared(v78, v79);
        return valid;
      }
      if( v66 >= v65 && v66 <= (unsigned __int64)PteLimit )
        goto LABEL_33;
      LODWORD(ProtectCode) = 24;
      v68 = 0i64;
    }
    else
    {
LABEL_140:
      v72 = v62;
      if( qword_140C4DC80 && (v62 & 0x10) == 0 )
        v72 = v62 & ~qword_140C4DC80;
      v68 = v72 >> 16;
      LODWORD(v63) = 256;
      if( (v62 & 8) != 0 )
        LODWORD(v63) = 1;
    }
LABEL_145:
    TrapInformation = v63;
    WsIrql = (MMPTE *)v68;
    if( !v68 )
    {
      valid = -1073741819;
      goto LABEL_164;
    }
LABEL_100:
    if( TrapInformation == 256 )
      goto LABEL_162;
    v56 = FaultStatus[1] & 2;
    v57 = FaultStatus[2];
    if( (FaultStatus[10] & 0x40) != 0 )
    {
      v58 = MmGetPteBase();
      if( v46 > (unsigned __int64)v58 + 0x3FFFFFFF78i64 || v46 < (unsigned __int64)v58 )
        goto LABEL_107;
    }
    v59 = *(_QWORD *)v46;
    if( (*(_QWORD *)v46 & 1) != 0 )
    {
      if( (FaultStatus[1] & 2) != 0 && (v59 & 0xA00) == 0 )
        goto LABEL_107;
LABEL_162:
      FaultStatus[12] = (UINT64)WsIrql;
      return -1073741802;
    }
    v73 = TrapInformation;
    if( (FaultStatus[1] & 2) != 0 )
      v56 = 1;
    if( *((char *)&MiReadWrite + (TrapInformation & 7)) - v56 < 10 )
      goto LABEL_107;
    if( (TrapInformation & 0xFFFFFFF8) != 16 || (v57 & 1) != 0 && *(_BYTE *)(v57 & 0xFFFFFFFFFFFFFFFEui64) == 1 )
      goto LABEL_162;
    if( !(unsigned int)MiAllowGuardFault((PVOID)v57) )
    {
LABEL_107:
      v60 = (void *)*FaultStatus;
      if( *FaultStatus < 0xFFFF800000000000ui64 )
      {
        v61 = MiLocateAddress((UINT64)v60);
        v60 = (void *)*FaultStatus;
        v1 = (UINT64)v61;
      }
      MiCheckFatalAccessViolation(v60);
      FaultStatus[11] = v1;
      valid = -1073741819;
      goto LABEL_110;
    }
    if( (v59 & 0x800) == 0 || (v59 & 0x400) != 0 )
    {
      *(_QWORD *)v46 = v59 & 0xFFFFFFFFFFFFFC1Fui64 | (32i64 * (v73 & 0xF));
    }
    else
    {
      v74 = MiLockTransitionLeafPage((_MMPTE *)v46, 0i64);
      v75 = v73 & 0xF;
      v76 = MI_READ_PTE_LOCK_FREE(v46);
      if( v74 )
        *((_QWORD *)v74 + 2) = (32i64 * (unsigned int)v75) | *((_QWORD *)v74 + 2) & 0xFFFFFFFFFFFFFC1Fui64;
      *(_QWORD *)v46 = (32 * v75) | v76 & 0xFFFFFFFFFFFFFC1Fui64;
      if( v74 )
      {
        _InterlockedAnd64((volatile signed __int64 *)v74 + 3, 0x7FFFFFFFFFFFFFFFui64);
        valid = -2147483647;
        goto LABEL_110;
      }
    }
    valid = -2147483647;
LABEL_110:
    MiReleaseFaultState((INT64)(FaultStatus + 7), 0x11u, 0i64);
    if( valid == -2147483647 )
      return MiCheckForUserStackOverflow((PVOID)*FaultStatus);
    return valid;
  }
  VirtualAddress = 0;
  v49 = MiZeroFault((INT64)FaultStatus, &VirtualAddress, &TrapInformation, &WsIrql);
  v50 = VirtualAddress;
  v51 = v49;
  if( !VirtualAddress )
    goto LABEL_100;
  v52 = FaultStatus[9];
  v53 = FaultStatus[7];
  if( v52 )
  {
    if( *((_WORD *)FaultStatus + 33) )
    {
      MiEmptyDeferredWorkingSetEntries((INT64)(FaultStatus + 7));
      v52 = FaultStatus[9];
    }
    MiUnlockPageTableInternal(v53, v52);
    *((_BYTE *)FaultStatus + 69) |= 2u;
    FaultStatus[9] = 0i64;
  }
  v54 = *((_BYTE *)FaultStatus + 68);
  if( (*((_BYTE *)FaultStatus + 69) & 1) != 0 )
    MiUnlockWorkingSetExclusive(v53, v54);
  else
    MiUnlockWorkingSetShared(v53, v54);
  if( v50 == 2 )
    return MiCheckForUserStackOverflow((PVOID)*FaultStatus);
  return v51;
}

Referenced by:

MmAccessFault