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