MiRevertValidPte
VOID __stdcall MiRevertValidPte(
_MMVAD_SHORT *FoundVad,
_MMPTE *PointerPte,
UINT64 ProtectionMask,
UINT64 PageFrameIndex,
_MI_TB_FLUSH_LIST *TbFlushList){
_MMPTE *v5;
_MMVAD_SHORT *v6;
int v8;
UINT64 v9;
unsigned int v10;
__int64 v11;
_MMPTE *PteBase;
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;} v13;
UINT64 v14;
_MMPTE *PxeUserLimit;
int v16;
_MMPFN *PfnDb;
__int64 v18;
__int64 v19;
UINT64 v20;
UINT64 v21;
int v22;
signed __int64 v23;
INT64 *v24;
int v25;
_BOOL4 v26;
__int64 v27;
__int64 v28;
int v29;
char Long;
UINT64 v31;
__int64 v32;
_MI_PARTITION *v33;
unsigned __int8 v34;
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;} v35;
VOID *v36;
unsigned __int64 v37;
__int64 v38;
_MMPFN *v39;
volatile signed __int32 *v40;
__int64 v41;
NTSTATUS v42;
UINT64 v43;
__int64 v44;
UINT64 SpinCount;
__int64 v46;
UINT64 NumberOfEntries;
__int64 v48;
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;} v49;
VOID *Va;
unsigned int v53;
unsigned int a2;
v5 = PointerPte;
a2 = 0;
v6 = FoundVad;
v8 = ProtectionMask;
if( (FoundVad->u.LongFlags & 0x500000) == 5242880 )
{
v37 = ((unsigned __int64)FoundVad->u.LongFlags >> 18) & 3;
v10 = MiVadPageIndices[v37];
v53 = v10;
if( v10 <= 1 )
a2 = 2 - v10;
v9 = MiVadPageSizes[v37];
v38 = 16i64;
v11 = v9;
if( v9 != 16 )
v38 = 1i64;
if( v9 == 16 )
v11 = 1i64;
v48 = v38;
}
else
{
v9 = 1i64;
v10 = 3;
v53 = 3;
v11 = 1i64;
v48 = 1i64;
}
NumberOfEntries = v9;
PteBase = MmGetPteBase();
v13.Long = (unsigned __int64)PointerPte->u;
v49.Long = (unsigned __int64)PointerPte->u;
v14 = (__int64)(((_QWORD)PointerPte << 25) - ((_QWORD)PteBase << 25)) >> 16;
Va = (VOID *)v14;
PxeUserLimit = MmGetPxeUserLimit();
if( PointerPte >= MmGetPml4eBase() && PointerPte <= PxeUserLimit )
v49.Long = v13.Long;
v16 = ProtectionMask & 0x18;
if( (v13.Long & 0x18) == 8 )
{
v8 = ProtectionMask | 0x18;
if( v16 == 24 )
v8 = ProtectionMask;
}
else if( (v13.Long & 0x10) != 0 )
{
if( v16 != 8 )
v8 = ProtectionMask & 0xFFFFFFE7 | 8;
}
else if( (ProtectionMask & 0x18) != 0 )
{
v8 = ProtectionMask & 0xFFFFFFE7;
}
if( PageFrameIndex <= 0xFFFFFFFFFi64 && (MmGetPfnDb()[PageFrameIndex].u4._bf_0 & 0x4000000000000i64) != 0 )
{
PfnDb = MmGetPfnDb();
v18 = (__int64)&PfnDb[PageFrameIndex];
v46 = v18;
if( (MiFlags & 0x40000) != 0 && (v8 & 2) != 0 )
{
if( v11 )
{
v39 = &PfnDb[PageFrameIndex];
v40 = (volatile signed __int32 *)(v18 + 24);
v41 = v11;
do
{
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64(v40, 0x3Fui64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( *(__int64 *)v40 < 0 );
}
if( !MiGetPagePrivilege((ULONG_PTR)v39, 1ui64, 0i64) )
MiMarkPfnVerified(v39, 7ui64);
_InterlockedAnd64((volatile signed __int64 *)v40, 0x7FFFFFFFFFFFFFFFui64);
++v39;
v40 += 12;
--v41;
}
while( v41 );
v5 = PointerPte;
v10 = v53;
v6 = FoundVad;
v46 = (__int64)v39;
v18 = (__int64)v39;
v14 = (UINT64)Va;
PteBase = MmGetPteBase();
}
v18 += -48 * v11;
v46 = v18;
}
}
else
{
v18 = 0i64;
v46 = 0i64;
}
if( v10 <= 1 )
v8 |= 0x4000000u;
v19 = v8 & 0x1F;
v20 = ((PageFrameIndex & 0xFFFFFFFFFi64) << 12) | MmProtectToPteMask[v19] & 0xFFFF000000000E7Fui64 | 0x21;
if( v5 < PteBase || v5 > MmGetPteLimit() )
goto LABEL_110;
if( v5 >= MmGetPdeBase() && v5 <= MmGetPdeLimit() )
{
if( v5 == MmGetPxeSelfRef() )
{
v20 = ((PageFrameIndex & 0xFFFFFFFFFi64) << 12) | MmProtectToPteMask[v19] & 0xFFFF000000000E7Fui64 | 0x8000000000000021ui64;
}
else if( (v8 & 0x4000000) == 0 )
{
v20 = ((PageFrameIndex & 0xFFFFFFFFFi64) << 12) & 0x7FFFFFFFFFFFFFFFi64 | MmProtectToPteMask[v19] & 0x7FFF000000000E7Fi64 | 0x21;
}
v42 = MiUserPdeOrAbove((UINT64)v5);
v18 = v46;
v6 = FoundVad;
if( v42 )
v20 |= 4ui64;
}
if( v5 <= &PteBase[0x7FFFFFFEFi64] )
v20 |= 4ui64;
if( (v8 & 0x4000000) != 0 )
{
LODWORD(v43) = MiGetLeafVa(v14);
v18 = v46;
v21 = v43;
}
else
{
v21 = v14;
}
if( v21 >= 0xFFFF800000000000ui64 )
{
if( MiGetSystemRegionType(v21) == 1
|| v21 >= (unsigned __int64)MmGetPteBase() && v21 <= (unsigned __int64)MmGetPteLimit() )
{
v6 = FoundVad;
v18 = v46;
goto LABEL_23;
}
if( v21 < *(&stru_140C4DB30 + 937) || (v22 = *(&stru_140C4DB30 + 537), v21 > *(&stru_140C4DB30 + 175)) )
v22 = *(&stru_140C4DB30 + 536);
v6 = FoundVad;
v18 = v46;
}
else
{
v22 = *(&stru_140C4DB30 + 537);
}
if( v22 )
LABEL_110:
v20 |= 0x100ui64;
LABEL_23:
if( v8 < 0 && (v8 & 5) == 4 )
v20 |= 0x42ui64;
if( (v8 & 0x40000000) != 0 )
v20 &= ~4ui64;
if( (v8 & 0x20000000) != 0 )
v20 ^= ((unsigned __int16)v20 ^ (unsigned __int16)(*(&stru_140C4DB30 + 536) << 8)) & 0x100;
if( (v8 & 0x8000000) != 0 )
v20 &= ~0x100ui64;
if( (v8 & 0x4000000) != 0 )
v20 |= 0x80ui64;
v23 = v20 & 0xF0FFFFFFFFFFFFFFui64 | 0xA00000000000000i64;
if( v18 )
{
if( (MiFlags & 0x2000000) != 0 && (v13.Long & 0x42) == 64 )
v23 |= 0x40ui64;
}
else
{
v44 = v23 | 0x42;
if( (v8 & 4) == 0 )
v44 = v23;
v23 = v44;
}
v24 = (INT64 *)v5;
v25 = 0;
v26 = (v6->u.LongFlags & 0x300000) == 3145728;
do
{
if( v26 && (MI_READ_PTE_LOCK_FREE((INT64)v24) & 0x42) != 0 )
{
LODWORD(v36) = MiGetLeafVa((UINT64)v24);
MiCaptureWriteWatchDirtyBit(KeGetCurrentThread()->ApcState.Process, v36, FoundVad);
v26 = 0;
}
v23 ^= (v23 ^ (PageFrameIndex << 12)) & 0xFFFFFFFFF000i64;
if( !v25 )
{
if( (MiFlags & 0x100) != 0 || (MiFlags & 0x200) != 0 )
{
v27 = *v24;
if( (*v24 & 0x40) != 0 && (v23 & 0x40) == 0 || (v27 & 2) != 0 && (v23 & 2) == 0 || v23 < 0 && v27 >= 0 )
v25 = 1;
}
else
{
v25 = 1;
}
}
++PageFrameIndex;
if( v53 <= 1 )
{
MiRewritePteWithLockBit((INT64)&KeGetCurrentThread()->ApcState.Process->Vm, v24, v23);
}
else
{
v28 = v23 ^ (v23 ^ *v24) & 0xF00000000000000i64 ^ (v23 ^ (v23 ^ *v24) & 0xF00000000000000i64 ^ *v24) & 0x7000000000000000i64;
LOBYTE(v29) = MiPteInShadowRange((UINT64)v24);
if( v29 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v28 & 1) != 0 )
v28 |= 0x8000000000000000ui64;
*v24 = v28;
}
++v24;
--v48;
}
while( v48 );
Long = v49.Long;
if( v25 )
{
if( !a2 )
{
v31 = NumberOfEntries;
MiInsertTbFlushEntry(TbFlushList, Va, NumberOfEntries, 0i64);
goto LABEL_50;
}
MiInsertLargeTbFlushEntry(TbFlushList, a2, (INT64)PointerPte);
}
v31 = NumberOfEntries;
LABEL_50:
if( v31 == 1 && (Long & 0x42) != 0 )
{
v32 = v46;
if( v46 )
{
if( (FoundVad->u.LongFlags & 0x70) != 64 || MiRotatedToFrameBuffer(PointerPte) )
{
v33 = 0i64;
HIDWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)(v32 + 24), 0x3Fui64) )
{
do
KeYieldProcessorEx((UINT64 *)((char *)&SpinCount + 4));
while( *(__int64 *)(v32 + 24) < 0 );
}
v34 = *(_BYTE *)(v32 + 34);
v35.Long = 0i64;
if( (v34 & 0x10) == 0 )
{
if( (!_bittest64((const signed __int64 *)(v32 + 16), 0xAu) & (unsigned __int8)~(v34 >> 3)) != 0 )
{
v35.Long = MiCapturePageFileInfoInline((_MMPTE *)(v32 + 16), 1ui64, 0i64).u.Long;
v34 = *(_BYTE *)(v32 + 34);
}
*(_BYTE *)(v32 + 34) = v34 | 0x10;
if( v35.Long )
v33 = *(_MI_PARTITION **)(*(&stru_140C4DB30 + 267) + 8 * ((*(_QWORD *)(v32 + 40) >> 39) & 0x3FFi64));
}
_InterlockedAnd64((volatile signed __int64 *)(v32 + 24), 0x7FFFFFFFFFFFFFFFui64);
if( v35.Long )
MiReleasePageFileInfo(v33, (_MMPTE)v35.Long, 1ui64);
}
}
}
}Referenced by:
MiProtectPrivateMemory
MiSetProtectionOnSection
MiSetReadOnlyOnSectionView