I've written a little program that lists all DLLs of a given process ID:
#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 );
}
This does work correctly with most programs. I tried this with some process IDs running on my system. But for some 32 bit processes it lists only some essential DLLs. F.e. for Adobe Digital Editions (ADE) it lists:
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
For sure this process isn't only running on such a small number of DLLs.
What's going on with 32 bit processes processes like ADE ?
CodePudding user response:
The DLLs you have shown are all 64bit DLLs that are loaded into every 32bit process to run the WOW64 emulation. Since your app is using TH32CS_SNAPMODULE
and displaying 64bit DLLs, that suggests your app is running as a 64bit process. The CreateToolhelp32Snapshot()
documentation says:
TH32CS_SNAPMODULE
0x00000008Includes all modules of the process specified in th32ProcessID in the snapshot. To enumerate the modules, see Module32First. If the function fails with ERROR_BAD_LENGTH, retry the function until it succeeds.
64-bit Windows: Using this flag in a 32-bit process includes the 32-bit modules of the process specified in th32ProcessID, while using it in a 64-bit process includes the 64-bit modules. To include the 32-bit modules of the process specified in th32ProcessID from a 64-bit process, use the TH32CS_SNAPMODULE32 flag.
TH32CS_SNAPMODULE32
0x00000010Includes all 32-bit modules of the process specified in th32ProcessID in the snapshot when called from a 64-bit process. This flag can be combined with TH32CS_SNAPMODULE or TH32CS_SNAPALL. If the function fails with ERROR_BAD_LENGTH, retry the function until it succeeds.
CodePudding user response:
You were all right. I now conditionally added 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 );
}
}