c++代码改成通过pid和模块名字获取指定的模块基址

不要说几个函数然后指指点点,直接回复加好注释的源码,不然不采纳。

PVOID GetProcessImageBase2(DWORD dwProcessId)//dwProcessId就是程序的标识符
{
    PVOID pProcessImageBase = NULL;
    //打开进程, 获取进程句柄
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
    if (NULL == hProcess)
    {
        return pProcessImageBase;
    }
    // 遍历进程模块,
    HMODULE hModule[100] = { 0 };
    DWORD dwRet = 0;
    BOOL bRet = EnumProcessModules(hProcess, (HMODULE*)(hModule), sizeof(hModule), &dwRet);
    if (FALSE == bRet)
    {
        CloseHandle(hProcess);
        return pProcessImageBase;
    }
    // 获取第一个模块加载基址
    pProcessImageBase = hModule[0];
    // 关闭句柄
    CloseHandle(hProcess);
    return pProcessImageBase;
}



改造了一下,可以运行,注意传入正确的pid和模块名称,模块名称此处为了方便,不带路径,运行效果:

img

代码如下:

#include <string>
using namespace std;
PVOID GetProcessImageBase3(DWORD dwProcessId, TCHAR*  moduleName)//dwProcessId就是程序的标识符
{
    PVOID pProcessImageBase = NULL;
    //打开进程, 获取进程句柄
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
    if (NULL == hProcess)
    {
        return pProcessImageBase;
    }
    // 遍历进程模块,
    HMODULE hModule[100] = { 0 };
    DWORD dwRet = 0;
    BOOL bRet = EnumProcessModules(hProcess, (HMODULE*)(hModule), sizeof(hModule), &dwRet);
    if (FALSE == bRet)
    {
        CloseHandle(hProcess);
        return pProcessImageBase;
    }
    int iSel = 0;
    for (int i = 0; i < (dwRet / sizeof(HMODULE)); i++)
    {
        TCHAR szModName[MAX_PATH];

        // Get the full path to the module's file.

        if (GetModuleFileNameEx(hProcess, hModule[i], szModName,
            sizeof(szModName) / sizeof(TCHAR)))
        {
            // 遍历模块名,与传入的模块名比较,相同则记录序号(只比较文件名,不比较路径,注意文件名带扩展名)
            basic_string<TCHAR, char_traits<TCHAR>, allocator<TCHAR> >
                str(szModName);
            if (str.find_last_of('\\') >= 0)
                str = str.substr(str.find_last_of(_T("\\"))+1);

            if (_tcsicmp(str.c_str(), moduleName) == 0)
            {
                iSel = i;
                break;
            }
            _tprintf(TEXT("\t%s (0x%08X)\n"), szModName, hModule[i]);
        }
    }
    // 获取指定名称模块的加载基址,未找到则返回第0个
    pProcessImageBase = hModule[iSel];
    // 关闭句柄
    CloseHandle(hProcess);
    return pProcessImageBase;
}


int APIENTRY _tWinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPTSTR    lpCmdLine,
    int       nCmdShow)
{
    //PVOID p = GetProcessImageBase2(12124);
    PVOID p = GetProcessImageBase3(12124, _T("devenv.exe"));//12124改成你的devenv.exe的pid

    return 0;
}


#include <windows.h>
#include <psapi.h>
#include<tlhelp32.h>
#include <string>
using namespace std;

PVOID GetProcessImageBase2(DWORD dwProcessId, wstring& targetModuleName)//dwProcessId就是程序的标识符, targetModuleName目标模块名
{
    HMODULE moduleHandle = NULL; //改个类型名,以便自增
    //打开进程, 获取进程句柄
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
    if (!hProcess)
        return NULL; //找不到返回空

    // 遍历进程模块,
    HMODULE hModule[100] = { 0 };
    DWORD dwRet = 0;
    BOOL bRet = EnumProcessModules(hProcess, (HMODULE*)(hModule), sizeof(hModule), &dwRet);
    if (FALSE == bRet)
    {
        CloseHandle(hProcess);
        return NULL;
    }

    // 获取第一个模块句柄
    moduleHandle = hModule[0];
    WCHAR moduleName[MAX_PATH] = {0}; //模块名接收缓冲区
    MODULEENTRY32 me32 = { 0 };

    while (moduleHandle)
    {
        DWORD nSize = GetModuleFileName((HMODULE)moduleHandle, moduleName, MAX_PATH);
        if (!nSize) //函数错误返回0
        {
            ++moduleHandle; //下一个模块
            continue;
        }
        wstring wstrModuleName(moduleName, nSize);
        if (targetModuleName == wstrModuleName) //找到了同名模块
        {
            if(Module32First(moduleHandle, &me32)) //获取模块信息
            return me32.modBaseAddr; //返回模块基址
        }
        ++moduleHandle;//下一个模块
    }
    // 关闭句柄
    CloseHandle(hProcess);
    return NULL;
}



参考一下这个?https://blog.csdn.net/m0_46135508/article/details/118709531