2.物理内存的管理
物理內存
最大物理內存
10-10-12分頁 最多識別物理內存為4GB 2-9-9-12分頁 最多識別物理內存為64GB操作系統的 _ExVerifySuite() 函數限制了它無法超越4GB(網上有補丁可以突破4GB)實際物理內存
MmNumberOfPhysicalPages * 4 = 物理內存
一共有7FF6C個物理頁,乘4后得到的就是 KB。
物理內存管理
全局數組
數組指針:_MMPFN* MmPfnDatabase 數組長度:MmNumberOfPhysicalPages(上面已經演示過了)
80c86000 ~ (80c86000+0x18)描述的就是第一個物理頁的信息,
80c8601C ~ (80c86000+0x18)描述的就是第二個物理頁的信息,以此類推…
如果我們想找0x8000物理地址對應的物理頁,用0x8000除0x1000(一頁1000h),得到的就是索引,
80c86000+1c*索引 == 這個物理頁對應的_MMPFN結構
數組成員(PFN數據庫)
kd> dt _MMPFN nt!_MMPFN+0x000 u1 : __unnamed+0x004 PteAddress : Ptr32 _MMPTE+0x008 u2 : __unnamed+0x00c u3 : __unnamed+0x010 OriginalPte : _MMPTE+0x018 u4 : __unnamedtypedef struct _MMPFN {union{PFN_NUMBER Flink;ULONG WsIndex;//該頁面在進程工作集鏈表中的索引PKEVENT Event;NTSTATUS ReadStatus;SINGLE_LIST_ENTRY NextStackPfn;// HACK for ROSPFNSWAPENTRY SwapEntry;} u1;PMMPTE PteAddress;//執行此頁面的PTE的虛擬地址union{PFN_NUMBER Blink;ULONG_PTR ShareCount;//指向該頁面的PTE數量} u2;union{struct{USHORT ReferenceCount;//代表這個頁面必須要保留在內存中的引用計數MMPFNENTRY e1;};struct{USHORT ReferenceCount;USHORT ShortFlags;} e2;} u3;union{MMPTE OriginalPte;//包含了指向此頁面的PTE的原始內容LONG AweReferenceCount;// HACK for ROSPFNPMM_RMAP_ENTRY RmapListHead;};union{ULONG_PTR EntireFrame;struct{ULONG_PTR PteFrame:25;ULONG_PTR InPageError:1;ULONG_PTR VerifierAllocation:1;ULONG_PTR AweAllocation:1;ULONG_PTR Priority:3;ULONG_PTR MustBeCached:1;};} u4;//指向該頁面的PTE所在的頁表頁面的物理頁幀編號,以及一些標志位u3.e1.PageLocation 這個成員標識了當前物理頁空閑狀態(空閑:使用中,兩大類) 0:MmZeroedPageListHead //零化 1:MmFreePageListHead //空閑 2:MmStandbyPageListHead //備用 3:MmModifiedPageListHead //修改 OriginalPte.u.Soft.Prototype=1 或者 外存都會在這 4:MmModifiedNoWritePageListHead//已修改但不寫出 5:MmBadPageListHead //損壞操作系統的6個循環鏈表
5:MmBadPageListHead
壞鏈(把所有損壞的物理頁串到一起)
0:MmZeroedPageListHead
零化鏈表(是系統在空閑的時候進行零化的,不是程序自己清零的那種)
1:MmFreePageListHead
空閑鏈表(物理頁是周轉使用的,剛被釋放的物理頁是沒有清0,系統空閑的時候有專門的線程從這個隊列摘取物理頁,加以清0后再掛入MmZeroedPageListHead)
2:MmStandbyPageListHead
備用鏈表(當系統內存不夠的時候,操作系統會把物理內存中的數據交換到硬盤上,此時頁面不是直接掛到空閑鏈表上去,而是掛到備用鏈表上,雖然我釋放了,但里邊的內容還是有意義的)
3:MmModifiedPageListHead
以修改狀態。類似于備用鏈表,已經從原來的工作集中移除,但是,頁面包含的內容已經被修改過,原來工作集的PTE,仍然指向物理頁面,但已被標記成正在轉移無效的PTE。
如果系統要把這個頁面回收給別人用,必須將其中的內容寫到磁盤上
4:MmModifiedNoWritePageListHead
已修改但不寫出。類似于以修改狀態,但區別在于,內存管理器不會將它的內容寫到磁盤上
下面來遍歷一下零化鏈表
EPROCESS.+0x1f8 Vm 結構如下nt!_MMSUPPORT+0x000 LastTrimTime : _LARGE_INTEGER+0x008 Flags : _MMSUPPORT_FLAGS+0x00c PageFaultCount : Uint4B+0x010 PeakWorkingSetSize : Uint4B+0x014 WorkingSetSize : Uint4B+0x018 MinimumWorkingSetSize : Uint4B+0x01c MaximumWorkingSetSize : Uint4B+0x020 VmWorkingSetList : Ptr32 _MMWSL+0x024 WorkingSetExpansionLinks : _LIST_ENTRY+0x02c Claim : Uint4B+0x030 NextEstimationSlot : Uint4B+0x034 NextAgingSlot : Uint4B+0x038 EstimatedAvailable : Uint4B+0x03c GrowthSinceLastEstimate : Uint4B+0x020 VmWorkingSetList 這個成員可以找到這個進程使用的所有物理頁+0x018 MinimumWorkingSetSize 最小的物理頁大小+0x01c MaximumWorkingSetSize 最大的物理頁大小總結