MmStealTopLevelPage
NTSTATUS __stdcall MmStealTopLevelPage(VOID *Context){
_ETHREAD *CurrentThread;
_EPROCESS *Process;
_MMSUPPORT_SHARED *SharedVm;
NTSTATUS v6;
__int64 v7;
unsigned __int64 *v8;
__int64 v9;
unsigned __int64 v10;
unsigned __int64 Long;
int v12;
__int64 v13;
unsigned __int64 v14;
UINT64 v15;
__int64 v16;
unsigned __int64 v17;
__int64 v18;
int v19;
int v20;
unsigned __int64 v21;
unsigned __int64 v22;
UINT8 WsIrql;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
if( *((_ETHREAD **)Context + 5) != CurrentThread )
return 0;
Process = CurrentThread->Tcb.ApcState.Process;
SharedVm = MiGetSharedVm(&Process->Vm.Instance);
v6 = 0;
WsIrql = ExAcquireSpinLockExclusive((INT64 *)&SharedVm->WorkingSetLock);
SharedVm->GoodCitizenWaiting = 0;
MiReplacePageTablePage((_MI_REPLACE_INFO *)Context);
if( *((int *)Context + 14) >= 0 )
{
v7 = *((_QWORD *)Context + 4);
v8 = (unsigned __int64 *)(*((_QWORD *)Context + 2)
+ 8
* (((unsigned __int64)((unsigned int)MmGetPteBase()
+ ((*((_DWORD *)Context + 2) >> 9) & 0xFFFFFFF8)) >> 3) & 0x1FF));
LODWORD(v9) = MI_READ_PTE_LOCK_FREE((INT64)v8);
v10 = ((v7 & 0xFFFFFFFFFi64) << 12) | v9 & 0xFFFF000000000FFFui64;
Long = ZeroPte.u.Long;
LOBYTE(v12) = MiPteInShadowRange((UINT64)v8);
if( v12 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (ZeroPte.u.Long & 1) != 0 )
Long = v13 | ZeroPte.u.Long;
*v8 = Long;
if( v12 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v10 & 1) != 0 )
v10 |= v13;
*v8 = v10;
if( *((_DWORD *)Context + 15) )
{
v15 = (UINT64)MmGetPteBase() + (((unsigned __int64)Process->Vm.Shared.ShadowMapping >> 9) & 0x7FFFFFFFF8i64);
LODWORD(v16) = MI_READ_PTE_LOCK_FREE(v15);
v17 = ZeroPte.u.Long;
v18 = v16;
LOBYTE(v19) = MiPteInShadowRange(v15);
v20 = v19;
if( v19 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (ZeroPte.u.Long & 1) != 0 )
v17 = ZeroPte.u.Long | 0x8000000000000000ui64;
*(_QWORD *)v15 = v17;
KeFlushSingleTb((__int64)((v15 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16, FlushKernel, 2i64);
v21 = ((v7 & 0xFFFFFFFFFi64) << 12) | v18 & 0xFFFF000000000FFFui64;
if( v20 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v21 & 1) != 0 )
v21 |= 0x8000000000000000ui64;
*(_QWORD *)v15 = v21;
LODWORD(v22) = KeMakeUserDirectoryTableBase(v7 << 12);
Process->Pcb.UserDirectoryTableBase = v22;
}
else
{
LODWORD(v14) = KeMakeKernelDirectoryTableBase(v7 << 12);
Process->Pcb.DirectoryTableBase = v14;
}
v6 = 1;
}
MiUnlockWorkingSetExclusive(&Process->Vm.Instance, WsIrql);
return v6;
}Referenced by:
KiSwapDirectoryTableBaseTarget