首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何列出某个进程ID的所有模块

如何列出某个进程ID的所有模块
EN

Stack Overflow用户
提问于 2022-05-26 05:38:55
回答 2查看 93关注 0票数 0

我编写了一个小程序,其中列出了给定进程ID的所有all:

代码语言:javascript
运行
复制
#include <Windows.h>
#include <TlHelp32.h>
#include <iostream>
#include <memory>
#include <vector>
#include <charconv>

using namespace std;

using XHANDLE = unique_ptr<void, decltype([]( void *h ) { h && h != INVALID_HANDLE_VALUE && CloseHandle( (HANDLE)h ); })>;

vector<MODULEENTRY32W> getModules( DWORD dwProcessId );
[[noreturn]]
void throwSysErr( char const *str );

int main( int argc, char **argv )
{
    try
    {
        if( argc < 2 )
            return EXIT_FAILURE;
        DWORD dwProcesId =
            [&]() -> DWORD
            {
                DWORD dwRet = 0;
                if( from_chars_result fcr = from_chars( argv[1], argv[1] + strlen( argv[1] ), dwRet ); fcr.ec != errc() || *fcr.ptr )
                    throw system_error( (int)fcr.ec, generic_category(), "invalid process id" );
                return dwRet;
            }();
        for( MODULEENTRY32W const &me : getModules( dwProcesId ) )
            wcout << me.szExePath << endl;
    }
    catch( exception const &exc )
    {
        cout << exc.what() << endl;
    }
}

vector<MODULEENTRY32W> getModules( DWORD dwProcessId )
{
    constexpr char const *ERR_STR = "can't list modules";
    XHANDLE xhToolHelp( CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwProcessId ) );
    if( xhToolHelp.get() == INVALID_HANDLE_VALUE )
        throwSysErr( ERR_STR );
    vector<MODULEENTRY32W> ret;
    MODULEENTRY32W me;
    me.dwSize = sizeof me;
    if( !Module32FirstW( xhToolHelp.get(), &me ) )
        if( GetLastError() == ERROR_NO_MORE_FILES )
            return ret;
        else
            throwSysErr( ERR_STR );
    for( ; ; )
    {
        ret.emplace_back( me );
        me.dwSize = sizeof me;
        if( !Module32NextW( xhToolHelp.get(), &me ) )
            if( GetLastError() == ERROR_NO_MORE_FILES )
                return ret;
            else
                throwSysErr( ERR_STR );
    }
}

[[noreturn]]
void throwSysErr( char const *str )
{
    throw system_error( (int)GetLastError(), system_category(), str );
}

对于大多数程序来说,这确实是正确的。我在我的系统上运行了一些进程I,尝试了这一点。但是对于32位进程,它只列出了一些基本的DLL。F.e.对于Adobe数字版本(ADE),它列出:

代码语言:javascript
运行
复制
C:\Program Files (x86)\Adobe Digital Editions\DigitalEditions.exe
C:\Windows\SYSTEM32\ntdll.dll
C:\Windows\System32\wow64.dll
C:\Windows\System32\wow64base.dll
C:\Windows\System32\wow64win.dll
C:\Windows\System32\wow64con.dll
C:\Windows\System32\wow64cpu.dll

当然,这个进程不只是在这么少的DLL上运行。

像ADE这样的32位进程是怎么回事?

EN

回答 2

Stack Overflow用户

发布于 2022-05-26 05:59:25

您显示的DLL都是加载到每个32位进程中以运行WOW64仿真的所有64位DLL。由于您的应用程序使用TH32CS_SNAPMODULE并显示64位DLL,这意味着您的应用程序是作为64位进程运行的。CreateToolhelp32Snapshot()文档说:

TH32CS_SNAPMODULE

0x00000008

包括快照中th32ProcessID中指定的进程的所有模块。若要枚举模块,请参阅Module32First。如果函数在ERROR_BAD_LENGTH中失败,请重试该函数,直到它成功为止。

64位窗口:在32位进程中使用此标志的新编码包括在th32ProcessID中指定的进程的32位模块,而在64位进程中使用它则包括64位模块。若要从64位进程中包含th32ProcessID中指定的进程的32位模块,请使用TH32CS_SNAPMODULE32标志.

TH32CS_SNAPMODULE32

0x00000010

当从64位进程调用时,包含在快照中th32ProcessID中指定的进程的所有32位模块。此标志可以与TH32CS_SNAPMODULE或TH32CS_SNAPALL组合。如果函数在ERROR_BAD_LENGTH中失败,请重试该函数,直到它成功为止。

票数 2
EN

Stack Overflow用户

发布于 2022-05-26 06:03:42

你还好吧。我现在有条件地添加了TH32CS_SNAPMODULE32:

代码语言:javascript
运行
复制
vector<MODULEENTRY32W> getModules( DWORD dwProcessId )
{
    constexpr char const *ERR_STR = "can't list modules";
    XHANDLE xhProcess( OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, dwProcessId ) );
    BOOL fWow64PRocess;
    if( !xhProcess.get() || !IsWow64Process( xhProcess.get(), &fWow64PRocess ) )
        throwSysErr( ERR_STR );
    XHANDLE xhToolHelp( CreateToolhelp32Snapshot( TH32CS_SNAPMODULE | (fWow64PRocess ? TH32CS_SNAPMODULE32 : 0), dwProcessId ) );
    if( xhToolHelp.get() == INVALID_HANDLE_VALUE )
        throwSysErr( ERR_STR );
    vector<MODULEENTRY32W> ret;
    MODULEENTRY32W me;
    me.dwSize = sizeof me;
    if( !Module32FirstW( xhToolHelp.get(), &me ) )
        if( GetLastError() == ERROR_NO_MORE_FILES )
            return ret;
        else
            throwSysErr( ERR_STR );
    for( ; ; )
    {
        ret.emplace_back( me );
        me.dwSize = sizeof me;
        if( !Module32NextW( xhToolHelp.get(), &me ) )
            if( GetLastError() == ERROR_NO_MORE_FILES )
                return ret;
            else
                throwSysErr( ERR_STR );
    }
}
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72387177

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档