chapt14、探索虚拟内存

探索windows的内存管理和进程的虚拟地址空间

获取系统信息--System Info
VOID GetSystemInfo(LPSYSTEM_INFO psinf);
typedef struct _SYSTEM_INFO {
   union {
      DWORD dwOemId;   // Obsolete, do not use
      struct {
         WORD wProcessorArchitecture;
         WORD wReserved;
      };
   };
   DWORD     dwPageSize; // 页面大小
   LPVOID    lpMinimumApplicationAddress; // 最小可用地址
   LPVOID    lpMaximumApplicationAddress; // 最大可用地址
   DWORD_PTR dwActiveProcessorMask;
   DWORD     dwNumberOfProcessors; // 处理器个数
   DWORD     dwProcessorType;
   DWORD     dwAllocationGranularity; // CPU内存分配粒度
   WORD      wProcessorLevel;
   WORD      wProcessorRevision;
} SYSTEM_INFO, *LPSYSTEM_INFO;

虚拟内存状态--Virtual Memory Status
VOID GlobalMemoryStatus(LPMEMORYSTATUS pmst);
typedef struct _MEMORYSTATUS {
   DWORD dwLength; // 结构体大小
   DWORD dwMemoryLoad; // 内存使用率
   SIZE_T dwTotalPhys; // RAM大小
   SIZE_T dwAvailPhys; // 可用RAM
   SIZE_T dwTotalPageFile; // PageFile大小
   SIZE_T dwAvailPageFile; // 可用PageFile大小
   SIZE_T dwTotalVirtual; // 总地址空间
   SIZE_T dwAvailVirtual; // 可用地址空间
} MEMORYSTATUS, *LPMEMORYSTATUS;


检测某地址的状态--Determining the State of an Address Space
VirtualAlloc VirtualQuery MEMORY_BASIC_INFORMATION

VirtualAlloc:虚拟内存保留和申请。
VirtualQuery:查询虚拟内存信息
MEMORY_BASIC_INFORMATION:内存基本信息结构体
在32位操作系统里,一个进程有4GB的地址空间,但应用程序一般只用2GB,高位的2GB被系统内核占用了。
虚拟内存一般有3种状态:就是MEMORY_BASIC_INFORMATION的State表示的状态
MEM_COMMIT:提交状态,表示已经占用物理存储的pages(占用了内存或硬盘文件)
MEM_FREE:自由状态,进程不可访问但是可用VirtualAlloc分配
MEM_RESERVE:保留状态,地址空间保留但没有物理存储空间对应,VirtuallAlloc不能分配了,但是可以提交。
而处于COMMIT状态的,一般又分3种
MEM_IMAGE:镜像,这些pages对应了可执行文件(一般就是dll,exe)。
MEM_MAPPED:映射,这些pages对应了其他文件(如map了的文件)
MEM_PRIVATE:私有,这个pages是私有的,不被其他进程共享。相应的,有些shared的,这个信息可以通过QueryWorkingSet获取

// 获取一系列pages的信息
SIZE_T WINAPI VirtualQuery(
  _In_opt_  LPCVOID lpAddress,
  _Out_     PMEMORY_BASIC_INFORMATION lpBuffer,
  _In_      SIZE_T dwLength
);
说明:WirtualQuery返回一系列连续pages的基本信息,这些pages起始于同一个地址并具有如下共同的属性:
-这些pages的状态一致(MEM_COMMIT, MEM_RESERVE, MEM_FREE, MEM_PRIVATE, MEM_MAPPED, or MEM_IMAGE).
-如果其实page不是MEM_FREE的,则所有的pages都属于同一次系统调用,如:VirtualAlloc, MapViewOfFile等。即它们具有相同的AllocationBase
-这些pages的访问属性相同(PAGE_READONLY, PAGE_READWRITE, PAGE_NOACCESS, PAGE_WRITECOPY, PAGE_EXECUTE, PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE, PAGE_EXECUTE_WRITECOPY, PAGE_GUARD, or PAGE_NOCACHE).
一次系统调用申请的空间即具有同一个AllocationBase的空间,可能由若干个符合以上特性的region组成。
在《Windows核心编程》第四版里,把这样的一个region称作一个Block,若干具有同一个AllocationBase的blocks被称作一个Region。

typedef struct _MEMORY_BASIC_INFORMATION {
  PVOID  BaseAddress;
  PVOID  AllocationBase;
  DWORD  AllocationProtect;
  SIZE_T RegionSize;
  DWORD  State;
  DWORD  Protect;
  DWORD  Type;
} MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION;
BaseAddress:调用VirtualQuery时所传入的address对于pages大小向下取整,是page size的倍数。
AllocationBase:调用VirtualAlloc是所分配的基础地址。
AllocationProtect:刚分配时所具有的保护属性。
RegionSize:以BaseAddress为起始地址的区域大小。
State:区域内pages的状态,MEM_COMMIT、MEM_FREE、MEM_RESERVE
Protect:区域内pages的访问属性,取值范围同AllocationProtect
Type:区域内pages的物理存储类型,MEM_IMAGE、MEM_MAPPED、MEM_PRIVATE。

原文地址:https://www.cnblogs.com/xkxjy/p/3672262.html