C/C++ 遍歷程序記憶體塊
阿新 • • 發佈:2021-07-16
期待的效果就像 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; }
效果圖:
文章出處:https://www.cnblogs.com/lyshark許可協議: 文章中的程式碼均為學習時整理的筆記,部落格中除去明確標註有參考文獻的文章,其他文章【均為原創】作品,轉載請務必【添加出處】,您添加出處是我創作的動力!
防惡意轉載:如果發現您在轉載時,沒有新增本人部落格連結,本人將通過爬蟲批量爬取您部落格中所有內容,打上本人原創版權水印,並進行二次發行,請相互尊重,你尊重我的勞動成果,我才會尊重你。