MxSwapPages
VOID __stdcall MxSwapPages(_MI_COLOR_BASE *ColorBase, _MMPTE *PointerPxe){
UINT64 v3;
UINT64 v4;
__int64 v5;
UINT64 v6;
INT64 v7;
INT64 v8;
_MMPFN *PfnDb;
_MMPFN *v10;
INT64 v11;
unsigned __int64 v12;
UINT64 v13;
__int64 v14;
__int64 v15;
int v16;
__int64 v17;
__int64 v18;
unsigned __int64 Long;
UINT8 v20;
char v21;
unsigned __int64 v22;
INT64 v23;
UINT64 v24;
unsigned __int64 v25;
unsigned __int64 *v26;
int v27;
UINT64 Phase0Mapping;
UINT64 v29;
int v31;
UINT64 v32;
LODWORD(v3) = MI_READ_PTE_LOCK_FREE((INT64)PointerPxe);
v32 = v3;
v4 = v3;
MiPteInShadowRange((UINT64)&v32);
v5 = (v4 >> 12) & 0xFFFFFFFFFi64;
Phase0Mapping = (UINT64)MxGetPhase0Mapping();
v6 = Phase0Mapping;
if( Phase0Mapping )
{
LODWORD(v7) = MiGetPage(
(ULONG_PTR *)&Irp.Core.PartitionId,
ColorBase[2] & _InterlockedExchangeAdd(*(volatile signed __int32 **)ColorBase, 1u) | (unsigned int)ColorBase[3],
8ui64);
v8 = v7;
if( v7 != -1 )
{
PfnDb = MmGetPfnDb();
v10 = &PfnDb[v7];
v11 = (INT64)&PfnDb[v5];
v12 = MiLockPageInline((_MMPFN *)v11);
MiLockNestedPageAtDpcInline(v10);
MiFinalizePageAttribute(v10, (_MI_PFN_CACHE_ATTRIBUTE)(*(unsigned __int8 *)(v11 + 34) >> 6), 1ui64);
MiCopyPfnEntryEx((INT64)v10, v11);
_InterlockedAnd64(&v10->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
_InterlockedAnd64((volatile signed __int64 *)(v11 + 24), 0x7FFFFFFFFFFFFFFFui64);
__writecr8(v12);
v13 = (UINT64)MmGetPteBase() + ((Phase0Mapping >> 9) & 0x7FFFFFFFF8i64);
LODWORD(v14) = MiMakeValidPte((_XSTATE_CONFIGURATION *)v13, v8, 2684354564i64);
v15 = v14;
LOBYTE(v16) = MiPteInShadowRange(v13);
v31 = v16;
if( v16 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v15 & 1) != 0 )
v15 |= v17;
*(_QWORD *)v13 = v15;
v18 = (__int64)(((_QWORD)PointerPxe << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16;
memmove((VOID *)Phase0Mapping, (const VOID *)v18, 0x1000u);
if( ((v13 ^ v18) & 0xFFFFFFFFFFFFF000ui64) != 0 )
{
Long = ZeroPte.u.Long;
if( v31 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (ZeroPte.u.Long & 1) != 0 )
Long = ZeroPte.u.Long | 0x8000000000000000ui64;
*(_QWORD *)v13 = Long;
}
else
{
v25 = ZeroPte.u.Long;
v26 = (unsigned __int64 *)(Phase0Mapping + 8 * ((v13 >> 3) & 0x1FF));
LOBYTE(v27) = MiPteInShadowRange((UINT64)v26);
if( v27 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (ZeroPte.u.Long & 1) != 0 )
v25 = ZeroPte.u.Long | 0x8000000000000000ui64;
*v26 = v25;
v6 = Phase0Mapping;
}
v32 = v32 ^ (v32 ^ (v8 << 12)) & 0xFFFFFFFFF000i64 | 0x20;
MiWriteValidPteNewPage((INT64 *)PointerPxe, v32, 0i64);
KeFlushSingleTb(v18, FlushKernel, 1i64);
KeFlushSingleTb(v6, FlushKernel, 1i64);
v20 = MiLockPageInline((_MMPFN *)v11);
v21 = *(_BYTE *)(v11 + 34) & 0xDF;
*(_WORD *)(v11 + 32) = 0;
v22 = v20;
*(_QWORD *)(v11 + 24) &= 0xC000000000000000ui64;
*(_BYTE *)(v11 + 34) = v21;
*(_BYTE *)(v11 + 34) &= ~8u;
MiInsertPageInFreeOrZeroedList(v5, 2ui64, v23, v24, Phase0Mapping, v29);
_InterlockedAnd64((volatile signed __int64 *)(v11 + 24), 0x7FFFFFFFFFFFFFFFui64);
__writecr8(v22);
}
}
}Referenced by:
MxMovePageTables
MxRelocatePageTables