• Windows编程之模块遍历(C++实现)


                Windows编程之模块遍历

    PS: 主要扣代码使用,直接滑动到最下面使用.

    遍历模块需要几个API,和一个结构体

      1.创建进程快照

      2.遍历首次模块

      3.继续下次遍历

      4.模块信息结构体

    API 分别是:

    1.创建进程快照

    HANDLE WINAPI CreateToolhelp32Snapshot(      进程快照API
      DWORD dwFlags,                       遍历的标志,表示你要遍历什么(进程,模块,堆...)
      DWORD th32ProcessID                   遍历的进程ID,如果为0,则是当前进程,如果不为0,则是创建指定进程的快照进行遍历
    );

    注意,创建进程快照需要包含头文件  Tlhelp32.h

    返回值:

      成功返回快照句柄

      失败返回 INVALID_HANDLE_VALUE

    2.遍历首次模块.

    BOOL WINAPI Module32First(
      HANDLE hSnapshot,           快照句柄
      LPMODULEENTRY32 lpme         模块信息结构体
    );
     
    模块信息结构体


    对我们有用的就是
    dwSize         初始化结构体的大小
    th32ProcessId 进程ID
    szExeFile[MAX_PATH] 进程路径

    3.遍历下一次进程
    BOOL WINAPI Process32Next(
      HANDLE hSnapshot,        进程句柄
      LPPROCESSENTRY32 lppe     进程信息结构体
    );
    typedef struct tagMODULEENTRY32 { 
      DWORD   dwSize;                 大小,第一次使用必须初始化
      DWORD   th32ModuleID;              进程模块标识符
      DWORD   th32ProcessID;             进程ID
      DWORD   GlblcntUsage;              全局模块使用次数
      DWORD   ProccntUsage;              模块的引用计数
      BYTE  * modBaseAddr;               模块的基址
      DWORD   modBaseSize;               模块的大小
      HMODULE hModule;                 模块的句柄
      TCHAR   szModule[MAX_MODULE_NAME32 + 1];   模块名称的字符串
      TCHAR   szExePath[MAX_PATH];          模块路径字符串
    } MODULEENTRY32; 
    typedef MODULEENTRY32 *PMODULEENTRY32; 

    这个常用的也很多

    模块基址  模块大小 模块句柄 模块名称,以及模块路径等等.

    兼容代码,遍历自己进程模块(DLL)
    #include <stdio.h>
    #include <windows.h>
    #include <Tlhelp32.h>
    int main(int argc, char* argv[])
    {
        HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,0);
        if (INVALID_HANDLE_VALUE == hSnapshot)
        {
            return 0;
        }
        MODULEENTRY32 mi; 
        mi.dwSize = sizeof(MODULEENTRY32); //第一次使用必须初始化成员
        BOOL bRet = Module32First(hSnapshot,&mi);
        while (bRet)
        {
            /*
            循环遍历添加自己的额外代码
            */    
        
            bRet = Module32Next(hSnapshot,&mi);
        }
        return 0;
    }

    兼容代码,遍历指定进程模块

    思路:

      1.获取你想要遍历的进程ID (可以通过遍历进程,也可以通过通过句柄获得进程ID)

      2.创建进程快照,第一个参数传入遍历模块,第二个参数传入你想要遍历进程的ID

    #include <stdio.h>
    #include <windows.h>
    #include <Tlhelp32.h>
    int main(int argc, char* argv[])
    {
        HANDLE hProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
        if (INVALID_HANDLE_VALUE == hProcessSnapshot)
        {
            return 0;
        }
        DWORD dwPid = 0;
        PROCESSENTRY32 pi;
        pi.dwSize = sizeof(PROCESSENTRY32);
        BOOL Ret = Process32First(hProcessSnapshot,&pi);
        while (Ret)
        {
            if (strcmp("QQ.exe",pi.szExeFile) == 0)
            {
                dwPid = pi.th32ProcessID;
                break;
            }
            Ret = Process32Next(hProcessSnapshot,&pi);
        }
        CloseHandle(hProcessSnapshot);
    
    
        HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,dwPid);//上面获取了进程PID,下面使用即可.
        if (INVALID_HANDLE_VALUE == hSnapshot)
        {
            return 0;
        }
        MODULEENTRY32 mi; 
        mi.dwSize = sizeof(MODULEENTRY32); //第一次使用必须初始化成员
        BOOL  bRet = Module32First(hSnapshot,&mi);
        while (bRet)
        {
            /*
            循环遍历添加自己的额外代码
            */    
        
            bRet = Module32Next(hSnapshot,&mi);
        }
        CloseHandle(hSnapshot);
        return 0;
    }
  • 相关阅读:
    Leetcode NO.110 Balanced Binary Tree 平衡二叉树
    Leetcode NO.226 Invert Binary Tree 翻转二叉树
    Leetcode NO.215 Kth Largest Element In An Array 数组中的第K个最大元素
    根据特征的浏览器判断
    Cygwin在打开在当前目录
    【转帖】科学对待 健康养猫 打造快乐孕妇
    解决chrome浏览器安装扩展、应用程序一直处在“检查中”的问题
    对【SQL SERVER 分布式事务解决方案】的心得补充
    关于“点击这里继续访问您选择的百度XXX”
    VBA一例:如何保持文本框焦点
  • 原文地址:https://www.cnblogs.com/iBinary/p/8159491.html
Copyright © 2020-2023  润新知