期待的效果就像 PCHuntor 里的那樣,如下:
上代碼
#include "stdafx.h"
#include <Windows.h>
#include <vector>
#include <iostream>
#include <assert.h>
#include <psapi.h>
#include <tlhelp32.h>
using namespace std;
/*枚舉指定進程所有內存塊
assert(hProcess != nullptr);
參數:
hProcess: 要枚舉的進程,需擁有PROCESS_QUERY_INFORMATION權限
memories: 返回枚舉到的內存塊數組
返回:
成功返回true,失敗返回false.
*/
static bool EnumAllMemoryBlocks(HANDLE hProcess, OUT vector<MEMORY_BASIC_INFORMATION>& memories){
// 如果 hProcess 為空則結束運行
assert(hProcess != nullptr);
// 初始化 vector 容量
memories.clear();
memories.reserve(200);
// 獲取 PageSize 和地址粒度
SYSTEM_INFO sysInfo = { 0 };
GetSystemInfo(&sysInfo);
/*
typedef struct _SYSTEM_INFO {
union {
DWORD dwOemId; // 兼容性保留
struct {
WORD wProcessorArchitecture; // 操作系統處理器體系結構
WORD wReserved; // 保留
} DUMMYSTRUCTNAME;
} DUMMYUNIONNAME;
DWORD dwPageSize; // 頁面大小和頁面保護和承諾的粒度
LPVOID lpMinimumApplicationAddress; // 指向應用程序和dll可訪問的最低內存地址的指針
LPVOID lpMaximumApplicationAddress; // 指向應用程序和dll可訪問的最高內存地址的指針
DWORD_PTR dwActiveProcessorMask; // 處理器掩碼
DWORD dwNumberOfProcessors; // 當前組中邏輯處理器的數量
DWORD dwProcessorType; // 處理器類型,兼容性保留
DWORD dwAllocationGranularity; // 虛擬內存的起始地址的粒度
WORD wProcessorLevel; // 處理器級別
WORD wProcessorRevision; // 處理器修訂
} SYSTEM_INFO, *LPSYSTEM_INFO;
*/
//遍歷內存
const char* p = (const char*)sysInfo.lpMinimumApplicationAddress;
MEMORY_BASIC_INFORMATION memInfo = { 0 };
while (p < sysInfo.lpMaximumApplicationAddress){
// 獲取進程虛擬內存塊緩沖區字節數
size_t size = VirtualQueryEx(
hProcess, // 進程句柄
p, // 要查詢內存塊的基地址指針
&memInfo, // 接收內存塊信息的 MEMORY_BASIC_INFORMATION 對象
sizeof(MEMORY_BASIC_INFORMATION32) // 緩沖區大小
);
if (size != sizeof(MEMORY_BASIC_INFORMATION32)){break;}
// 將內存塊信息追加到 vector 數組尾部
memories.push_back(memInfo);
// 移動指針
p += memInfo.RegionSize;
}
return memories.size() > 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); // 進程快照句柄
PROCESSENTRY32 process = {sizeof(PROCESSENTRY32)}; // 接收進程信息的對象
vector<MEMORY_BASIC_INFORMATION> vec; // 存放進程內存塊的數組
/*
typedef struct _MEMORY_BASIC_INFORMATION {
PVOID BaseAddress; // 內存塊基地址指針
PVOID AllocationBase; // VirtualAlloc 函數分配的基地址指針
DWORD AllocationProtect; // 內存塊初始內存保護屬性
SIZE_T RegionSize; // 內存塊大小
DWORD State; // 內存塊狀態(COMMIT、FREE、RESERVE)
DWORD Protect; // 內存塊當前內存保護屬性
DWORD Type; // 內存塊類型(IMAGE、MAPPED、PRIVATE)
} MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION;
*/
// 遍歷進程
while (Process32Next(hProcessSnap,&process)){
// 找到想要的進程
if(strcmp(process.szExeFile,"rundll32.exe") == 0){
// 獲取進程句柄
HANDLE h_rundll32 = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process.th32ProcessID);
if(!h_rundll32){cout << "OpenProcess failed." << endl;}
// 遍歷該進程的內存塊
if(EnumAllMemoryBlocks(h_rundll32,vec)){
for(int i=0;i<vec.size();i++){
// 輸出
cout << "BaseAddress:" << vec[i].BaseAddress << endl;
cout << "AllocationBase:" << vec[i].AllocationBase << endl;
cout << "AllocationProtect:" << vec[i].AllocationProtect << endl;
cout << "RegionSize:" << vec[i].RegionSize << endl;
cout << "State:" << vec[i].State << endl;
cout << "Protect:" << vec[i].Protect << endl;
cout << "Type:" << hex << vec[i].Type << endl;
cout << "----------------------------------" << endl;
}
}else{cout << "EnumAllMemoryBlocks failed." << endl;}
}
}
getchar();
return 0;
}
效果圖: