System-wide hooks with MHook

2019-04-15 16:38发布

问题:

I have this project where I hook some Windows functions (GetOpenFileNameA, GetOpenFileNameW, GetSaveFileNameA, GetSaveFileNameW) with MHook library. This is the code I use to install the hooks.

for(size_t i = 0; i < FunctionsCount; ++i)
{
    HMODULE hModule = GetModuleHandleA(Function[i].ModuleName);

    //[1]
    if( !hModule )
        return FALSE;

    *Function[i].Original = GetProcAddress(hModule, Function[i].Name);

    if(*Function[i].Original == NULL)
        return FALSE;

    if(!Mhook_SetHook(Function[i].Original, Function[i].Hooked))
        return FALSE;
}

It is called from DllMain on DLL_PROCESS_ATTACH reason.

Now, when I inject my Dll using the CreateRemoteThread approach it works pretty well, but when I want to set up the system-wide hooks using LoadAppInit_DLLs mechanism my hooks doesn't works. After hours debugging I found that the reason is that my Dll is loaded BEFORE comdlg32.dll (which is the module where these functions are), and then the statement [1] returns false, then my Dll is not loaded.

The solution I've so far is to call LoadLibrary if [1] returns false.

HMODULE hModule = GetModuleHandleA(Function[i].ModuleName);

//[2]
if( !hModule )
{
    LoadLibraryA(Function[i].ModuleName);
    hModule = GetModuleHandleA(Function[i].ModuleName);
}

I've found many site where is said this is evil and I agree (even when works fine). Also if a process doesn't use common dialogs at all I'm hooking functions that will never be called.

If anybody could help, maybe a workaround or an explanation of another way to set-up global hooks it will be appreciated. Thanks in advance

回答1:

You need to hook LoadLibraryXXX functions and after successful their execution check whether your module has been loaded (calling GetModuleHandle) and hook it if it is loaded.

Also it is a good idea to pin hooked dlls so they are not unloaded anymore.