是什么导致了运行中的进程DirectoryTableBase(CR3)变动

Baklib
狐白 最后一次编辑 4 天前
119

前提

如图,csrss系统进程的CR3值与启动时的值不同
通过调试的栈最终引用函数的是MmStealTopLevelPage
__int64 __fastcall MmStealTopLevelPage(__int64 a1) { struct _KTHREAD *CurrentThread; // r15 _EPROCESS *Process; // r15 __int64 v5; // rdx unsigned int v6; // ebp __int64 v7; // rsi unsigned __int64 v8; // r12 ULONG_PTR v9; // rbx unsigned __int64 v10; // rsi ULONG_PTR v11; // r14 __int64 v12; // rbx unsigned __int64 v13; // rdi unsigned __int64 v14; // rsi bool v15; // zf ULONG_PTR *BugCheckParameter2; // [rsp+70h] [rbp+8h] CurrentThread = KeGetCurrentThread(); if ( *(struct _KTHREAD **)(a1 + 40) != CurrentThread ) return 0; Process = CurrentThread->ApcState.Process; MiLockWorkingSetExclusiveAtDpc(&Process->Vm); MiReplacePageTablePage(a1); v6 = 0; if ( *(int *)(a1 + 56) >= 0 ) { v7 = *(_QWORD *)(a1 + 32); ++dword_140EF4AA8; v8 = MiMapPageInHyperSpaceWorker(*(_QWORD *)(a1 + 32), 0, 0x80000000LL); BugCheckParameter2 = (ULONG_PTR *)(v8 + 8 * (((((*(_QWORD *)(a1 + 8) >> 9) & 0x7FFFFFFFF8uLL) - 0x98000000000LL) >> 3) & 0x1FF)); v9 = (v7 << 12) ^ ((v7 << 12) ^ ((__int64 (*)(void))MI_READ_PTE_LOCK_FREE)()) & 0xFFF0000000000FFFuLL; *BugCheckParameter2 = CLFS_LSN_NULL_EXT; if ( _bittest64(&MiFlags, 0x24u) && (v9 & 0x20) == 0 && (unsigned __int64)BugCheckParameter2 >= 0xFFFFF6C000000000uLL ) { MiCheckLinearProtectedPteAccessedBit((ULONG_PTR)BugCheckParameter2, v9); } v5 = 0x7FFFFFFFF8LL; *BugCheckParameter2 = v9; *(_QWORD *)KeGetCurrentPrcb()->MmInternal = 0; *(_QWORD *)(((v8 >> 9) & 0x7FFFFFFFF8LL) - 0x98000000000LL) = CLFS_LSN_NULL_EXT; if ( *(_DWORD *)(a1 + 64) ) { v11 = (((unsigned __int64)Process->Vm.Shared.ShadowMapping >> 9) & 0x7FFFFFFFF8LL) - 0x98000000000LL; v12 = MI_READ_PTE_LOCK_FREE(v11); *(_QWORD *)v11 = CLFS_LSN_NULL_EXT; MiFlushSingleTbEntry((__int64)(v11 << 25) >> 16, 2, 1); v13 = (v7 << 12) ^ (v12 ^ (v7 << 12)) & 0xFFF0000000000FFFuLL; if ( _bittest64(&MiFlags, 0x24u) && (v12 & 0x20) == 0 && v11 >= 0xFFFFF6C000000000uLL ) MiCheckLinearProtectedPteAccessedBit(v11, (v7 << 12) ^ (v12 ^ (v7 << 12)) & 0xFFF0000000000FFFuLL); v14 = v7 << 12; v15 = KiFlushPcid == 0; *(_QWORD *)v11 = v13; if ( !v15 ) v14 |= 1u; Process->Pcb.UserDirectoryTableBase = v14; } else { v10 = v7 << 12; if ( KiFlushPcid ) v10 |= 2u; Process->Pcb.DirectoryTableBase = v10; } v6 = 1; } LOBYTE(v5) = 17; MiUnlockWorkingSetExclusive(&Process->Vm, v5); return v6; }

是谁做的

目前已知的有
任务计划程序 -> MemoryDiagnostic
NTPAI->NtSetSystemInformation->SystemScrubPhysicalMemoryInformation

什么情况会引发这种情况

如果一个进程占用大量内存,可能会触发物理内存回收整合

可能的影响

不能依赖保存的CR3的值,因为随时可能回收导致CR3的物理地址失效。

如何防止CR3更变

锁定