VirtualQueryEx

VirtualQueryEx

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;

}

相關詞條

相關搜尋

熱門詞條

聯絡我們