注册 登录
编程论坛 C语言论坛

求助,关于获取模块地址的问题.

a451410 发布于 2024-08-13 02:08, 203 次点击
    使用 GetModuleHandle可以获取一个模块的地址,
如,HMODULE hm = GetModuleHandle(xxxxx.dll);就会返回地址;

    请问如何获取一个xxxxx.exe 的地址呢?   
如,我想获取一个HMODULE hm = GetModuleHandle(xxxxx.exe);就总会返回一个0,而不是一个正确的值;

我该怎么做才能正确返回一个exe的地址。
3 回复
#2
rjsp2024-08-13 09:37
这个“Module”指的是内存中的模块,如果你说的exe并没有被加载(运行),根本就不存在Module。
其次,如果你这个xxxxx.exe 与 GetModuleHandle所在的程序 并不是同一个进程的话,因为权限问题,肯定失败嘛

我写个示例,你先启动windows自带的记事本程序,然后执行下面的程序
程序代码:
#include <windows.h>
#include <psapi.h>

#include <vector>
#include <string>
#include <iostream>

HANDLE GetProcessHandle_ByWindow( const wchar_t* lpClassName, const wchar_t* lpWindowName )
{
    HWND hWnd = ::FindWindowW( lpClassName, lpWindowName );
    if( !hWnd )
        return nullptr;

    DWORD pid;
    if( GetWindowThreadProcessId(hWnd,&pid) == 0 )
        return nullptr;

    return OpenProcess( PROCESS_ALL_ACCESS, FALSE, pid );
}

std::vector<std::pair<std::wstring,HMODULE>> GetModules_ByProcessHandle( HANDLE hProcess )
{
    std::vector<HMODULE> temp( 100, nullptr );
    for( ; ; )
    {
        DWORD cb_needed;
        if( !EnumProcessModulesEx(hProcess, &temp[0], DWORD(temp.size()*sizeof(HMODULE)), &cb_needed, LIST_MODULES_DEFAULT) )
            return {};
        if( cb_needed < temp.size()*sizeof(HMODULE) )
        {
            temp.resize( cb_needed/sizeof(HMODULE) );
            break;
        }
        temp.resize( temp.size()*2 );
    }

    std::vector<std::pair<std::wstring,HMODULE>> result;
    for( const auto& h : temp )
    {
        std::wstring basename( 10, L'?' );
        for( ; ; )
        {
            DWORD n = GetModuleBaseNameW( hProcess, h, &basename[0], (DWORD)basename.size() );
            if( n == 0 )
                return {};
            if( n < basename.size() )
            {
                basename.resize( n );
                break;
            }
            basename.resize( basename.size()*2 );
        }
        result.emplace_back( basename, h );
    }
    return result;
}

int main( void )
{
    std::wcout.imbue( std::locale(std::locale(),"",std::locale::ctype) );

    HANDLE hProcess = GetProcessHandle_ByWindow( L"Notepad", nullptr );
    if( hProcess )
    {
        std::vector<std::pair<std::wstring,HMODULE>> modules = GetModules_ByProcessHandle( hProcess );
        for( const auto& [name,hModule] : modules )
        {
            std::wcout << hModule << '\t' << name << '\n';
        }

        CloseHandle( hProcess );
    }

    return 0;
}

应该输出
00007FF61CAF0000        Notepad.exe
00007FFFF3090000        ntdll.dll
00007FFFF1450000        KERNEL32.DLL
00007FFFF04E0000        KERNELBASE.dll
00007FFFF1060000        SHLWAPI.dll
00007FFFF2180000        msvcrt.dll
00007FFFF2EA0000        USER32.dll
00007FFFF0BE0000        win32u.dll
00007FFFF0E80000        GDI32.dll
00007FFFF0950000        gdi32full.dll
……………………




#3
rjsp2024-08-13 10:03
如果你的xxxxx.exe并没有窗体,那么就无法使用FindWindowW。这时可以遍历内存快照,ms有示例
https://learn.
#4
a4514102024-08-13 15:59
回复 2楼 rjsp
谢谢@  我正在尝试理解。
1