探究Windows 2000/XP原型PTE(http://webcrazy.yeah.net)

本文详细探讨了Windows 2000/XP操作系统的内存管理,尤其是原型PTE(Prototype PTE)的角色。通过原型PTE,系统能够有效地处理内存共享,特别是对于文件映射的情况。当多个进程需要访问同一文件时,Windows 2000/XP使用Section对象和PPTE表来实现共享,并避免频繁更新硬件PTE。在Page Fault处理过程中,通过软件模拟来处理指向PPTE的无效PTE,从而提高效率。文章还介绍了如何通过软中断和调试工具验证这一机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

探究Windows 2000/XP原型PTE
              WebCrazy(http://webcrazy.yeah.net)

    内存管理可以说是操作系统实现中最重要的环节,也是最为复杂的一环节。对于相对贫乏的内存资源,内存共享也成了一个很重要的有效手段。Windows 2000/XP在此方面的实现借助于一个称为原型PTE(Prototype PTE,PPTE)的软件机制。在《小议Windows NT/2000分页机制》中我详细的介绍了Intel X86实现分段、分页的硬件PTE工作方式。我们来回顾一下这种机制:

    假设我们的一个进程映射了从虚拟地址0xXXXXXXXX(假设位于分配粒度上)开始的4M空间,而这4M空间当前都相应的映射了实际的物理内存(鉴于Lazy evaluation等的先进思想,这种情况在Windows 2000/XP中比较少见)。我们将这4M空间分成1000块的4K(PAGE_SIZE,X86处理器决定),对于第n个4K(0<=n<1000),其虚拟地址(0xXXXXXXXX+n*4K),我们都有一个对应的硬件PTE,指出目前这4K驻留于物理内存的位置。通过由PDBR(CR3寄存器)与虚拟地址可定位这个硬件PTE(具体请参阅《小议Windows NT/2000分页机制》)。

    现在让我们来考虑这样一种情况,我们有一个文件其大小也为4M,我们知道通常我们要使用这个文件都要将它读入内存。试想同时有两个或更多的进程需读写这个文件,这就需要解决内存共享的问题。实际上就算当前只有一个进程访问这个文件,对于这种潜在的需要共享的文件,Windows 2000/XP均会事先考虑共享情况。她通过一个称为Section的内核对象来实现这样的目的。仔细想想,这种情况下内存共享决不仅仅是内存资源的充分利用,就算我们可以为每个进程各分配4M空间,但是这将导致各个进程某种时刻可能得不到这个文件的最新内容。这是非常糟糕的情况。在内部Windows 2000/XP利用原型PTE来解决这样的情况。基于硬件PTE相同的原理,对于这样一个4M的文件,在映射这个文件时,Windows 2000/XP同样的将这个文件分成1000块,每块4K(PAGE_SIZE)大小。然后从页交换区分配1000个DWORD,每个DWORD值都是原型PTE,它们组成原型PTE表。对于这个文件的第n个4K(0<=n<1000),如果当前其驻留在物理内存中的话,其对应的PPTE的Valid位(bit 0,与硬件PTE一致)为1,然后这个PPTE的Page Frame Number(PPTE的高20位)用于指示物理内存。如果当前其仍然在磁盘中的话,Valid位为0。针对这种情况,通过PPTE的高20位(PFN Entry),查找Page Frame Datbase(由MmPfnDatabase定位),通过PFN Entry的Subsection PTE(windbg中称为restore pte,《Inside Windows 2000》中称为original pte,Windows XP内部称为Subsection PTE),定位Subsection,然后通过Subsection指向的Control Area的FILE_OBJECT,与PPTE在PPTE表的偏移n,通过公式:

    PFN Entry Subsection PTE->Subsection->Control Area->FileObject + n * 4K

定位所要访问的文件偏移,这样Windows 2000/XP使用页面调入IO读入这页内容,更新PPTE表的这个PPTE。以上的这一系列定位转换算法,如Subsection PTE如何定位Subsection,我将另行介绍。上面的描述解决了一个非常重要的问题,我们不需要更新所有引用这一页面的进程的硬件PTE,因为此时所有进程的PTE均指向PPTE,我们只要更新PPTE就能达到目的。至于进程PTE如何指向PPTE,下面我会涉及到这个内容。这儿你只要有一个概念,进程的PTE为了指向PPTE,肯定是一个Invalid PTE,即bit 0为0,而且其bit 10为1(PPTE标志,具体请看我在《探寻Windows NT/2000 Copy On Write机制》列出的HARDWARE_PTE_X86结构)。

 
上面的错误,我使用了!analyze -v 指令后 SYSTEM_SERVICE_EXCEPTION (3b) An exception happened while executing a system service routine. Arguments: Arg1: 00000000c000001d, Exception code that caused the BugCheck Arg2: ffffbf8942103b20, Address of the instruction which caused the BugCheck Arg3: ffffdf815547d070, Address of the context record for the exception that caused the BugCheck Arg4: 0000000000000000, zero. Debugging Details: ------------------ KEY_VALUES_STRING: 1 Key : Analysis.CPU.mSec Value: 3109 Key : Analysis.Elapsed.mSec Value: 15964 Key : Analysis.IO.Other.Mb Value: 0 Key : Analysis.IO.Read.Mb Value: 14 Key : Analysis.IO.Write.Mb Value: 2 Key : Analysis.Init.CPU.mSec Value: 1625 Key : Analysis.Init.Elapsed.mSec Value: 336944 Key : Analysis.Memory.CommitPeak.Mb Value: 121 Key : Analysis.Version.DbgEng Value: 10.0.27829.1001 Key : Analysis.Version.Description Value: 10.2503.24.01 amd64fre Key : Analysis.Version.Ext Value: 1.2503.24.1 Key : Bugcheck.Code.KiBugCheckData Value: 0x3b Key : Bugcheck.Code.LegacyAPI Value: 0x3b Key : Bugcheck.Code.TargetModel Value: 0x3b Key : Failure.Bucket Value: 0x3B_C000001D_HyperHideDrv!HookedNtContinue Key : Failure.Exception.IP.Address Value: 0xffffbf8942103b20 Key : Failure.Hash Value: {8e106373-5690-bf65-5b28-0541e087c782} Key : Hypervisor.Enlightenments.Value Value: 13088 Key : Hypervisor.Enlightenments.ValueHex Value: 0x3320 Key : Hypervisor.Flags.AnyHypervisorPresent Value: 1 Key : Hypervisor.Flags.ApicEnlightened Value: 0 Key : Hypervisor.Flags.ApicVirtualizationAvailable Value: 0 Key : Hypervisor.Flags.AsyncMemoryHint Value: 0 Key : Hypervisor.Flags.CoreSchedulerRequested Value: 0 Key : Hypervisor.Flags.CpuManager Value: 0 Key : Hypervisor.Flags.DeprecateAutoEoi Value: 1 Key : Hypervisor.Flags.DynamicCpuDisabled Value: 0 Key : Hypervisor.Flags.Epf Value: 0 Key : Hypervisor.Flags.ExtendedProcessorMasks Value: 0 Key : Hypervisor.Flags.HardwareMbecAvailable Value: 0 Key : Hypervisor.Flags.MaxBankNumber Value: 0 Key : Hypervisor.Flags.MemoryZeroingControl Value: 0 Key : Hypervisor.Flags.NoExtendedRangeFlush Value: 1 Key : Hypervisor.Flags.NoNonArchCoreSharing Value: 0 Key : Hypervisor.Flags.Phase0InitDone Value: 1 Key : Hypervisor.Flags.PowerSchedulerQos Value: 0 Key : Hypervisor.Flags.RootScheduler Value: 0 Key : Hypervisor.Flags.SynicAvailable Value: 1 Key : Hypervisor.Flags.UseQpcBias Value: 0 Key : Hypervisor.Flags.Value Value: 536632 Key : Hypervisor.Flags.ValueHex Value: 0x83038 Key : Hypervisor.Flags.VpAssistPage Value: 1 Key : Hypervisor.Flags.VsmAvailable Value: 0 Key : Hypervisor.RootFlags.AccessStats Value: 0 Key : Hypervisor.RootFlags.CrashdumpEnlightened Value: 0 Key : Hypervisor.RootFlags.CreateVirtualProcessor Value: 0 Key : Hypervisor.RootFlags.DisableHyperthreading Value: 0 Key : Hypervisor.RootFlags.HostTimelineSync Value: 0 Key : Hypervisor.RootFlags.HypervisorDebuggingEnabled Value: 0 Key : Hypervisor.RootFlags.IsHyperV Value: 0 Key : Hypervisor.RootFlags.LivedumpEnlightened Value: 0 Key : Hypervisor.RootFlags.MapDeviceInterrupt Value: 0 Key : Hypervisor.RootFlags.MceEnlightened Value: 0 Key : Hypervisor.RootFlags.Nested Value: 0 Key : Hypervisor.RootFlags.StartLogicalProcessor Value: 0 Key : Hypervisor.RootFlags.Value Value: 0 Key : Hypervisor.RootFlags.ValueHex Value: 0x0 Key : SecureKernel.HalpHvciEnabled Value: 0 Key : WER.OS.Branch Value: vb_release Key : WER.OS.Version Value: 10.0.19041.1 BUGCHECK_CODE: 3b BUGCHECK_P1: c000001d BUGCHECK_P2: ffffbf8942103b20 BUGCHECK_P3: ffffdf815547d070 BUGCHECK_P4: 0 FAULTING_THREAD: ffffbf8943364080 CONTEXT: ffffdf815547d070 -- (.cxr 0xffffdf815547d070) rax=ffffbf8942103b10 rbx=ffffbf8943364080 rcx=000000e265bff770 rdx=0000000000000001 rsi=0000000000000000 rdi=0000000000000000 rip=ffffbf8942103b20 rsp=ffffdf815547da78 rbp=ffffdf815547db80 r8=00000000ffffffff r9=7ffff80119936b30 r10=7ffffffffffffffc r11=0000000000336cb0 r12=0000000000000000 r13=0000000000000000 r14=0000000000000000 r15=0000000000000000 iopl=0 nv up ei ng nz ac po cy cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00010297 ffffbf89`42103b20 ff ??? Resetting default scope PROCESS_NAME: msedgewebview2.exe STACK_TEXT: ffffdf81`5547da78 fffff801`1992bc21 : ffffbf89`48c74080 fffff801`00000013 00000000`00000000 ffffdf81`5547db80 : 0xffffbf89`42103b20 ffffdf81`5547da80 fffff801`14811f05 : 000000e2`65bff770 00000000`00000001 00000000`00000001 ffffbf89`00000000 : HyperHideDrv!HookedNtContinue+0x1b1 [C:\Users\pc\Desktop\vt-debuuger-main\HyperHideDrv\HookedFunctions.cpp @ 1540] ffffdf81`5547db00 00007ff9`79badd54 : 00007ff9`79b85c28 000000e2`65bff770 00000000`00000000 00000000`00000000 : nt!KiSystemServiceCopyEnd+0x25 000000e2`65bff718 00007ff9`79b85c28 : 000000e2`65bff770 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!NtContinue+0x14 000000e2`65bff720 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!LdrInitializeThunk+0x18 FAULTING_SOURCE_LINE: C:\Users\pc\Desktop\vt-debuuger-main\HyperHideDrv\HookedFunctions.cpp FAULTING_SOURCE_FILE: C:\Users\pc\Desktop\vt-debuuger-main\HyperHideDrv\HookedFunctions.cpp FAULTING_SOURCE_LINE_NUMBER: 1540 FAULTING_SOURCE_CODE: 1536: } 1537: } 1538: 1539: return OriginalNtContinue(Context, TestAlert); > 1540: } 1541: 1542: NTSTATUS(NTAPI* OriginalNtQueryInformationJobObject)(HANDLE JobHandle, JOBOBJECTINFOCLASS JobInformationClass, PVOID JobInformation, ULONG JobInformationLength, PULONG ReturnLength); 1543: NTSTATUS NTAPI HookedNtQueryInformationJobObject(HANDLE JobHandle, JOBOBJECTINFOCLASS JobInformationClass, PVOID JobInformation, ULONG JobInformationLength, PULONG ReturnLength) 1544: { 1545: NTSTATUS Status = OriginalNtQueryInformationJobObject(JobHandle, JobInformationClass, JobInformation, JobInformationLength, ReturnLength); SYMBOL_NAME: HyperHideDrv!HookedNtContinue+1b1 MODULE_NAME: HyperHideDrv IMAGE_NAME: HyperHideDrv.sys STACK_COMMAND: .cxr 0xffffdf815547d070 ; kb BUCKET_ID_FUNC_OFFSET: 1b1 FAILURE_BUCKET_ID: 0x3B_C000001D_HyperHideDrv!HookedNtContinue OS_VERSION: 10.0.19041.1 BUILDLAB_STR: vb_release OSPLATFORM_TYPE: x64 OSNAME: Windows 10 FAILURE_ID_HASH: {8e106373-5690-bf65-5b28-0541e087c782} Followup: MachineOwner ---------
最新发布
08-08
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值