物理内存
最大物理内存
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结构
数组成员
kd> dt _MMPFN
nt!_MMPFN
+0x000 u1 : __unnamed
+0x004 PteAddress : Ptr32 _MMPTE
+0x008 u2 : __unnamed
+0x00c u3 : __unnamed
+0x010 OriginalPte : _MMPTE
+0x018 u4 : __unnamed
typedef struct _MMPFN
{
union
{
PFN_NUMBER Flink;
ULONG WsIndex;
PKEVENT Event;
NTSTATUS ReadStatus;
SINGLE_LIST_ENTRY NextStackPfn;
// HACK for ROSPFN
SWAPENTRY SwapEntry;
} u1;
PMMPTE PteAddress;
union
{
PFN_NUMBER Blink;
ULONG_PTR ShareCount;
} u2;
union
{
struct
{
USHORT ReferenceCount;
MMPFNENTRY e1;
};
struct
{
USHORT ReferenceCount;
USHORT ShortFlags;
} e2;
} u3;
union
{
MMPTE OriginalPte;
LONG AweReferenceCount;
// HACK for ROSPFN
PMM_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;
u3.e1.PageLocation 这个成员标识了当前物理页空闲状态(空闲:使用中,两大类)
0:MmZeroedPageListHead //零化
1:MmFreePageListHead //空闲
2:MmStandbyPageListHead //备用
3:MmModifiedPageListHead //
4:MmModifiedNoWritePageListHead//
5:MmBadPageListHead //损坏
操作系统的6个循环链表
5:MmBadPageListHead
坏链(把所有损坏的物理页串到一起)
0:MmZeroedPageListHead
零化链表(是系统在空闲的时候进行零化的,不是程序自己清零的那种)
1:MmFreePageListHead
空闲链表(物理页是周转使用的,刚被释放的物理页是没有清0,系统空闲的时候有专门的线程从这个队列摘取物理页,加以清0后再挂入MmZeroedPageListHead)
2:MmStandbyPageListHead
备用链表(当系统内存不够的时候,操作系统会把物理内存中的数据交换到硬盘上,此时页面不是直接挂到空闲链表上去,而是挂到备用链表上,虽然我释放了,但里边的内容还是有意义的)
MMPFNLIST MmZeroedPageListHead = {0, ZeroedPageList, LIST_HEAD, LIST_HEAD};
MMPFNLIST MmFreePageListHead = {0, FreePageList, LIST_HEAD, LIST_HEAD};
MMPFNLIST MmStandbyPageListHead = {0, StandbyPageList, LIST_HEAD, LIST_HEAD};
MMPFNLIST MmStandbyPageListByPriority[8];
MMPFNLIST MmModifiedPageListHead = {0, ModifiedPageList, LIST_HEAD, LIST_HEAD};
MMPFNLIST MmModifiedPageListByColor[1] = {{0, ModifiedPageList, LIST_HEAD, LIST_HEAD}};
MMPFNLIST MmModifiedNoWritePageListHead = {0, ModifiedNoWritePageList, LIST_HEAD, LIST_HEAD};
MMPFNLIST MmBadPageListHead = {0, BadPageList, LIST_HEAD, LIST_HEAD};
MMPFNLIST MmRomPageListHead = {0, StandbyPageList, LIST_HEAD, LIST_HEAD};
以上链表的LIST_HEAD就是它的索引,成员3上一个节点 成员4下一个节点
下面来遍历一下零化链表
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
最大的物理页大小