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
解决方案
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.