我编写了一个小程序,其中列出了给定进程ID的所有all:
#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),它列出:
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位进程是怎么回事?
发布于 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中失败,请重试该函数,直到它成功为止。
发布于 2022-05-26 06:03:42
你还好吧。我现在有条件地添加了TH32CS_SNAPMODULE32:
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 );
}
}
https://stackoverflow.com/questions/72387177
复制相似问题