2.物理内存的管理
物理內(nèi)存
最大物理內(nèi)存
10-10-12分頁(yè) 最多識(shí)別物理內(nèi)存為4GB 2-9-9-12分頁(yè) 最多識(shí)別物理內(nèi)存為64GB操作系統(tǒng)的 _ExVerifySuite() 函數(shù)限制了它無(wú)法超越4GB(網(wǎng)上有補(bǔ)丁可以突破4GB)實(shí)際物理內(nèi)存
MmNumberOfPhysicalPages * 4 = 物理內(nèi)存
一共有7FF6C個(gè)物理頁(yè),乘4后得到的就是 KB。
物理內(nèi)存管理
全局?jǐn)?shù)組
數(shù)組指針:_MMPFN* MmPfnDatabase 數(shù)組長(zhǎng)度:MmNumberOfPhysicalPages(上面已經(jīng)演示過(guò)了)
80c86000 ~ (80c86000+0x18)描述的就是第一個(gè)物理頁(yè)的信息,
80c8601C ~ (80c86000+0x18)描述的就是第二個(gè)物理頁(yè)的信息,以此類推…
如果我們想找0x8000物理地址對(duì)應(yīng)的物理頁(yè),用0x8000除0x1000(一頁(yè)1000h),得到的就是索引,
80c86000+1c*索引 == 這個(gè)物理頁(yè)對(duì)應(yīng)的_MMPFN結(jié)構(gòu)
數(shù)組成員(PFN數(shù)據(jù)庫(kù))
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;//該頁(yè)面在進(jìn)程工作集鏈表中的索引PKEVENT Event;NTSTATUS ReadStatus;SINGLE_LIST_ENTRY NextStackPfn;// HACK for ROSPFNSWAPENTRY SwapEntry;} u1;PMMPTE PteAddress;//執(zhí)行此頁(yè)面的PTE的虛擬地址union{PFN_NUMBER Blink;ULONG_PTR ShareCount;//指向該頁(yè)面的PTE數(shù)量} u2;union{struct{USHORT ReferenceCount;//代表這個(gè)頁(yè)面必須要保留在內(nèi)存中的引用計(jì)數(shù)MMPFNENTRY e1;};struct{USHORT ReferenceCount;USHORT ShortFlags;} e2;} u3;union{MMPTE OriginalPte;//包含了指向此頁(yè)面的PTE的原始內(nèi)容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;//指向該頁(yè)面的PTE所在的頁(yè)表頁(yè)面的物理頁(yè)幀編號(hào),以及一些標(biāo)志位u3.e1.PageLocation 這個(gè)成員標(biāo)識(shí)了當(dāng)前物理頁(yè)空閑狀態(tài)(空閑:使用中,兩大類) 0:MmZeroedPageListHead //零化 1:MmFreePageListHead //空閑 2:MmStandbyPageListHead //備用 3:MmModifiedPageListHead //修改 OriginalPte.u.Soft.Prototype=1 或者 外存都會(huì)在這 4:MmModifiedNoWritePageListHead//已修改但不寫出 5:MmBadPageListHead //損壞操作系統(tǒng)的6個(gè)循環(huán)鏈表
5:MmBadPageListHead
壞鏈(把所有損壞的物理頁(yè)串到一起)
0:MmZeroedPageListHead
零化鏈表(是系統(tǒng)在空閑的時(shí)候進(jìn)行零化的,不是程序自己清零的那種)
1:MmFreePageListHead
空閑鏈表(物理頁(yè)是周轉(zhuǎn)使用的,剛被釋放的物理頁(yè)是沒(méi)有清0,系統(tǒng)空閑的時(shí)候有專門的線程從這個(gè)隊(duì)列摘取物理頁(yè),加以清0后再掛入MmZeroedPageListHead)
2:MmStandbyPageListHead
備用鏈表(當(dāng)系統(tǒng)內(nèi)存不夠的時(shí)候,操作系統(tǒng)會(huì)把物理內(nèi)存中的數(shù)據(jù)交換到硬盤上,此時(shí)頁(yè)面不是直接掛到空閑鏈表上去,而是掛到備用鏈表上,雖然我釋放了,但里邊的內(nèi)容還是有意義的)
3:MmModifiedPageListHead
以修改狀態(tài)。類似于備用鏈表,已經(jīng)從原來(lái)的工作集中移除,但是,頁(yè)面包含的內(nèi)容已經(jīng)被修改過(guò),原來(lái)工作集的PTE,仍然指向物理頁(yè)面,但已被標(biāo)記成正在轉(zhuǎn)移無(wú)效的PTE。
如果系統(tǒng)要把這個(gè)頁(yè)面回收給別人用,必須將其中的內(nèi)容寫到磁盤上
4:MmModifiedNoWritePageListHead
已修改但不寫出。類似于以修改狀態(tài),但區(qū)別在于,內(nèi)存管理器不會(huì)將它的內(nèi)容寫到磁盤上
下面來(lái)遍歷一下零化鏈表
EPROCESS.+0x1f8 Vm 結(jié)構(gòu)如下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 這個(gè)成員可以找到這個(gè)進(jìn)程使用的所有物理頁(yè)+0x018 MinimumWorkingSetSize 最小的物理頁(yè)大小+0x01c MaximumWorkingSetSize 最大的物理頁(yè)大小總結(jié)