MiResolveTransitionFault
INT64 __fastcall MiResolveTransitionFault(
VOID *FaultingAddress,
_MMPTE *PoINTerPte,
_MMPFN *ProtoPfn,
_MMSUPPORT_INSTANCE *Vm,
VOID *TrapInformation,
UINT64 StoreInstruction,
INT64 VmIrql,
CHAR PreviousMode,
_MMINPAGE_SUPPORT **ReadBlock){
VOID *v9;
__int64 v10;
INT64 v12;
unsigned __int64 v13;
_DWORD *v14;
ULONG_PTR v15;
char *v16;
_MMPFN *PfnDb;
unsigned __int64 v18;
char *v19;
INT64 result;
unsigned __int64 v21;
_MMPTE *Pml4eBase;
_MMPTE *PxeUserLimit;
unsigned __int64 v24;
unsigned int v25;
char v26;
__int64 v27;
_QWORD *v28;
WCHAR *v29;
_MMSUPPORT_INSTANCE *v30;
__int64 v31;
unsigned __int64 v32;
__int64 v33;
unsigned __int64 v34;
__int64 v35;
__int64 v36;
INT64 v37;
unsigned __int64 v38;
INT64 v39;
__int64 v40;
__int64 v41;
int v42;
INT64 v43;
int v44;
unsigned __int64 v45;
unsigned __int64 v46;
__int64 CurrentPrcb;
_MMPFN *v48;
int v49;
int v50;
bool v51;
__int64 v52;
_MMPTE *PteBase;
char v54;
int v55;
unsigned __int64 v56;
unsigned __int64 v57;
unsigned __int64 v58;
__int64 v59;
__int64 v60;
signed __int32 v61;
struct _SLIST_ENTRY *v62;
int v63;
WCHAR *v64;
_BYTE *v65;
__int64 v66;
__int64 v67;
char v68;
int v69;
__int16 v70;
UNICODE_STRING *v71;
int v72;
char v73;
INT64 *BugCheckParameter4;
_DWORD *a6;
PSLIST_ENTRY *a7;
INT64 v77;
INT64 a9;
INT64 v79;
INT64 a11;
INT64 a5;
PSLIST_ENTRY ListEntry;
INT64 v83;
_MMPTE *v84;
__int64 v85;
v9 = TrapInformation;
v10 = *((_QWORD *)FaultingAddress + 7);
v12 = *((_QWORD *)FaultingAddress + 2);
v13 = (unsigned __int64)PoINTerPte;
LODWORD(a9) = 0;
v14 = FaultingAddress;
*(_QWORD *)TrapInformation = 0i64;
v85 = v10;
a11 = v12;
ListEntry = 0i64;
if( !ProtoPfn )
{
v15 = MI_READ_PTE_LOCK_FREE((INT64)PoINTerPte);
if( (v15 & 0x800) != 0 )
{
v16 = (char *)MmGetPfnDb() + 40;
do
{
PfnDb = MmGetPfnDb();
if( (v15 & 1) == 0 && (!v15 || !qword_140C4DC80 || (qword_140C4DC80 & v15) != 0) )
{
v18 = v15;
if( qword_140C4DC80 && (v15 & 0x10) == 0 )
v18 = v15 & ~qword_140C4DC80;
if( (*(_QWORD *)&v16[48 * ((v18 >> 12) & 0xFFFFFFFFFi64)] & 0x4000000000000i64) != 0 )
{
v19 = (char *)PfnDb + 48 * ((v18 >> 12) & 0xFFFFFFFFFi64);
HIDWORD(a9) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)v19 + 6, 0x3Fui64) )
{
do
KeYieldProcessorEx((UINT64 *)((char *)&a9 + 4));
while( *((__int64 *)v19 + 3) < 0 );
}
if( MI_READ_PTE_LOCK_FREE(v13) == v15 )
{
PoINTerPte = (_MMPTE *)0x8000000000000000i64;
if( (*((_QWORD *)v19 + 1) | 0x8000000000000000ui64) != v13 )
{
PoINTerPte = (_MMPTE *)0x1000000000i64;
if( (*((_QWORD *)v19 + 5) & 0x1000000000i64) == 0 )
KeBugCheckEx(0x1Au, 0x411ui64, v13, v15, *((_QWORD *)v19 + 1));
}
v21 = *(_QWORD *)v13;
Pml4eBase = MmGetPml4eBase();
PxeUserLimit = MmGetPxeUserLimit();
v9 = TrapInformation;
v12 = a11;
v14 = FaultingAddress;
goto LABEL_26;
}
_InterlockedAnd64((volatile signed __int64 *)v19 + 3, 0x7FFFFFFFFFFFFFFFui64);
}
}
v15 = MI_READ_PTE_LOCK_FREE(v13);
}
while( (v15 & 0x800) != 0 );
}
return 3221226548i64;
}
v21 = *(_QWORD *)PoINTerPte;
Pml4eBase = MmGetPml4eBase();
PxeUserLimit = MmGetPxeUserLimit();
v24 = *(_QWORD *)PoINTerPte;
if( qword_140C4DC80 && (v21 & 0x10) == 0 )
v24 = v21 & ~qword_140C4DC80;
v19 = (char *)MmGetPfnDb() + 48 * ((v24 >> 12) & 0xFFFFFFFFFi64);
LABEL_26:
if( (v19[35] & 0x10) != 0 )
{
v25 = -1073740023;
LABEL_39:
_InterlockedAnd64((volatile signed __int64 *)v19 + 3, 0x7FFFFFFFFFFFFFFFui64);
if( ProtoPfn )
{
LOBYTE(PoINTerPte) = 17;
MiUnlockProtoPoolPage(ProtoPfn, (UINT64)PoINTerPte);
}
return v25;
}
PoINTerPte = (_MMPTE *)(v12 & 1);
v84 = PoINTerPte;
if( (v12 & 1) != 0 && *(_BYTE *)(v12 & 0xFFFFFFFFFFFFFFFEui64) == 1 )
{
MiUpdatePfnPriority((INT64)v19);
v25 = 0;
goto LABEL_39;
}
__incgsdword(0x2E98u);
v26 = v19[34];
if( (v26 & 8) != 0 )
{
if( (MiFlags & 0x40000) != 0 && (v27 = *((_QWORD *)v19 + 2) >> 5, (v27 & 0x1F) == 0) && (v27 & 2) != 0
|| (v12 & 1) != 0
&& *(_BYTE *)(v12 & 0xFFFFFFFFFFFFFFFEui64) == 5
&& (*(_DWORD *)((v12 & 0xFFFFFFFFFFFFFFFEui64) + 56) & 0x20) != 0 )
{
v14[20] |= 0x80u;
v25 = -1073741801;
goto LABEL_39;
}
}
if( (v26 & 0x20) != 0 )
{
result = MiHandleCollidedFault((INT64)v14, (_MMPTE *)v13, (INT64)ProtoPfn, (INT64)v19, (INT64)v9, &a9);
if( (unsigned int)a9 <= 1 || (int)result < 0 )
return result;
}
else
{
a5 = 0i64;
a7 = &ListEntry;
a6 = (_DWORD *)v21;
BugCheckParameter4 = &a5;
result = MiHandleTransitionFault();
if( (int)result < 0 )
return result;
if( a5 )
v19 = (char *)a5;
}
v30 = Vm;
v31 = *((_QWORD *)FaultingAddress + 2);
if( (v31 & 1) != 0 && *(_BYTE *)(v31 & 0xFFFFFFFFFFFFFFFEui64) == 4 )
{
v21 = -865i64;
*(_QWORD *)v13 = *(_QWORD *)v13 & 0xFFFFFFFFFFFFFC1Fui64 | 0x80;
}
if( ((v21 >> 5) & 0x1F) == 24 )
MiMakeProtoReadOnly((UINT64 *)v13, (INT64)v19);
v32 = *(_QWORD *)v13;
v33 = *(_QWORD *)v13;
if( qword_140C4DC80 && (v32 & 0x10) == 0 )
v33 = v32 & ~qword_140C4DC80;
v34 = v33 & 0xFFFFFFFFF000i64 | MmProtectToPteMask[(v32 >> 5) & 0x1F] & 0xFFFF000000000E7Fui64 | 0x21;
if( v13 < (unsigned __int64)MmGetPteBase() || v13 > (unsigned __int64)MmGetPteLimit() )
{
v36 = v34 | 0x100;
}
else
{
v35 = (__int64)((v13 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16;
if( v13 >= (unsigned __int64)MmGetPdeBase() && v13 <= (unsigned __int64)MmGetPdeLimit() )
{
if( (_MMPTE *)v13 == MmGetPxeSelfRef() )
v34 |= 0x8000000000000000ui64;
else
v34 &= ~0x8000000000000000ui64;
if( (unsigned int)MiUserPdeOrAbove(v13) )
v34 |= 4ui64;
}
if( v13 <= (unsigned __int64)MmGetPteBase() + 0x3FFFFFFF78i64 )
v34 |= 4ui64;
v36 = v34 | 0x100;
if( !(unsigned int)MiIsAddressGlobal(v35) )
v36 = (__int64)v28;
}
v37 = ZeroPte;
v38 = v36 & 0xF0FFFFFFFFFFFFFFui64 | 0xA00000000000000i64;
v39 = *(_QWORD *)(qword_140C4E388 + 8 * ((*((_QWORD *)v19 + 5) >> 39) & 0x3FFi64));
v40 = *((_QWORD *)v19 + 2);
v83 = v39;
if( (v40 & 0x400) == 0 && (v40 & 4) != 0 && (unsigned __int16)v40 >> 12 == *(_DWORD *)(v39 + 1156) )
v37 = MiCaptureDirtyBitToPfn((INT64)v19);
v41 = *((_QWORD *)v19 + 2);
if( (v41 & 0x400) == 0 && (v41 & 0x4000000) != 0 )
v38 |= 0x40ui64;
if( (v38 & 0x800) != 0 )
{
v28 = FaultingAddress;
if( Vm && !MiOkToSetPteDirtyForNotValidFault(v38, *(_QWORD *)FaultingAddress) )
v30 = 0i64;
if( (v19[34] & 0x10) != 0 )
{
if( v30 || *v28 >= 0xFFFF800000000000ui64 )
goto LABEL_90;
}
else if( v30 )
{
LOBYTE(v42) = MI_PFN_IS_PROTO((UNICODE_STRING *)v19, (UNICODE_STRING *)v39, (UINT8)v28, v29);
if( !v42 )
{
v37 = MiCaptureDirtyBitToPfn(v43);
LABEL_90:
v38 |= 0x42ui64;
}
}
}
LOBYTE(v44) = MI_PFN_IS_PROTO((UNICODE_STRING *)v19, (UNICODE_STRING *)v39, (UINT8)v28, v29);
if( v44 )
{
v45 = v38;
if( v13 >= (unsigned __int64)Pml4eBase
&& v13 <= (unsigned __int64)PxeUserLimit
&& (*(_DWORD *)(*((_QWORD *)KeGetCurrentThread() + 23) + 2172i64) & 0x1000) != 0 )
{
v45 = v38 | 0x8000000000000000ui64;
}
*(_QWORD *)v13 = v45;
}
_InterlockedAnd64((volatile signed __int64 *)v19 + 3, 0x7FFFFFFFFFFFFFFFui64);
v48 = ProtoPfn;
v49 = 0;
v50 = 1;
if( !ProtoPfn )
goto LABEL_146;
LODWORD(v79) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)ProtoPfn + 6, 0x3Fui64) )
{
do
KeYieldProcessorEx((UINT64 *)&v79);
while( *((__int64 *)ProtoPfn + 3) < 0 );
}
*((_BYTE *)ProtoPfn + 34) &= ~0x20u;
v45 = *((unsigned __int16 *)ProtoPfn + 16);
if( !(_WORD)v45 )
MiBadRefCount(ProtoPfn, v45);
v51 = (_WORD)v45 == 1;
LOWORD(v45) = v45 - 1;
*((_WORD *)ProtoPfn + 16) = v45;
if( v51 && MiIsPfnFileOnly((INT64)ProtoPfn) )
goto LABEL_144;
CurrentPrcb = *((_QWORD *)ProtoPfn + 5);
if( (CurrentPrcb & 0x1000000000i64) != 0 || (CurrentPrcb & 0x2000000000000i64) != 0 )
goto LABEL_145;
v52 = *((_QWORD *)ProtoPfn + 3) & 0x3FFFFFFFFFFFFFFFi64;
if( !(_WORD)v45 )
goto LABEL_114;
if( (_WORD)v45 != 1 )
{
if( (_WORD)v45 != 2 || !v52 )
goto LABEL_145;
LABEL_112:
if( (*((_BYTE *)ProtoPfn + 34) & 8) == 0 )
goto LABEL_145;
goto LABEL_113;
}
if( !v52 )
goto LABEL_112;
LABEL_113:
v50 = 0;
LABEL_114:
PteBase = MmGetPteBase();
v46 = *((_QWORD *)ProtoPfn + 1) | 0x8000000000000000ui64;
if( v46 > (unsigned __int64)PteBase + 0x3FFFFFFF78i64 || v46 < (unsigned __int64)PteBase )
{
v54 = *((_BYTE *)ProtoPfn + 35);
if( (v54 & 0x20) != 0 )
{
*((_BYTE *)ProtoPfn + 35) = v54 & 0xDF;
goto LABEL_143;
}
}
LOBYTE(v55) = MI_PFN_IS_PROTO((UNICODE_STRING *)ProtoPfn, 0i64, *((_BYTE *)ProtoPfn + 8), (PWCHAR)CurrentPrcb);
if( v55 && (*((_DWORD *)ProtoPfn + 4) & 0x400i64) != 0 )
{
v45 = 1i64;
}
else if( v56 <= v58 && v56 >= (unsigned __int64)MmGetPteBase() && (*((_BYTE *)ProtoPfn + 35) & 0x20) != 0 )
{
v45 = 1i64;
}
else if( v50 == 1 && (v59 & 0x4000000000000000i64) != 0 )
{
v45 = 1i64;
}
CurrentPrcb = (v57 >> 39) & 0x3FF;
v60 = *(_QWORD *)(qword_140C4E388 + 8 * CurrentPrcb);
if( (_DWORD)v45 == 1 )
MiReturnCommit(*(_MI_PARTITION **)(qword_140C4E388 + 8 * CurrentPrcb), 1ui64);
v46 = 1i64;
if( (ULONG_PTR *)v60 != &MiSystemPartition )
goto LABEL_141;
CurrentPrcb = (__int64)KeGetCurrentPrcb();
v45 = *(int *)(CurrentPrcb + 33564);
if( (_DWORD)v45 == -1 )
goto LABEL_141;
if( v45 + 1 <= 0x100 )
{
do
{
v61 = _InterlockedCompareExchange((volatile signed __int32 *)(CurrentPrcb + 33564), v45 + 1, v45);
v51 = (_DWORD)v45 == v61;
v45 = v61;
if( v51 )
goto LABEL_142;
}
while( v61 != -1 && (unsigned __int64)(v61 + 1i64) <= 0x100 );
}
if( (int)v45 > 192
&& (_DWORD)v45 != -1
&& (_DWORD)v45 == _InterlockedCompareExchange((volatile signed __int32 *)(CurrentPrcb + 33564), 192, v45) )
{
v46 = (int)v45 - 192 + 1i64;
}
if( v46 )
LABEL_141:
v46 = _InterlockedExchangeAdd64((volatile signed __int64 *)(v60 + 7168), v46);
LABEL_142:
v48 = ProtoPfn;
LABEL_143:
if( v50 )
LABEL_144:
MiPfnReferenceCountIsZero(v48, (v48 - MmGetPfnDb()) / 48, (UINT8 *)v46);
LABEL_145:
_InterlockedAnd64((volatile signed __int64 *)v48 + 3, 0x7FFFFFFFFFFFFFFFui64);
LABEL_146:
if( v37 )
MiReleasePageFileInfo(
v83,
v37,
1,
CurrentPrcb,
(INT64)BugCheckParameter4,
(INT64)a6,
(INT64)a7,
v77,
a9,
v79,
a11,
a5);
v62 = ListEntry;
if( ListEntry )
{
if( SLODWORD(ListEntry[11].Next) > 1 )
KeSetEvent((PRKEVENT)(&ListEntry[3].Next + 1), 0);
MiFreeInPageSupportBlock(v62);
}
LOBYTE(v63) = MI_PFN_IS_PROTO((UNICODE_STRING *)v19, (UNICODE_STRING *)v45, v46, (PWCHAR)CurrentPrcb);
if( v63 )
{
result = MiCompleteProtoPteFault((INT64)FaultingAddress, v38, (__int64)Vm, 0, a11);
if( (int)result < 0 )
return result;
}
else
{
v65 = (_BYTE *)(a11 & 0xFFFFFFFFFFFFFFFEui64);
if( v84 && *v65 == 4 )
{
*(_QWORD *)v13 = v38;
}
else
{
v66 = 0i64;
if( v84 )
{
if( *v65 == 3 )
{
v38 &= ~0x20ui64;
v49 = 1;
}
else if( *v65 == 5 )
{
v66 = a11 & 0xFFFFFFFFFFFFFFFEui64;
}
}
if( (*((_BYTE *)FaultingAddress + 69) & 8) != 0 )
{
v67 = *((_QWORD *)FaultingAddress + 2);
if( (v67 & 1) == 0 || *(_BYTE *)(v67 & 0xFFFFFFFFFFFFFFFEui64) != 2 )
v38 &= ~0x20ui64;
}
v68 = *((_BYTE *)FaultingAddress + 69);
if( (v68 & 5) == 4 && (v68 & 2) == 0 )
{
v69 = *((unsigned __int16 *)FaultingAddress + 33);
if( (_WORD)v69
&& (v69 + *((unsigned __int16 *)FaultingAddress + 32) != (((unsigned int)v13 >> 3) & 0x1FF)
|| (v68 & 0x10) == 0) )
{
MiEmptyDeferredWorkingSetEntries((INT64)FaultingAddress + 56);
}
v70 = *((_WORD *)FaultingAddress + 33);
if( v70 )
{
*((_WORD *)FaultingAddress + 33) = v70 + 1;
}
else
{
v71 = (UNICODE_STRING *)*((unsigned __int8 *)FaultingAddress + 69);
*((_WORD *)FaultingAddress + 33) = 1;
*((_WORD *)FaultingAddress + 32) = ((unsigned int)v13 >> 3) & 0x1FF;
LOBYTE(v72) = MI_PFN_IS_PROTO((UNICODE_STRING *)v19, v71, 0xFFu, v64);
if( v72 )
*((_BYTE *)FaultingAddress + 69) = v73 & 0xEF;
else
*((_BYTE *)FaultingAddress + 69) = v73 | 0x10;
}
v49 |= 4u;
}
LODWORD(a6) = v49;
if( !(unsigned int)MiAllocateWsle(v85, v13, v19, 0, v38, (__int64)a6, v66) )
{
MiLockAndDecrementShareCount((UINT64)v19, 0);
return 3221225495i64;
}
}
}
return 272i64;
}Referenced by:
MiDispatchFault
MiResolveProtoPteFault