C++实现支持32位和64位进程的模块枚举

 更新时间:2025年12月15日 08:39:59   作者:二分掌柜的  
这篇文章主要为大家详细介绍了如何使用C++实现支持32位和64位进程的模块枚举,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

使用 Visual Studio 2022 (VC++ 2022) 创建 MFC 对话框应用程序

支持查找 32位和64位进程(使用 TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32 同时枚举两种模块)

输入进程名称(例如 notepad.exe),点击“查找进程”按钮

在列表控件(ListCtrl)中显示该进程的所有模块名称、基址、大小、路径

1. 资源部分(在资源编辑器中添加控件)

在对话框资源(ID 为 IDD_GETMODULEBASE_DIALOG)中添加以下控件:

类型IDCaption其他属性
Edit ControlIDC_EDIT_PROCESS(空)
ButtonIDC_BTN_SEARCH查找进程
List ControlIDC_LIST_MODULES(空)View: Report, 加四列(见代码)
StaticIDC_STATIC_TIP输入进程名(如 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();

    // 设置列表控件为报告视图并添加列
    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;
}

// 根据进程名获取 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)  // 不区分大小写
            {
                dwPID = pe32.th32ProcessID;
                break;
            }
        } while (Process32Next(hSnapshot, &pe32));
    }

    CloseHandle(hSnapshot);
    return dwPID;
}

// 枚举指定进程的所有模块(同时支持 32/64 位模块)
BOOL CGetModuleBaseDlg::GetAllModules(DWORD dwPID, CListCtrl& listCtrl)
{
    listCtrl.DeleteAllItems();

    // 同时使用 TH32CS_SNAPMODULE 和 TH32CS_SNAPMODULE32 可兼容 WOW64 进程的 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("请输入进程名称!"));
        return;
    }

    DWORD dwPID = GetProcessIDByName(strProcessName);
    if (dwPID == 0)
    {
        AfxMessageBox(_T("未找到指定进程!请确认进程名称正确(包含.exe),且进程正在运行。"));
        m_listModules.DeleteAllItems();
        return;
    }

    CString strTitle;
    strTitle.Format(_T("进程 %s (PID: %u) 的模块列表"), strProcessName, dwPID);
    SetWindowText(strTitle);

    if (!GetAllModules(dwPID, m_listModules))
    {
        AfxMessageBox(_T("枚举模块失败,可能没有足够权限。"));
        m_listModules.DeleteAllItems();
    }
}

4. 项目配置(VS2022)

项目使用 Unicode 字符集。

使用 MFC:项目属性 → 常规 → 使用 MFC → “在共享 DLL 中使用 MFC” 或 “在静态库中使用 MFC”。

5.使用方法

  • 运行程序
  • 在编辑框输入进程可执行文件名,例如:notepad.exechrome.exe
  • 点击“查找进程”
  • 列表中会显示该进程加载的所有模块(包括主模块和 DLL)

这样就完整实现了你要求的功能,支持 32 位和 64 位进程的模块枚举。

到此这篇关于C++实现支持32位和64位进程的模块枚举的文章就介绍到这了,更多相关C++模块枚举内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Matlab实现将图像序列合并为视频的方法详解

    Matlab实现将图像序列合并为视频的方法详解

    MATLAB是一种高性能语言,用于操纵矩阵、执行技术计算、绘图等。它代表矩阵实验室。借助这个软件,我们可以从图像中创建视频。这篇文章主要介绍了Matlab实现将图像序列合并为视频的四个方法,希望对大家有所帮助
    2023-03-03
  • C++实现旋转数组的二分查找

    C++实现旋转数组的二分查找

    这篇文章主要介绍了C++实现旋转数组的二分查找方法,涉及数组的操作,有值得借鉴的技巧,需要的朋友可以参考下
    2014-09-09
  • C语言FlappyBird飞扬的小鸟实现开发流程

    C语言FlappyBird飞扬的小鸟实现开发流程

    因为在家宅了好多天,随手玩了下自己以前做的一些小游戏,说真的,有几个游戏做的是真的劣质,譬如 flappybird 真的让我难以忍受,于是重做了一波分享给大家
    2022-11-11
  • C++使用waveIn实现声音采集

    C++使用waveIn实现声音采集

    在Windows上实现录音比较简单的方法是使用winmm,其中的waveIn模块就可以打开录音设备,这篇文章主要为大家介绍了C++如何使用waveIn实现声音采集,需要的可以了解下
    2023-10-10
  • C++ set和multiset的使用小结

    C++ set和multiset的使用小结

    本文介绍了C++中序列式容器和关联式容器的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-12-12
  • C++实现LeetCode(173.二叉搜索树迭代器)

    C++实现LeetCode(173.二叉搜索树迭代器)

    这篇文章主要介绍了C++实现LeetCode(173.二叉搜索树迭代器),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • C++ RAII在HotSpot VM中的重要应用解析

    C++ RAII在HotSpot VM中的重要应用解析

    RAII技术被认为是C++中管理资源的最佳方法,进一步引申,使用RAII技术也可以实现安全、简洁的状态管理,编写出优雅的异常安全的代码,这篇文章主要介绍了C++ RAII在HotSpot VM中的重要应用,需要的朋友可以参考下
    2023-09-09
  • C语言实现简单的贪吃蛇游戏的示例代码

    C语言实现简单的贪吃蛇游戏的示例代码

    这篇文章主要为大家详细介绍了C语言如何实现经典贪吃蛇游戏,文中的示例代码讲解详细,对我们学习C语言有一定的帮助,感兴趣的小伙伴可以跟随小编一起了解一下
    2023-01-01
  • C语言代码中调用C++代码的方法示例

    C语言代码中调用C++代码的方法示例

    这篇文章主要介绍了C语言代码中调用C++代码的方法示例,文中也介绍了C++代码调用C代码的方法,有需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-02-02
  • boost.asio框架系列之定时器Timer

    boost.asio框架系列之定时器Timer

    这篇文章介绍了boost.asio框架系列之定时器Timer,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06

最新评论