先來了解一些概念:
區域,塊,頁面。
使用者位址空間劃分為不同的區域,然後區域劃分為不同的塊,塊由頁面組成。(如果區域是mem_free,則不存在塊的概念)
區域中的塊是該區域內連續的頁面,並且具有相同的保護屬性以及以相同型別的物理儲存器作為後備儲存器。
dword virtualqueryex
(handle hprocess,
lpcvoid pvaddress,
pmemory_basic_information pmbi,
dowrd dwlength
);
要想正確使用該函式,對mem_basic_information的準確理解不可少。
typedef struct _memory_basic_information
memory_basic_information, *pmemory_basic_information;
有了這個函式,我們只需要從0開始呼叫這個函式,然後累加位址重複呼叫這個函式即可。
本來使用者位址空間可以看做,區域,塊,頁面**去理解。但是這裡面mem_free狀態的區域是乙個異類,沒有塊的概念。因此我這做一些特殊處理,將mem_free也看做有塊的概念,裡面只有乙個塊。這樣能保證區域,塊和頁面的層級關係。
為了便於除錯,我們為頁面的狀態(state),保護屬性(protect),型別(type)定義三個列舉:
enum class pagestate
;enum class pagetype
;enum class pageprotect
;
然後我們需要定義個結構體,表示塊資訊:
struct memblkinfo
;
bool vmqueryblks
(handle hprocess, /* i: 程序控制代碼 */
lpcvoid pvblkbaseaddress, /* i: 塊起始位址(需要呼叫者保證為塊起始位址,該函式沒有做校驗,如果不是塊起始位址,資訊可能會錯誤)*/
memblkinfo& zblkinfo /* o: 塊資訊 */);
memory_basic_information mbi{};
if (!(virtualqueryex(hprocess, pvblkbaseaddress, &mbi, sizeof(mbi)) == sizeof(mbi)))
return false;
zblkinfo.preginallocationbase = mbi.allocationbase;
zblkinfo.allocationprotect = static_cast(mbi.allocationprotect);
zblkinfo.dwsize = mbi.regionsize;
zblkinfo.state = static_cast(mbi.state);
zblkinfo.protect = static_cast(mbi.protect);
zblkinfo.blktype = static_cast(mbi.type);
//當當前頁狀態為free時候需要特殊處理
if (zblkinfo.state == pagestate::free)
return true;
}
bool vmqueryreginblkinfos
(handle hprocess, /* i: 程序控制代碼 */
lpcvoid pvregionaddr, /* i: 區域基位址 */
std::vector& vecblkinfo /* o: 塊資訊 */);
if (!(vmqueryblks(hprocess, pvblkbaseaddr, blkinfo)))
return false;
//如果當前塊的基位址與區域的基位址不相同,表明當前塊不屬於當前區域
if (blkinfo.preginallocationbase != pvregionaddr)
break;
pvblkbaseaddr = (pvoid)((pbyte)pvblkbaseaddr + blkinfo.dwsize);
vecblkinfo.push_back(blkinfo);
}return (true);
}
然後我們獲取區域資訊,我們首先定義乙個表示區域的結構體:
struct vmregion
;
然後我們寫乙個函式完成獲取區域的資訊
bool vmqueryregion
(handle hprocess,
lpcvoid pvaddress, /* i: 區域基位址 */
vmregion* pvmregion
)//嘗試獲取區域關聯的檔案資訊
; return true;
pvmregion->wstrdisp = pszfilename;
static bool bloadlogicdosdevicemap = false;
static std::mapmaplogicdosdevicemap;
if (!bloadlogicdosdevicemap)
for (auto& pair : maplogicdosdevicemap)
}}return true;
}
這裡面有個函式getlogicdosdevicemap,該函式是獲取裝置卷名和碟符名的對應關係:
bool getlogicdosdevicemap
(std::map& mapdosdevicelogicdrive
) // go to the next null character.
while (*p++);
} while (*p); // end of string
}return true;
}
bool getregioninfos(dword processid, std::vector& vecregion)
; bok = vmqueryregion(hprocess, pvaddress, &zvmregion);
pvaddress = ((pbyte)zvmregion.pvrgnbaseaddress + zvmregion.dwreginsize);
vecregion.push_back(zvmregion);
}return true;
}
虛擬記憶體應用
虛擬記憶體的重要性體現在下面幾個方面 1 虛擬記憶體可以對映到硬碟,以達到擴充套件記憶體的作用,這樣系統在物理記憶體已經用滿的情況下,就不會因為沒有記憶體可用,而導致系統崩潰。2 虛擬記憶體是以程序空間為定址空間的,一般情況,程序使用者模式下的定址空間 是2g,為了避免記憶體的碎片,可以把2g程序空...
虛擬記憶體(Virtual Memory)
虛擬記憶體 virtual memory 是windows管理所有可用記憶體的方式。對於32位windows系 統,每個程序所用到的虛擬記憶體位址從0到2 32 1,總容量4gb,其中2gb是與作業系統以 及其他所有程序所共享,另外2gb分派給程序獨佔 這就是常說的32位windows中乙個進 程最...
虛擬記憶體使用
虛擬記憶體使用一 簡介windows 提供了3 中進行記憶體管理的方法,包括 虛擬記憶體 一般用來管理大型資料結構,受到硬碟調頁檔案的支援 記憶體對映檔案 常用來管理大型資料流和多程序共享。記憶體堆 最適合用來管理大量的小物件。二 虛擬記憶體的使用 1 我們可以在程序的位址空間中保留乙個區域 pvo...