C++實現(xiàn)支持32位和64位進(jìn)程的模塊枚舉
使用 Visual Studio 2022 (VC++ 2022) 創(chuàng)建 MFC 對話框應(yīng)用程序
支持查找 32位和64位進(jìn)程(使用 TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32 同時枚舉兩種模塊)
輸入進(jìn)程名稱(例如 notepad.exe),點擊“查找進(jìn)程”按鈕
在列表控件(ListCtrl)中顯示該進(jìn)程的所有模塊名稱、基址、大小、路徑
1. 資源部分(在資源編輯器中添加控件)
在對話框資源(ID 為 IDD_GETMODULEBASE_DIALOG)中添加以下控件:
| 類型 | ID | Caption | 其他屬性 |
|---|---|---|---|
| Edit Control | IDC_EDIT_PROCESS | (空) | |
| Button | IDC_BTN_SEARCH | 查找進(jìn)程 | |
| List Control | IDC_LIST_MODULES | (空) | View: Report, 加四列(見代碼) |
| Static | IDC_STATIC_TIP | 輸入進(jìn)程名(如 notepad.exe) |
2. GetModuleBaseDlg.h
#pragma once
#include <tlhelp32.h>
#include <afxwin.h>
#include <afxcmn.h>
class CGetModuleBaseDlg : public CDialogEx
{
public:
CGetModuleBaseDlg(CWnd* pParent = nullptr);
enum { IDD = IDD_GETMODULEBASE_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX);
virtual BOOL OnInitDialog();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedBtnSearch();
private:
DWORD GetProcessIDByName(LPCTSTR lpProcessName);
BOOL GetAllModules(DWORD dwPID, CListCtrl& listCtrl);
CEdit m_editProcess;
CButton m_btnSearch;
CListCtrl m_listModules;
};
3. GetModuleBaseDlg.cpp
#include "pch.h"
#include "GetModuleBase.h"
#include "GetModuleBaseDlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
CGetModuleBaseDlg::CGetModuleBaseDlg(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_GETMODULEBASE_DIALOG, pParent)
{
}
void CGetModuleBaseDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_EDIT_PROCESS, m_editProcess);
DDX_Control(pDX, IDC_BTN_SEARCH, m_btnSearch);
DDX_Control(pDX, IDC_LIST_MODULES, m_listModules);
}
BEGIN_MESSAGE_MAP(CGetModuleBaseDlg, CDialogEx)
ON_BN_CLICKED(IDC_BTN_SEARCH, &CGetModuleBaseDlg::OnBnClickedBtnSearch)
END_MESSAGE_MAP()
BOOL CGetModuleBaseDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 設(shè)置列表控件為報告視圖并添加列
m_listModules.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
m_listModules.InsertColumn(0, _T("模塊名稱"), LVCFMT_LEFT, 150);
m_listModules.InsertColumn(1, _T("基址"), LVCFMT_LEFT, 120);
m_listModules.InsertColumn(2, _T("大小"), LVCFMT_LEFT, 100);
m_listModules.InsertColumn(3, _T("路徑"), LVCFMT_LEFT, 400);
return TRUE;
}
// 根據(jù)進(jìn)程名獲取 PID(支持大小寫不敏感)
DWORD CGetModuleBaseDlg::GetProcessIDByName(LPCTSTR lpProcessName)
{
DWORD dwPID = 0;
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE)
return 0;
PROCESSENTRY32 pe32 = { sizeof(pe32) };
if (Process32First(hSnapshot, &pe32))
{
do
{
if (_tcsicmp(pe32.szExeFile, lpProcessName) == 0) // 不區(qū)分大小寫
{
dwPID = pe32.th32ProcessID;
break;
}
} while (Process32Next(hSnapshot, &pe32));
}
CloseHandle(hSnapshot);
return dwPID;
}
// 枚舉指定進(jìn)程的所有模塊(同時支持 32/64 位模塊)
BOOL CGetModuleBaseDlg::GetAllModules(DWORD dwPID, CListCtrl& listCtrl)
{
listCtrl.DeleteAllItems();
// 同時使用 TH32CS_SNAPMODULE 和 TH32CS_SNAPMODULE32 可兼容 WOW64 進(jìn)程的 32 位模塊
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, dwPID);
if (hSnapshot == INVALID_HANDLE_VALUE)
return FALSE;
MODULEENTRY32 me32 = { sizeof(me32) };
if (Module32First(hSnapshot, &me32))
{
int nItem = 0;
do
{
CString strBase, strSize;
strBase.Format(_T("0x%016I64X"), (ULONGLONG)me32.modBaseAddr);
strSize.Format(_T("0x%08X"), me32.modBaseSize);
listCtrl.InsertItem(nItem, me32.szModule);
listCtrl.SetItemText(nItem, 1, strBase);
listCtrl.SetItemText(nItem, 2, strSize);
listCtrl.SetItemText(nItem, 3, me32.szExePath);
nItem++;
} while (Module32Next(hSnapshot, &me32));
}
CloseHandle(hSnapshot);
return TRUE;
}
void CGetModuleBaseDlg::OnBnClickedBtnSearch()
{
CString strProcessName;
m_editProcess.GetWindowText(strProcessName);
strProcessName.Trim();
if (strProcessName.IsEmpty())
{
AfxMessageBox(_T("請輸入進(jìn)程名稱!"));
return;
}
DWORD dwPID = GetProcessIDByName(strProcessName);
if (dwPID == 0)
{
AfxMessageBox(_T("未找到指定進(jìn)程!請確認(rèn)進(jìn)程名稱正確(包含.exe),且進(jìn)程正在運行。"));
m_listModules.DeleteAllItems();
return;
}
CString strTitle;
strTitle.Format(_T("進(jìn)程 %s (PID: %u) 的模塊列表"), strProcessName, dwPID);
SetWindowText(strTitle);
if (!GetAllModules(dwPID, m_listModules))
{
AfxMessageBox(_T("枚舉模塊失敗,可能沒有足夠權(quán)限。"));
m_listModules.DeleteAllItems();
}
}
4. 項目配置(VS2022)
項目使用 Unicode 字符集。
使用 MFC:項目屬性 → 常規(guī) → 使用 MFC → “在共享 DLL 中使用 MFC” 或 “在靜態(tài)庫中使用 MFC”。

