标题：VirtualQueryEx
函数原型
DWORD VirtualQueryEx( 
HANDLE hProcess,
LPCVOID lpAddress, 
PMEMORY_BASIC_INFORMATION lpBuffer, 
DWORD dwLength 
);
参数:
hProcess 进程句柄。
lpAddress 查询内存的地址。
lpBuffer 指向MEMORY_BASIC_INFORMATION结构的指针，用于接收内存信息。
dwLength MEMORY_BASIC_INFORMATION结构的大小。
返回值:
函数写入lpBuffer的字节数，如果不等于sizeof(MEMORY_BASIC_INFORMATION)表示失败。
备注
MEMORY_BASIC_INFORMATION在WinNT.h中定义如下:
typedef struct _MEMORY_BASIC_INFORMATION {
PVOID BaseAddress; // 区域基地址。
PVOID AllocationBase; // 分配基地址。
DWORD AllocationProtect; // 区域被初次保留时赋予的保护属性。
SIZE_T RegionSize; // 区域大小（以字节为计量单位）。
DWORD State; // 状态（MEM_FREE、MEM_RESERVE或 MEM_COMMIT）。
DWORD Protect; // 保护属性。
DWORD Type; // 类型。
} MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION; 
成员解释：
BaseAddress 与lpAddress参数的值相同，但是四舍五入为页面的边界值。
AllocationBase 指明用VirtualAlloc函数分配内存区域的基地址。lpAddress在该区域之内。
AllocationProtect 指明该地址空间区域被初次保留时赋予该区域的保护属性。
PAGE_READONLY 只读属性，如果试图进行写操作，将引发访问违规。如果系统区分只读、执行两种属性，那么试图在该区域执行代码也将引发访问违规。
PAGE_READWRITE 允许读写。
PAGE_EXECUTE 只允许执行代码，对该区域试图进行读写操作将引发访问违规。
PAGE_EXECUTE_READ 允许执行和读取。
PAGE_EXECUTE_READWRITE 允许读写和执行代码。
PAGE_EXECUTE_WRITECOPY 对于该地址空间的区域，不管执行什么操作，都不会引发访问违规。如果试图在该页面上的内存中进行写入操作，就会将它自己的私有页面（受页文件的支持）拷贝赋予该进程。
PAGE_GUARD 在页面上写入一个字节时使应用程序收到一个通知（通过一个异常条件）。该标志有一些非常巧妙的用法。Windows 2000在创建线程堆栈时使用该标志。
PAGE_NOACCESS 禁止一切访问。
PAGE_NOCACHE 停用已提交页面的高速缓存。一般情况下最好不要使用该标志，因为它主要是供需要处理内存缓冲区的硬件设备驱动程序的开发人员使用的。
RegionSize 用于指明内存块从基地址即BaseAddress开始的所有页面的大小（以字节为计量单位）这些页面与含有用LpAddress参数设定的地址的页面拥有相同的保护属性、状态和类型。
State 用于指明所有相邻页面的状态。
MEM_COMMIT 指明已分配物理内存或者系统页文件。
MEM_FREE 空闲状态。该区域的虚拟地址不受任何内存的支持。该地址空间没有被保留。该状态下AllocationBase、AllocationProtect、Protect和Type等成员均未定义。
MEM_RESERVE 指明页面被保留，但是没有分配任何物理内存。该状态下Protect成员未定。
Protect 用于指明所有相邻页面（内存块)的保护属性。这些页面与含有拥有相同的保属性、状态和类型。意义同AllocationProtect。
Type 用于指明支持所有相邻页面的物理存储器的类型（MEM_IMAGE，MEM_MAPPED或MEM_PRIVATE）。这些相邻页面拥有相同的保护属性、状态和类型。如果是Windows 98，那么这个成员将总是MEM_PRIVATE 。
MEM_IMAGE 指明该区域的虚拟地址原先受内存映射的映像文件（如.exe或DLL文件）的支持，但也许不再受映像文件的支持。例如，当写入模块映像中的全局变量时，“写入时拷贝”的机制将由页文件来支持特定的页面，而不是受原始映像文件的支持。
MEM_MAPPED 该区域的虚拟地址原先是受内存映射的数据文件的支持，但也许不再受数据文件的支持。例如，数据文件可以使用“写入时拷贝”的保护属性来映射。对文件的任何写入操作都将导致页文件而不是原始数据支持特定的页面。
MEM_PRIVATE 指明该内存区域是私有的。不被其他进程共享。
示例代码:
#include "stdafx.h"
#include <windows.h>
#include <TCHAR.H>
BOOL ShowProcMemInfo(DWORD dwPID);
int _tmain(int argc, char* argv[])
{
ShowProcMemInfo( GetCurrentProcessId() );
return 0;
}
// 显示一个进程的内存状态 dwPID为进程ID
BOOL ShowProcMemInfo(DWORD dwPID)
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,
FALSE,
dwPID);
if(hProcess == NULL)
return FALSE;
MEMORY_BASIC_INFORMATION mbi;
PBYTE pAddress = NULL;
TCHAR szInfo[200] = _T("BaseAddr Size Type State Protect \n");
_tprintf(szInfo);
while(TRUE)
{
if(VirtualQueryEx(hProcess, pAddress, &mbi, sizeof(mbi)) != sizeof(mbi))
{
break;
}
if((mbi.AllocationBase != mbi.BaseAddress) && (mbi.State != MEM_FREE))
{
_stprintf(szInfo, _T(" %08X %8dK "), 
mbi.BaseAddress,
mbi.RegionSize>>10);
}
else
{
_stprintf(szInfo, _T("%08X %8dK "), 
mbi.BaseAddress,
mbi.RegionSize>>10);
}
LPCTSTR pStr = _T("");
switch(mbi.Type)
{
case MEM_IMAGE: pStr = _T("MEM_IMAGE "); break;
case MEM_MAPPED: pStr = _T("MEM_MAPPED "); break;
case MEM_PRIVATE: pStr = _T("MEM_PRIVATE"); break;
default: pStr = _T("-----------"); break;
}
_tcscat(szInfo, pStr);
_tcscat(szInfo, _T(" "));
switch(mbi.State)
{
case MEM_COMMIT: pStr = _T("MEM_COMMIT "); break;
case MEM_RESERVE: pStr = _T("MEM_RESERVE"); break;
case MEM_FREE: pStr = _T("MEM_FREE "); break;
default: pStr = _T("-----------"); break;
}
_tcscat(szInfo, pStr);
_tcscat(szInfo, _T(" "));
switch(mbi.AllocationProtect)
{
case PAGE_READONLY: pStr = _T("PAGE_READONLY "); break; 
case PAGE_READWRITE: pStr = _T("PAGE_READWRITE "); break; 
case PAGE_WRITECOPY: pStr = _T("PAGE_WRITECOPY "); break; 
case PAGE_EXECUTE: pStr = _T("PAGE_EXECUTE "); break; 
case PAGE_EXECUTE_READ: pStr = _T("PAGE_EXECUTE_READ "); break; 
case PAGE_EXECUTE_READWRITE: pStr = _T("PAGE_EXECUTE_READWRITE"); break; 
case PAGE_EXECUTE_WRITECOPY: pStr = _T("PAGE_EXECUTE_WRITECOPY"); break; 
case PAGE_GUARD: pStr = _T("PAGE_GUARD "); break; 
case PAGE_NOACCESS: pStr = _T("PAGE_NOACCESS "); break; 
case PAGE_NOCACHE: pStr = _T("PAGE_NOCACHE "); break; 
default: pStr = _T("----------------------"); break;
}
_tcscat(szInfo, pStr);
_tcscat(szInfo, _T("\n"));
_tprintf(szInfo);
pAddress = ((PBYTE)mbi.BaseAddress + mbi.RegionSize);
}
CloseHandle(hProcess);
return TRUE;
}