承接前兩篇對 XP 使用者模式 4GB 虛擬位址空間的整體架構與堆疊分析,本文將實際動手撰寫程式,列舉目前行程載入的所有模組(EXE、DLL),並查詢它們在虛擬記憶體中的確切位置與大小,進一步驗證理論與實際的對應關係。
要取得行程中所有模組的資訊,主要依賴 PSAPI(Process Status Helper)提供的兩個函數:
EnumProcessModules:列舉指定行程載入的所有模組控制代碼(HMODULE)。GetModuleInformation:依模組控制代碼取得 MODULEINFO 結構,包含基址(lpBaseOfDll)、大小(SizeOfImage)、進入點(EntryPoint)。#include
#include
#include
#include
#pragma comment(lib, "psapi.lib")
int main() {
HANDLE hProcess = GetCurrentProcess();
HMODULE hMods[1024];
DWORD cbNeeded;
if (EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) {
int nModCount = cbNeeded / sizeof(HMODULE);
for (int i = 0; i < nModCount; i++) {
TCHAR szModName[MAX_PATH];
MODULEINFO mi = {0};
GetModuleFileNameEx(hProcess, hMods[i], szModName, MAX_PATH);
GetModuleInformation(hProcess, hMods[i], &mi, sizeof(mi));
_tprintf(TEXT("%-40s Base: 0x%08X Size: 0x%08X Entry: 0x%08X\n"),
szModName, (DWORD)mi.lpBaseOfDll, mi.SizeOfImage, (DWORD)mi.EntryPoint);
}
}
return 0;
}
執行上述程式,可獲得類似下表的輸出(節選關鍵模組):
| 模組名稱 | 基址 (lpBaseOfDll) | 大小 (SizeOfImage) | 進入點 (EntryPoint) |
|---|---|---|---|
| TestApp.exe | 0x00400000 | 0x0000F000 | 0x00401000 |
| ntdll.dll | 0x7C900000 | 0x000B0000 | 0x7C901000 |
| kernel32.dll | 0x7C800000 | 0x000F6000 | 0x7C801000 |
| user32.dll | 0x7E410000 | 0x00091000 | 0x7E411000 |
| gdi32.dll | 0x77F10000 | 0x0004B000 | 0x77F11000 |
| advapi32.dll | 0x77DD0000 | 0x0009A000 | 0x77DD1000 |
| msvcrt.dll | 0x77C10000 | 0x00058000 | 0x77C11000 |
| shell32.dll | 0x7C9C0000 | 0x0081A000 | 0x7C9C1000 |
| comctl32.dll (v6) | 0x773D0000 | 0x00105000 | 0x773D1000 |
/DYNAMICBASE(ASLR),預設映像基址即為 0x00400000,這與「使用者模式分區從 0x00010000 開始」一致。SizeOfImage 反映 PE 檔案標頭中 SizeOfImage 欄位,已包含所有區段(.text、.data、.rdata 等)並對齊到區塊(通常 4KB 或 64KB)。EntryPoint = 基址 + AddressOfEntryPoint(PE Optional Header 中指定),通常指向 CRT 啟動程式碼而非 main/WinMain。拿到 lpBaseOfDll 後,即可像剖析檔案一樣解析記憶體中的 PE 結構:
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)mi.lpBaseOfDll;
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)((BYTE*)pDos + pDos->e_lfanew);
// 接著可遍歷 Section Header、Import Table、Export Table、Relocation Table 等
這是逆向工程、Hook 技術、熱修補、記憶體掃描等進階技術的基礎。
透過 EnumProcessModules + GetModuleInformation,我們能快速繪製行程的「模組地圖」,直觀驗證 XP 使用者模式記憶體佈局:EXE 佔據低址,系統 DLL 聚集高址,中間留給堆積、堆疊、動態配置區域。掌握這套查詢技巧,是深入理解 Windows 記憶體管理、進行除錯與安全分析的敲門磚。