MiIssueHardFault

NTSTATUS __stdcall MiIssueHardFault(
        _MMSUPPORT_INSTANCE *Vm,
        ULONG_PTR VmIrql,
        VOID *ReadBlock,
        _MMINPAGE_SUPPORT *TrapInformation,
        VOID *StoreInstruction,
        UINT64 PreviousMode,
        CHAR a7){
  unsigned __int64 v7; 
  _ETHREAD *v9; 
  __int64 v10; 
  VOID *v11; 
  unsigned int v12; 
  unsigned int v13; 
  _FILE_OBJECT *v14; 
  __int64 v15; 
  UINT64 VmWorkingSetList; 
  _LIST_ENTRY *Blink; 
  _MMWSL_INSTANCE *v18; 
  LONG v19; 
  _MMPFN *PfnDb; 
  __int64 v21; 
  int v22; 
  _LARGE_INTEGER v23; 
  _LARGE_INTEGER v24; 
  _MMSUPPORT_INSTANCE *v25; 
  INT16 *v26; 
  _MMWSL_INSTANCE *v27; 
  unsigned __int64 v28; 
  int v29; 
  _QWORD *v30; 
  unsigned __int64 v31; 
  _QWORD *v32; 
  INT64 v33; 
  INT64 v34; 
  _MMPFN *v36; 
  UINT64 v37; 
  int v38; 
  UINT8 v39; 
  wchar_t *v40; 
  int v41; 
  unsigned __int64 v42; 
  unsigned __int64 v43; 
  int v44; 
  unsigned int v45; 
  _MMSUPPORT_INSTANCE **Long; 
  __int64 v47; 
  unsigned __int64 v48; 
  int v49; 
  INT64 v50; 
  INT64 v51; 
  int v52; 
  _BYTE *v53; 
  int v54; 
  int v55; 
  INT64 v56; 
  __int64 v57; 
  _MI_STORE_INPAGE_COMPLETE_FLAGS *v58; 
  UINT64 v59; 
  PF_HARD_FAULT_INFO **VirtualFaultInfo; 
  _MI_FAULT_VA_LIST *VirtualFaultInfoa; 
  VOID *v62; 
  _LARGE_INTEGER v63; 
  char v64[8]; 
  INT16 v65[4]; 
  _LARGE_INTEGER *v66; 
  _MMPFN SwapPfn; 

  v7 = *(_QWORD *)(*(_QWORD *)&VmIrql + 208i64);
  v9 = *(_ETHREAD **)(*(_QWORD *)&VmIrql + 152i64);
  SwapPfn.u2._bf_0 = (__int64)Vm;
  v10 = *(_QWORD *)&VmIrql;
  v11 = *(VOID **)&Vm->NextPageColor;
  v12 = 0;
  *(_QWORD *)(*(_QWORD *)&VmIrql + 224i64) = v11;
  v64[0] = 0;
  SwapPfn.u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 = 0i64;
  SwapPfn.PteLong = v7;
  MiGetSessionIdForVa(v11, VmIrql);
  v14 = MiReferenceInPageFile((_MMINPAGE_SUPPORT *)v10, v13);
  SwapPfn.OriginalPte.u.Long = (unsigned __int64)&Vm->AgeDistribution[2];
  v15 = MiReleaseFaultState((INT64)&Vm->AgeDistribution[2], 1u, v64);
  VmWorkingSetList = (UINT64)Vm->VmWorkingSetList;
  *(_QWORD *)v65 = v15;
  if( v14 )
  {
    Blink = SwapPfn.ListEntry.Blink;
    *(_QWORD *)(v10 + 200) = v14;
    v12 = (LODWORD(Blink[3].Blink) >> 5) & 1;
  }
  else
  {
    *(_QWORD *)(v10 + 200) = *(_QWORD *)(*(_QWORD *)(v10 + 200) + 56i64);
  }
  v18 = Vm->VmWorkingSetList;
  if( ((unsigned __int8)v18 & 1) == 0 || *(_BYTE *)((unsigned __int64)v18 & 0xFFFFFFFFFFFFFFFEui64) != 1 )
    ++v9->ActiveFaultCount;
  if( (*(_BYTE *)(Vm->AgeDistribution[2] + 184) & 7) != 0 )
    --v9->Tcb.SpecialApcDisable;
  else
    --v9->Tcb.KernelApcDisable;
  __writecr8((unsigned __int8)v64[0]);
  v19 = *(_DWORD *)(v10 + 312);
  PfnDb = MmGetPfnDb();
  if( (*(_DWORD *)(v10 + 192) & 0x20000) != 0 )
  {
    v21 = (*(_DWORD *)(v10 + 312) >> 12) + (unsigned int)((*(_DWORD *)(v10 + 312) & 0xFFF) != 0);
    MiZeroPhysicalPage(
      *(_QWORD *)(v10 + 8 * v21 + 312),
      3ui64,
      (_MI_PFN_CACHE_ATTRIBUTE)(*((unsigned __int8 *)&PfnDb[*(_QWORD *)(v10 + 8 * v21 + 312)].u3 + 2) >> 6));
    v19 = *(_DWORD *)(v10 + 312);
  }
  *(_DWORD *)(v10 + 184) = v19;
  v66 = 0i64;
  if( *(_DWORD *)(v10 + 36) )
  {
    v12 = 2;
LABEL_24:
    v26 = (INT16 *)&Vm->AgeDistribution[2];
    goto LABEL_25;
  }
  v22 = *(_DWORD *)(v10 + 192);
  if( (v22 & 0x200008) == 2097160 && (v22 & 0x100) == 0 )
    goto LABEL_24;
  if( (PfKernelGlobals.Flags & 1) != 0 && (v22 & 0x100) == 0 && (v22 & 8) == 0 )
  {
    v23 = *(_LARGE_INTEGER *)(v10 + 96);
    v24 = *(_LARGE_INTEGER *)(v10 + 224);
    v57 = *(_QWORD *)(v10 + 200);
    v66 = &v63;
    PfHardFaultRecord(&v63, v23, v19, v24, v57, (__int64)v9);
  }
  v25 = (_MMSUPPORT_INSTANCE *)Vm->AgeDistribution[2];
  v26 = (INT16 *)&Vm->AgeDistribution[2];
  if( (v25->Flags._bf_0 & 0x60) == 96 && !MiGetSharedVm(v25)->CommitReleaseContext )
    KiStackAttachProcess(PsInitialSystemProcess, 0i64, (_KAPC_STATE *)(v10 + 104));
  v12 |= 2u;
  MiIssueHardFaultIo((_MMINPAGE_SUPPORT *)v10, v12 & 1, Vm->VmWorkingSetList);
LABEL_25:
  v27 = Vm->VmWorkingSetList;
  if( ((unsigned __int8)v27 & 1) != 0 )
  {
    v28 = (unsigned __int64)v27 & 0xFFFFFFFFFFFFFFFEui64;
    if( *(_BYTE *)v28 == 1 )
    {
      v29 = *(unsigned __int8 *)(*(_QWORD *)v26 + 184i64);
      if( (v29 & 7u) >= 2 )
        *(_DWORD *)(v10 + 192) ^= (*(_DWORD *)(v10 + 192) ^ (2 * v29 - 2)) & 6;
      if( v12 < 2 )
      {
        v32 = *(_QWORD **)(v28 + 64);
        if( *v32 == v28 + 56 )
        {
          *(_QWORD *)v10 = v28 + 56;
          *(_QWORD *)(v10 + 8) = v32;
          *v32 = v10;
          *(_QWORD *)(v28 + 64) = v10;
          *(_QWORD *)(v28 + 72) += *(unsigned int *)(v10 + 184);
          goto LABEL_35;
        }
      }
      else
      {
        v30 = *(_QWORD **)(v28 + 48);
        v31 = v28 + 40;
        if( *v30 == v31 )
        {
          *(_QWORD *)v10 = v31;
          *(_QWORD *)(v10 + 8) = v30;
          *v30 = v10;
          *(_QWORD *)(v31 + 8) = v10;
LABEL_35:
          KeGetCurrentIrql();
          __writecr8(1ui64);
          if( (*(_BYTE *)(*(_QWORD *)v26 + 184i64) & 7) != 0 )
            KiLeaveGuardedRegionUnsafe((__int64)v9);
          else
            KeLeaveCriticalRegionThread(&v9->Tcb);
          MiRelockFaultState(v26, v65[0], v33, v34, v56);
          return 0;
        }
      }
      __fastfail(3u);
    }
  }
  v36 = *(_MMPFN **)(v10 + 248);
  v37 = *(_QWORD *)(v10 + 232);
  if( (v36->u4._bf_0 & 0x1000000000i64) == 0 && (__int64)v36->ListEntry.Blink > 0 )
    v36 = 0i64;
  MiWaitForInPageComplete(
    (_MMINPAGE_SUPPORT *)Vm,
    (PVOID)v10,
    (_MMSUPPORT_INSTANCE *)&v66,
    PfnDb,
    v56,
    VirtualFaultInfo);
  v38 = MiFinishHardFault((_MMINPAGE_SUPPORT *)Vm, *(_MMPTE **)v65, (_MMSUPPORT_INSTANCE *)v10, &SwapPfn, v58);
  v41 = (int)v66;
  --v9->ActiveFaultCount;
  *(_DWORD *)v65 = v41;
  if( v38 )
    return v38;
  if( !v36 )
  {
    LODWORD(v42) = MI_READ_PTE_LOCK_FREE((INT64)&SwapPfn);
    v36 = &MmGetPfnDb()[(v42 >> 12) & 0xFFFFFFFFFi64];
  }
  v43 = Vm->TrimmedPageCount & 2;
  SwapPfn.PteLong = v43;
  LOBYTE(v44) = MI_PFN_IS_PROTO((_UNICODE_STRING *)v36, (_UNICODE_STRING *)v43, v39, v40);
  if( v44 )
  {
    v37 = (UINT64)MmGetPteBase() + ((*(_QWORD *)&Vm->NextPageColor >> 9) & 0x7FFFFFFFF8i64);
    v38 = MiCompleteProtoPteFault(
            Vm,
            SwapPfn.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::gap0[0],
            (VOID *)v45,
            0i64,
            VmWorkingSetList,
            (UINT64)VirtualFaultInfoa,
            v62);
    if( v38 >= 0 )
    {
      Long = (_MMSUPPORT_INSTANCE **)SwapPfn.OriginalPte.u.Long;
LABEL_48:
      if( *(&stru_140C4DB30 + 654)
        && *(_DWORD *)v65 != 2
        && (unsigned int)MiGetEffectivePagePriorityThread(v9) >= *(&stru_140C4DB30 + 655) )
      {
        MiLogPageAccess(*Long, (_MMPTE *)(v37 | 1));
      }
      if( !v38 )
        return 276;
    }
    return v38;
  }
  *(_QWORD *)&SwapPfn.u3.ReferenceCount = VmWorkingSetList & 1;
  if( (VmWorkingSetList & 1) != 0 && *(_BYTE *)(VmWorkingSetList & 0xFFFFFFFFFFFFFFFEui64) == 4 )
  {
    LODWORD(v47) = MI_READ_PTE_LOCK_FREE(v37);
    v48 = v47 & 0xFFFFFFFFFFFFFC1Fui64 | 0x80;
    LOBYTE(v49) = MiPteInShadowRange(v37);
    if( v49 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v48 & 1) != 0 )
      v48 |= 0x8000000000000000ui64;
    *(_QWORD *)v37 = v48;
  }
  LODWORD(v50) = MiMakeTransitionPteValid((_XSTATE_CONFIGURATION *)v37);
  v51 = v50;
  if( (unsigned int)MI_IS_SOFTWARE_PTE_SHADOW_STACK((union {unsigned __int64 Long;volatile unsigned __int64 VolatileLong;_MMPTE_HARDWARE Hard;_MMPTE_PROTOTYPE Proto;_MMPTE_SOFTWARE Soft;_MMPTE_TIMESTAMP TimeStamp;_MMPTE_TRANSITION Trans;_MMPTE_SUBSECTION Subsect;_MMPTE_LIST List;} *)&v36->OriginalPte.u.Long) )
    v51 |= 0x40ui64;
  if( SwapPfn.PteLong )
  {
    LOBYTE(v52) = MiOkToSetPteDirtyForNotValidFault(v51, *(_QWORD *)SwapPfn.u2._bf_0);
    if( v52 )
    {
      if( (v51 & 0x800) != 0 )
      {
        v51 |= 0x42ui64;
        if( (*(_BYTE *)(&v36->u3 + 1) & 0x10) == 0 )
        {
          if( MiGetPagingFileOffset(&v36->OriginalPte) )
            MiLockPageAndSetDirty(v36, (VOID *)1);
        }
      }
    }
  }
  v53 = (_BYTE *)(VmWorkingSetList & 0xFFFFFFFFFFFFFFFEui64);
  if( !*(_QWORD *)&SwapPfn.u3.ReferenceCount )
    goto LABEL_79;
  if( *v53 != 4 )
  {
    if( *v53 == 5 )
    {
      v55 = 0;
      goto LABEL_80;
    }
LABEL_79:
    v55 = 0;
LABEL_80:
    if( *(_QWORD *)&SwapPfn.u3.ReferenceCount && *v53 == 3 )
      v55 = 1;
    LODWORD(VirtualFaultInfoa) = v55;
    v59 = v51;
    Long = (_MMSUPPORT_INSTANCE **)SwapPfn.OriginalPte.u.Long;
    if( MiAllocateWsle(
           *(_MMSUPPORT_INSTANCE **)SwapPfn.OriginalPte.u.Long,
           (_MMPTE *)v37,
           v36,
           0i64,
           (_MMPTE)v59,
           VirtualFaultInfoa) )
    {
      goto LABEL_48;
    }
    MiLockAndDecrementShareCount(v36, 0i64);
    return -1073741801;
  }
  LOBYTE(v54) = MiPteInShadowRange(v37);
  if( v54 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v51 & 1) != 0 )
    v51 |= 0x8000000000000000ui64;
  *(_QWORD *)v37 = v51;
  return 276;
}

Referenced by:

MiInPagePageTable
MmAccessFault