Windows: Visual C++: Listing loaded modules from process?
Many of you who deal with reverse engineering might be using tools similar or is Dependency Walker which is a tool that during run-time enumerates statically or dynamically loaded modules.
If you don't get my terminology, allow me to provide an example: A piece of code that uses the function LoadLibraryEx would call this function from kernel32.dll.
Thus statically linking the compiled end result to the kernel32.dll module.
If you're then using LoadLibraryEx()[/url] from kernel32.dll to load user32.dll you're then dynamically loading the user32.dll module.
My first approach was to use LoadLibraryEx() to first load the module, then use EnumerateLoadedModulesEx() on the HINSTANCE of my first call. Seems like it would do exactly what I want right? I mean, even the function names makes sense.
Now there was just one tiny problem with this. After evaluating the program and coming to the conclusion that it doesn't work at all I read that the HINSTANCE that EnumerateLoadedModulesEx() must come from a process itself.
So, as I see it I must CreateProcess() on the module, this is pretty straight forward on any PE/COFF file (Executable). But how should I approach this when I need to load a DLL?
For reference sake, here's the code I mentioned before that failed: http://codepad.org/fHgaSrSW
I am not an expert with this stuff, but, if I have interpreted the MS Documentation right I think you might need to use "GetCurrentProcess()" (IE the current process) in place of using the HMODULE from LoadLibrary for the DLL.
Line 35-37:
if (!EnumerateLoadedModules(GetCurrentProcess(),
(PENUMLOADED_MODULES_CALLBACK)EnumerateLoadedModulesProc,
0)) {
An aside: If this were loading a DLL in another process (I know it would be a totally different method anyway), then you would have probably have already used CreateToolhelp32Snapshot and a while loop with "Process32Next()" to scan for the process of interest, and thus already have the process handle…
EDIT (After reading more careful about the Ex calls) As for using the "Ex" WINAPI call, if you were to change your "int main" to "WINAPI main"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
Then I would presume you just use hInstance…
Hope that helps.
Jim,
Well, the problem is of that EnumerateLoadedModules doesn't iterate through the modules. So if I were to use GetCurrentProcess in conjunction with EnumerateLoadedModule I would only get the modules which the calling process has loaded. As you can see in the code I had two commented lines which pretty much did what you suggested, it works however but it's not the result I'm looking for.
I'm not entirely sure what you meant with the Ex functions.
Edit:
Now I saw what you meant, this isn't a graphical software so WinMain isn't related.
Thanks though!
Sorry took me a while to figure this out, turns out CreateToolhelp32Snapshot does the trick for this in a - somewhat - convoluted way!
The API
CreateToolhelp32Snapshot() Module32First() Module32Next() GetCurrentProcessId() Traversing the Module List (Example)
Traversing the module list is quite strait forward - I'll admit I looked this up based on some code I'd used for scanning process names and killing the processes, just in an attempt to stop me playing games easily :P
Finding the module, by name, is quite easy from here…
Structure MODULEENTRY32 structure:
typedef struct MODULEENTRY32 {
DWORD dwSize;
DWORD th32ModuleID;
DWORD th32ProcessID;
DWORD GlblcntUsage;
DWORD ProccntUsage;
BYTE *modBaseAddr;
DWORD modBaseSize;
HMODULE hModule;
TCHAR szModule[MAX_MODULE_NAME32 + 1];
TCHAR szExePath[MAX_PATH];
} MODULEENTRY32, *PMODULEENTRY32;
A simple comparison between the current szModule (IE the name of the module loaded in the process specified) This is the code I've compiled on MinGW (GCC for Windows):
#include <stdio.h>
#include <windows.h>
#include <tlhelp32.h>
void CheckModuleLoaded( TCHAR modName[] )
{
//Create a module entry struct
MODULEENTRY32 modEntry;
//Create a snapshot all the modules in the specified process
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,GetCurrentProcessId());
//Get the first entry
if(hSnap != INVALID_HANDLE_VALUE && Module32First(hSnap,&modEntry))
{
//Do stuff, again and again...
do
{
if(stricmp(modEntry.szModule,modName) == 0)
{
printf("================================\n");
printf(" Loaded Module: %s\n", modEntry.szModule);
printf("================================\n");
printf("Base Address: %X\n", modEntry.modBaseAddr);
printf("Base Size: %d\n", modEntry.modBaseSize);
printf("================================\n");
//CloseHandel(hSnap); -- Not in GCC windows.h for some stupid reason, not sure where it is in GCC libs
}
}
while(Module32Next(hSnap,&modEntry));
}
//CloseHandel(hSnap); -- Not in GCC windows.h for some stupid reason, not sure where it is in GCC libs
}
int main (int argc, char *argv[])
{
HMODULE loadProc;
if(argc == 2)
{
if( (loadProc = LoadLibrary(argv[1])) != NULL )
{
//
CheckModuleLoaded(argv[1]);
//
}
}
else
{
//
printf("Invalid parameters!\nUsage %s: [DLL File]\n",argv[1]);
//
}
return 0;
}
I do have Visual Studio but I haven't had chance to write an MSVC++ friendly version - sorry!
You could probably do the parameter to the function as a pointer rather than pushing the string on the stack…
Hope this was what you were after though!
Jim,