期待的效果就像 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;
}效果图:

版权声明:本博客文章与代码均为学习时整理的笔记,文章 [均为原创] 作品,转载请 [添加出处] ,您添加出处是我创作的动力!