5.使用方法
- 運行程序
- 在編輯框輸入進(jìn)程可執(zhí)行文件名,例如:
notepad.exe、chrome.exe - 點擊“查找進(jìn)程”
- 列表中會顯示該進(jìn)程加載的所有模塊(包括主模塊和 DLL)
這樣就完整實現(xiàn)了你要求的功能,支持 32 位和 64 位進(jìn)程的模塊枚舉。

到此這篇關(guān)于C++實現(xiàn)支持32位和64位進(jìn)程的模塊枚舉的文章就介紹到這了,更多相關(guān)C++模塊枚舉內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++實現(xiàn)旋轉(zhuǎn)數(shù)組的二分查找
這篇文章主要介紹了C++實現(xiàn)旋轉(zhuǎn)數(shù)組的二分查找方法,涉及數(shù)組的操作,有值得借鑒的技巧,需要的朋友可以參考下2014-09-09
C語言FlappyBird飛揚的小鳥實現(xiàn)開發(fā)流程
因為在家宅了好多天,隨手玩了下自己以前做的一些小游戲,說真的,有幾個游戲做的是真的劣質(zhì),譬如 flappybird 真的讓我難以忍受,于是重做了一波分享給大家2022-11-11
C++實現(xiàn)LeetCode(173.二叉搜索樹迭代器)
這篇文章主要介紹了C++實現(xiàn)LeetCode(173.二叉搜索樹迭代器),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08
C++?RAII在HotSpot?VM中的重要應(yīng)用解析
RAII技術(shù)被認(rèn)為是C++中管理資源的最佳方法,進(jìn)一步引申,使用RAII技術(shù)也可以實現(xiàn)安全、簡潔的狀態(tài)管理,編寫出優(yōu)雅的異常安全的代碼,這篇文章主要介紹了C++?RAII在HotSpot?VM中的重要應(yīng)用,需要的朋友可以參考下2023-09-09

