How to Get the Hmodule for the Currently Executing Code

How do I get the HMODULE for the currently executing code?

HMODULE GetCurrentModule()
{ // NB: XP+ solution!
HMODULE hModule = NULL;
GetModuleHandleEx(
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
(LPCTSTR)GetCurrentModule,
&hModule);

return hModule;
}

How to get my own code's module handle?

Store the module handle away when it is given to you in DllMain and then use it later when you actually need it. A lot of frameworks (e.g., MFC) do this automatically.

Get path of current module after using RemoteThread

There's a "hidden" tool helper library mentionned by Raymond Chen that gets around several quirks in the Win32 APi. It seems you can use that to fetch the handle to the first module associated to a process (presumably the original executable). You can use that handle to get the path to the executable.

Looks something like:

  // Get a listing of modules loaded in the process.
DWORD process = ...;
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, process);
// Get the handle to the first module loaded by that process.
MODULEENTRY32 entry;
Module32First(snapshot, &entry);
HANDLE module = entry.hModule;
// Get the path to the executable/DLL file containing the module.
GetModuleFileName(module, ...);

Edit: I've tried a complete example. You get an empty string using GetModuleFileName() because the module handle was not loaded using the LoadLibrary() function call.

However, it seems the MODULEENTRY32 structure already provides the full path to the module in its szExePath member. The following example works for me:

#include <Windows.h>
#include <TlHelp32.h>
#include <iostream>
int main ( int, char ** )
{
// Substitute `process` with appropriate process ID.
const ::DWORD process = ::GetCurrentProcessId();
const ::HANDLE snapshot =
::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, process);
if ( snapshot == INVALID_HANDLE_VALUE ) {
std::cerr << "Couldn't get snapshot!" << std::endl;
return (EXIT_FAILURE);
}
// Get 1st module info.
::MODULEENTRY32W module;
::ZeroMemory(&module, sizeof(module));
module.dwSize = sizeof(module);
const ::BOOL result = Module32FirstW(snapshot, &module);
if ( result == FALSE )
{
// Handle errors.
const ::DWORD error = ::GetLastError();
std::cerr
<< "Couldn't get 1st module (" << error << ")."
<< std::endl;
return (EXIT_FAILURE);
}
std::wcout
<< module.szExePath << std::endl;
// Cleanup.
::CloseHandle(snapshot);
return (EXIT_SUCCESS);
}

Get HModule from inside a DLL

The first argument to DllMain() is the HMODULE of the DLL.

Get DLL path at runtime

You can use the GetModuleHandleEx function and get the handle to a static function in your DLL. You'll find more information here.

After that you can use GetModuleFileName to get the path from the handle you just obtained. More information on that call is here.

A complete example:

char path[MAX_PATH];
HMODULE hm = NULL;

if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
(LPCSTR) &functionInThisDll, &hm) == 0)
{
int ret = GetLastError();
fprintf(stderr, "GetModuleHandle failed, error = %d\n", ret);
// Return or however you want to handle an error.
}
if (GetModuleFileName(hm, path, sizeof(path)) == 0)
{
int ret = GetLastError();
fprintf(stderr, "GetModuleFileName failed, error = %d\n", ret);
// Return or however you want to handle an error.
}

// The path variable should now contain the full filepath for this DLL.

Why are frameworks storing their own HMODULE when it can be retrieved using __ImageBase or GetModuleHandleEx()?

__ImageBase is a trick provided by the Microsoft linker and might not work with other compilers/linkers. Even if the framework does not support other toolsets they might not know about this magic symbol so that is probably why it is not used much.

The same thing can be done in pure WinAPI with VirtualQuery or GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,...)

Injected DLL not correct HMODULE

Got it working with help from:

RectangleEquals -> Answer

What is HMODULE?

The method that you propose will work fine.

It seems that you have injected a dll into a target process and wish to obtain the address of a function in that dll in the target process from the process that injected the dll.

I assume that you also have the dll loaded in the process that injected the dll into the target process and that you want to create a remote thread in the target process and get it to execute the target function in the target process.

Since the dll that you have injected may not be loaded at the same address in the target process as it is in the injecting process you cannot simply use the address that you would obtain from calling GetProcAddress on the function in the injecting process.

An HMODULE is just the DLL's base address (see this answer for details). So you can take the HMODULE of the dll in your injecting process and subtract it from the address returned by GetProcAddress on your function. You can then add the HMODULE of the injected dll in the target process to this offset to get the address of the target function in the injected dll in the target process. Assuming this function has the correct signature, pass it as the thread function to your call to create the remote thread and you are now running the target function in the target process.

I explain this in more detail in this answer.

Determine the current HINSTANCE?

If memory serves, GetModuleHandle(NULL); returns the instance handle.



Related Topics



Leave a reply



Submit