//************************************************************************* // Method: fillModuleListPSAPI // Description: support function // //************************************************************************* bool StackWalker::fillModuleListPSAPI( ModuleList& modules, DWORD pid, HANDLE hProcess ) { // EnumProcessModules() typedef BOOL (__stdcall *tEPM)( HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded ); // GetModuleFileNameEx() typedef DWORD (__stdcall *tGMFNE)( HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize ); // GetModuleBaseName() -- redundant, as GMFNE() has the same prototype, but who cares? typedef DWORD (__stdcall *tGMBN)( HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize ); // GetModuleInformation() typedef BOOL (__stdcall *tGMI)( HANDLE hProcess, HMODULE hModule, LPMODULEINFO pmi, DWORD nSize ); HINSTANCE hPsapi; tEPM pEPM; tGMFNE pGMFNE; tGMBN pGMBN; tGMI pGMI; int i; ModuleEntry e; DWORD cbNeeded; MODULEINFO mi; HMODULE *hMods = 0; char *tt = 0; hPsapi = LoadLibrary( "psapi.dll" ); if ( hPsapi == 0 ) return false; modules.clear(); pEPM = (tEPM) GetProcAddress( hPsapi, "EnumProcessModules" ); pGMFNE = (tGMFNE) GetProcAddress( hPsapi, "GetModuleFileNameExA" ); pGMBN = (tGMFNE) GetProcAddress( hPsapi, "GetModuleBaseNameA" ); pGMI = (tGMI) GetProcAddress( hPsapi, "GetModuleInformation" ); if ( pEPM == 0 || pGMFNE == 0 || pGMBN == 0 || pGMI == 0 ) { // yuck. Some API is missing. FreeLibrary( hPsapi ); return false; } hMods = new HMODULE[TTBUFLEN / sizeof HMODULE]; tt = new char[TTBUFLEN]; // not that this is a sample. Which means I can get away with // not checking for errors, but you cannot. :) if ( ! pEPM( hProcess, hMods, TTBUFLEN, &cbNeeded ) ) { //printf( "EPM failed, GetLastError() = %lu\n", GetLastError() ); goto cleanup; } if ( cbNeeded > TTBUFLEN ) { //printf( "More than %lu module handles. Huh?\n", lenof( hMods ) ); goto cleanup; } for ( i = 0; i < cbNeeded / sizeof hMods[0]; ++ i ) { // for each module, get: // base address, size pGMI( hProcess, hMods[i], &mi, sizeof mi ); e.baseAddress = (DWORD) mi.lpBaseOfDll; e.size = mi.SizeOfImage; // image file name tt[0] = '\0'; pGMFNE( hProcess, hMods[i], tt, TTBUFLEN ); e.imageName = tt; // module name tt[0] = '\0'; pGMBN( hProcess, hMods[i], tt, TTBUFLEN ); e.moduleName = tt; /*printf( "%08lXh %6lu %-15.15s %s\n", e.baseAddress, e.size, e.moduleName.c_str(), e.imageName.c_str() );*/ modules.push_back( e ); } cleanup: if ( hPsapi ) FreeLibrary( hPsapi ); delete [] tt; delete [] hMods; return modules.size() != 0; }
bool fillModuleListPSAPI( ModuleList& modules, DWORD pid, HANDLE hProcess ) { // EnumProcessModules() typedef BOOL (__stdcall *tEPM)( HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded ); // GetModuleFileNameEx() typedef DWORD (__stdcall *tGMFNE)( HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize ); // GetModuleBaseName() -- redundant, as GMFNE() has the same prototype, but who cares? typedef DWORD (__stdcall *tGMBN)( HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize ); // GetModuleInformation() typedef BOOL (__stdcall *tGMI)( HANDLE hProcess, HMODULE hModule, LPMODULEINFO pmi, DWORD nSize ); HINSTANCE hPsapi; tEPM pEPM; tGMFNE pGMFNE; tGMBN pGMBN; tGMI pGMI; DWORD i; ModuleEntry e; DWORD cbNeeded; MODULEINFO mi; HMODULE *hMods = 0; char *tt = 0; GString g("psapi.dll"); hPsapi = LoadLibrary( g ); if ( hPsapi == 0 ) return false; modules.clear(); pEPM = (tEPM) GetProcAddress( hPsapi, "EnumProcessModules" ); pGMFNE = (tGMFNE) GetProcAddress( hPsapi, "GetModuleFileNameExA" ); pGMBN = (tGMFNE) GetProcAddress( hPsapi, "GetModuleBaseNameA" ); pGMI = (tGMI) GetProcAddress( hPsapi, "GetModuleInformation" ); if ( pEPM == 0 || pGMFNE == 0 || pGMBN == 0 || pGMI == 0 ) { FreeLibrary( hPsapi ); return false; } hMods = new HMODULE[TTBUFLEN / sizeof(HMODULE)]; tt = new char[TTBUFLEN]; // check for errors and cleanup if ( ! pEPM( hProcess, hMods, TTBUFLEN, &cbNeeded ) ) { goto cleanup; } if ( cbNeeded > TTBUFLEN ) { goto cleanup; } for ( i = 0; i < cbNeeded / sizeof hMods[0]; ++ i ) { // for each module, get: // base address, size pGMI( hProcess, hMods[i], &mi, sizeof mi ); e.baseAddress = (DWORD) mi.lpBaseOfDll; e.size = mi.SizeOfImage; // image file name tt[0] = '\0'; pGMFNE( hProcess, hMods[i], tt, TTBUFLEN ); e.imageName = tt; // module name tt[0] = '\0'; pGMBN( hProcess, hMods[i], tt, TTBUFLEN ); e.moduleName = tt; modules.push_back( e ); } cleanup: if ( hPsapi ) FreeLibrary( hPsapi ); delete [] tt; delete [] hMods; return modules.size() != 0; }