MiValidFault
NTSTATUS __stdcall MiValidFault(
UINT64 FaultStatus,
PVOID VirtualAddress,
_MMPTE *PteContents,
PVOID TrapInformation,
UINT8 WsIrql,
INT8 PreviousMode){
_MMVAD *v6;
void *v7;
INT64 v8;
_MMVAD *PteBase;
INT64 *v11;
INT64 v12;
_EPROCESS *Process;
char v14;
INT64 v16;
_BYTE *v17;
int v18;
_MMPTE v19;
NTSTATUS v20;
UINT8 v21;
INT64 v22;
_MMPTE *v23;
_ETHREAD *CurrentThread;
unsigned __int64 v25;
__int64 v26;
INT64 v27;
__int64 v28;
UINT8 v29;
_MMPFN *v30;
_UNICODE_STRING *Long;
wchar_t *v32;
int v33;
_MMPFN *v34;
_DWORD *v35;
_KTBFLUSH_TYPE v36;
int v37;
int v38;
__int64 v39;
int v40;
signed __int64 v41;
_MMSUPPORT_INSTANCE *v42;
PVOID BugCheckParameter4;
INT64 v44;
INT64 *a2;
_EPROCESS *v46;
v44 = (INT64)VirtualAddress;
v6 = *(_MMVAD **)FaultStatus;
v7 = *(void **)(FaultStatus + 8);
v8 = *(_QWORD *)(FaultStatus + 16);
PteBase = (_MMVAD *)MmGetPteBase();
v11 = (INT64 *)((char *)PteBase + ((*(_QWORD *)FaultStatus >> 9) & 0x7FFFFFFFF8i64));
v12 = v8 & 1;
a2 = v11;
Process = KeGetCurrentThread()->ApcState.Process;
v46 = Process;
if( (v8 & 1) != 0 )
{
v14 = *(_BYTE *)(v8 & 0xFFFFFFFFFFFFFFFEui64);
if( v14 == 1 )
{
MiUpdatePrefetchPriority((_MI_FAULT_VA_LIST *)(v8 & 0xFFFFFFFFFFFFFFFEui64), v6, 0i64, PteBase);
return 0;
}
if( v14 == 3 )
return 0;
v12 = v8 & 1;
}
v16 = v44;
if( v6 >= PteBase && v6 <= (_MMVAD *)MmGetPteLimit() && (v44 & 0x80u) != 0i64 )
{
v17 = (_BYTE *)(v8 & 0xFFFFFFFFFFFFFFFEui64);
if( v12 )
{
if( *v17 != 1 && *v17 != 3 && *v17 != 6 )
LABEL_97:
KeBugCheckEx(0x50u, v6, v7, (PVOID)v8, (PVOID)8);
}
else if( KeInvalidAccessAllowed((VOID *)v8) != 1 )
{
goto LABEL_97;
}
return -1073741819;
}
v18 = 0;
if( (v44 & 4) == 0 && (unsigned __int64)v6 <= 0x7FFFFFFEFFFFi64 )
return -1073741819;
v19.u.Long = 0xFFFF800000000000ui64;
if( (*(_DWORD *)(FaultStatus + 80) & 0x40) == 0
&& v8
&& (unsigned __int64)v6 < 0xFFFF800000000000ui64
&& !v12
&& !KeIsUserVaAccessAllowed(v8) )
{
if( KeInvalidAccessAllowed((VOID *)v8) != 1 )
KeBugCheckEx(0x50u, v6, v7, (PVOID)v8, (PVOID)0xF);
Process = v46;
v19.u.Long = 0xFFFF800000000000ui64;
v11 = a2;
}
if( ((unsigned __int8)v7 & 2) == 0 )
{
if( ((unsigned __int8)v7 & 0x10) != 0 )
{
if( v16 < 0 )
{
if( MiCanGrantExecute(Process, v6) == 1 )
{
LODWORD(v25) = MI_READ_PTE_LOCK_FREE((INT64)&v44);
if( (MmGetPfnDb()[(v25 >> 12) & 0xFFFFFFFFFi64].u4._bf_0 & 0x4000000000000i64) != 0 )
{
v26 = v16 & 0x7FFFFFFFFFFFFFFFi64;
if( (MiFlags & 0x100) != 0 || (MiFlags & 0x200) != 0 )
v26 |= 0x20ui64;
v27 = v26;
v21 = (unsigned __int8)a2;
MiWriteValidPteNewProtection(a2, v27);
if( (MiFlags & 0x100) == 0 && (MiFlags & 0x200) == 0 )
KeFlushSingleTb((UINT64)v6, FlushUser, 0i64);
goto LABEL_31;
}
}
return -1073741819;
}
if( (*(_DWORD *)(FaultStatus + 80) & 0x40) == 0 )
MiCheckSystemNxFault(FaultStatus, (VOID *)v16, (VOID *)5, v19, (UINT64)BugCheckParameter4);
}
goto LABEL_60;
}
if( (v16 & 0x200) == 0 )
{
if( (v16 & 0x800) == 0 )
return -1073741819;
if( v16 < 0 || (v16 & 0x42) != 0 || (Process->Flags & 0x10) == 0 || (unsigned __int64)v6 >= v19.u.Long )
goto LABEL_60;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
if( (*(_DWORD *)(FaultStatus + 80) & 0x40) != 0 )
{
if( (CurrentThread->_bf_1 & 0x10) == 0 )
return -1073739997;
}
else if( (CurrentThread->_bf_1 & 0x20) == 0 )
{
v16 = v44;
v18 = MiKernelWriteToExecutableMemory(FaultStatus, v44, Process);
if( v18 < 0 )
return v18;
goto LABEL_60;
}
v16 = v44;
LABEL_60:
if( ((unsigned __int8)v7 & 2) != 0 )
{
v28 = ((unsigned __int64)v16 >> 12) & 0xFFFFFFFFFi64;
v29 = 6 * ((unsigned __int64)v16 >> 12);
if( (MmGetPfnDb()[v28].u4._bf_0 & 0x4000000000000i64) != 0 )
{
v30 = &MmGetPfnDb()[v28];
Long = (_UNICODE_STRING *)v30->OriginalPte.u.Long;
v32 = (wchar_t *)(&v30->3 + 1);
if( ((unsigned __int8)Long & 1) == 0
&& (!Long || !*(&stru_140C4DB30 + 42) || ((unsigned __int64)Long & *(&stru_140C4DB30 + 42)) != 0)
&& ((unsigned __int16)Long & 0x400) == 0 )
{
LOBYTE(Long) = (unsigned __int8)Long >> 2;
if( ((unsigned __int8)Long & 1) != 0 )
{
MiLockPageAndSetDirty(v30, (VOID *)1);
v32 = (wchar_t *)(&v30->3 + 1);
}
}
LOBYTE(v33) = MI_PFN_IS_PROTO((_UNICODE_STRING *)v30, Long, v29, v32);
if( v33 && (*v35 & 0x400i64) != 0 )
MiCheckAndUpdateIoAttribution(v34);
}
LABEL_72:
v36 = FlushKernel;
v22 = v8 & 1;
v37 = 0;
v38 = 0;
v39 = v16;
if( (v16 & 0x20) != 0 )
{
if( ((v8 & 1) == 0 || *(_BYTE *)(v8 & 0xFFFFFFFFFFFFFFFEui64) != 5)
&& (MiFlags & 0x100) == 0
&& (MiFlags & 0x200) == 0 )
{
v37 = 1;
}
}
else
{
v39 = v16 | 0x20;
v38 = 1;
}
if( (*(_QWORD *)(FaultStatus + 8) & 2) == 0 || (v39 & 2) != 0 )
{
if( !v38 )
{
v21 = (unsigned __int8)a2;
goto LABEL_91;
}
}
else
{
if( (v39 & 0x42) == 64 )
v37 = 1;
v39 |= 0x62ui64;
}
v41 = v16;
v21 = (unsigned __int8)a2;
if( v41 != _InterlockedCompareExchange64(a2, v39, v41) )
goto LABEL_32;
LABEL_91:
if( v37 && (MiFlags & 0x100) == 0 && (MiFlags & 0x200) == 0 )
{
v42 = *(_MMSUPPORT_INSTANCE **)(FaultStatus + 56);
if( v42 )
v36 = MiTbFlushType(v42);
KeFlushSingleTb((UINT64)v6, v36, 0i64);
}
goto LABEL_32;
}
if( (*(_DWORD *)(FaultStatus + 80) & 0x20) == 0 )
goto LABEL_72;
LOBYTE(v40) = MI_IS_PTE_SHADOW_STACK(&v44);
if( v40 )
goto LABEL_72;
return -1073741819;
}
v20 = MiCopyOnWrite((UINT64)v6, v11, 0xFFFFFFFFFFFFFFFFui64, 0i64);
v18 = v20;
if( v20 >= 0 )
{
v21 = (unsigned __int8)a2;
v18 = 274;
LABEL_31:
v22 = v8 & 1;
LABEL_32:
if( v22 )
{
v23 = (_MMPTE *)(v8 & 0xFFFFFFFFFFFFFFFEui64);
if( LOBYTE(v23->u.Long) == 5 )
MiValidVirtualizationFault((_MI_FAULT_VA_LIST *)FaultStatus, v23, v21);
}
return v18;
}
MiSetFaultPacketDirectives(FaultStatus, (unsigned int)v20);
return v18;
}Referenced by:
MiUserFault