System-wide hooks with MHook - c++

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.

Related

Hook APIs that imported to program by LoadLibrary/GetProcAddress

I know how I can hook functions from the IAT table, but I have a problem with APIs which were imported by calling LoadLibrary/GetProcAddress functions. I want to know exactly how someone could hook those functions. I realize that I should hook the GetProcAddress function but how can I check the parameters that were passsed to that function?
For example, consider a program which is going to include MessageBoxW via LoadLibrary/GetProcAddress, how can I hook that MessageBoxW and then check the parameters that have been passed to it?
I have searched a lot in StackOverflow and Google, but I couldn't find a step-by-step tutorial about this. So, if you have such a tutorial or article, I would be really grateful to read them.
In order to hook APIs that they are loaded into a binary dynamically with help of LoadLibrary/GetProcAddress, you should intercept return address of the GetProcAddress and name of the functions that passed to it (for example, consider a program try to load MessageBoxA in this way).
In the second step, you should save that original address of MessageBoxA API in a variable like OriginalMessageBoxA.
In the third and final step, you should return address of your modified API (HookedMessageBoxA) to the callee of the GetProcAddress so when the program try to call that address, program redirected to your function. Something like the following one:
VOID* HookedGetProcAddress(HMODULE hModule, LPCSTR lpProcName)
{
if (std::string(lpProcName).compare("MessageBoxA") == 0)
{
OMessageBoxA = (PMessageBoxA)GetProcAddress(hModule, lpProcName);
return HookedMessageBoxA;
}
else
{
return OGetProcAddress(hModule, lpProcName);
}
}
In that moment, caller will go through your HookedMessageBoxA and you can check parameters that passed to MessageBoxA. As folks said, it is kinda same like normal IAT hook with a minor changes and tricks.

How to hook an exe function?

I need to get something from a program. And with the help of ollydbg and IDA, I found the "thing" I can get is in a function called sub_HEXHEX.
Now I know how to hook a function from Dll like DrawTextA or other one.
I need to get function address with
HMODULE hmod = LoadLibrary(L"User32.dll");
GetProcAddress(hmod, "DrawTextA")
But when I need to hook this sub_HEXHEX, I confused. I can get that exe's HANDLE, I know the function's Address (that 0x00HEXHEX), but there's no GetProcAddress I can use. I tried use HANDLE + 0x00HEXHEX as function's address, but I think im wrong with 'offset' things.
Here is what I did
DWORD dwPid = GetCurrentProcessId();
hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, dwPid);
OldA2ECB0 = (sub_A2ECB0)((HMODULE)hProcess + 0xA2ECB0);
pfOldA2ECB0 = (FARPROC)OldA2ECB0;
And sub_A2ECB0
typedef int(*sub_A2ECB0)(LPCSTR param1, int param2);
But pfOldA2ECB0 will be NULL.
My knowledge is poor with C++ and Win32 (English, too), so its toooooo difficult for me.
From what I understand, and I do believe I understand correctly what you want is internal hooking.
I can show you how to do this in 3 simple steps.
These are the things you must understand:
The function shown in IDA is not exported, thus you cannot use GetProcAddress()
You must be within the context of the remote process to hook internal functions
You cannot use libraries like Detours, you must have your own method/function for hooking
These are the steps you must do:
Be withing the context of the remote process, simplest method: inject your dll.
Get the address offset from IDA, in your case is 00A2ECB0.
Simply apply the hook once inside the remote process:
//0xE8 instruction is a relative call instruction
SetCompleteHook(0xE8,0x00A2ECB0,&YOUR_OWN_FUNCTION);
Helper:
void SetCompleteHook(BYTE head,DWORD offset,...)
{
DWORD OldProtect;
VirtualProtect((void*)offset,5,PAGE_EXECUTE_READWRITE,&OldProtect);
if(head != 0xFF)
{
*(BYTE*)(offset) = head;
}
DWORD* function = &offset+1;
*(DWORD*)(offset+1) = (*function)-(offset+5);
VirtualProtect((void*)offset,5,OldProtect,&OldProtect);
}
And that's it really, it's as simple and straightforward as possible in your scenario.
You can go further of course and perform much more complex internal hooking, but for your learning purpose this is a massive step ahead and starting point.
Enjoy!

How to use `/DELAYLOAD` on a DLL from another DLL

I have a solution with two DLLs. The first one is the "main" DLL. It happens to be an ODBC driver, but I think that is not important for this question.
The second DLL contains all the UI logic for the first one. As the UI is not always needed, I want to use the /DELAYLOAD feature which explicitly says:
The delayed loading of a DLL can be specified during the build of
either a .EXE or .DLL project.
The main DLL's project correctly references the UI ones. If I don't use /DELAYLOAD, everythin works just fine. The two DLLs will be installed into the same directory, so I thought loading one DLL from within the other should be easy. But apparently, it's not.
As soon as the first function from the UI DLL is called, the application (any ODBC client in my case) crashes.
GetLastError() yields 126 which apparently means that the target DLL could not be found in any of the search paths.
And indeed, according to this answer LoadLibrary() does have a look into the directory of the calling executable, but not into the one of the currently executed DLL. I'm assuming /DELAYLOAD is also just using LoadLibrary() under the hood, is that correct?
If I copy the executable into the installation directory of my driver, it works just fine, which proves my assumption that it just doesn't look in the current DLL's directory.
Appart from that, I was also able to make it run by calling
LoadLibrary(L"C:\\absolute\\path\\to\\UI.dll");
just before the first function of the UI DLL is loaded.
I was also able to determine this path programmatically using
wchar_t buffer[512];
GetModuleFileName(hThisDLL, buffer, sizeof(buffer));
But then I would have to cover every single UI call with this logic. So I wouldn't see much advantage anymore that /DELAYLOAD has over the "old-school" way of using LoadLibrary() and GetProcAddress().
Question
Is there a simple way to make /DELAYLOAD find the target DLL from another DLL in the same directory?
There is. My suggestion would be to create a delay-load-failure hook function.
https://learn.microsoft.com/en-us/cpp/build/reference/failure-hooks?view=vs-2019
Basically, you write a function inside your main DLL that gets notified in the event of a delay load failure. In that function, when the given code indicates failure, you try manually calling LoadLibrary with of a path consisting of the folder in which your main DLL resides plus the name of the DLL that failed to load
How you get the your main DLL from within your main DLL is up to you. There are many ways.
Something like this:
FARPROC WINAPI delayHook(unsigned dliNotify, PDelayLoadInfo pdli)
{
FARPROC fpRet = NULL;
switch (dliNotify)
{
case dliStartProcessing:
break;
case dliNotePreLoadLibrary:
break;
case dliNotePreGetProcAddress:
break;
case dliFailLoadLib:
{
std::string newPath = GetMyModulePath();
newPath += "\\";
newPath += pdli->szDll;
fpRet = reinterpret_cast<FARPROC>(::LoadLibrary(csDir));
}
break;
case dliFailGetProc:
break;
case dliNoteEndProcessing:
break;
default:
break;
}
return fpRet;
}
//
// Set access to our delay load hook.
//
PfnDliHook __pfnDliFailureHook2 = delayHook;

Using GetProcAddress and EasyHook to hook class methods and constructors

I've had plenty of success using EasyHook to hook system API routines (in C++) out of libraries. These libraries have always been flat and basically filled with globally callable routines. Here is a small sample using MessageBeep() out of the User32.dll library (minus setup code):
HMODULE hUser32 = GetModuleHandle ( L"User32" );
FARPROC TrampolineMethod; // This would have been set to my new replacement trampoline method.
TRACED_HOOK_HANDLE hHook = new HOOK_TRACE_INFO();
NTSTATUS status;
status = LhInstallHook(
GetProcAddress(hUser32, "MessageBeep"),
TrampolineMethod,
(PVOID)0x12345678,
hHook);
This is all works great. The problem is, I now have a need to hook methods out of a class, not just a global function. I don't really care about the object itself, I'm really more interested in examining the parameters of the method and that's it. I don't know how to syntactically identify the routine in the function name parameter for GetProcAddress(), and I'm not even sure if GetProcAddress() supports it. For example, I'd like to hook the Pen::SetColor() method out of the gdiplus.dll library:
HMODULE hGDIPlus = GetModuleHandle ( L"Gdiplus" );
FARPROC TrampolineMethod; // This would have been set to my new replacement trampoline method.
TRACED_HOOK_HANDLE hHook = new HOOK_TRACE_INFO();
NTSTATUS status;
status = LhInstallHook(
GetProcAddress(hGDIPlus, "Pen.SetColor"), // this is probably wrong or not possible here
TrampolineMethod,
(PVOID)0x12345678,
hHook);
This doesn't work of course and I don't think the GetProcAddress(hGDIPlus, "Pen.SetColor") is correct. How do I specify a member function of a class to GetProcAddress()? Is this even possible? Also, how would this look if I wanted to hook a constructor such as Pen::Pen()?
The Portable Executable (PE) format that Windows uses doesn't really supports exporting or importing objects or their methods, so that's not what GdiPlus (or any other DLL) uses internally. The object notation is probably an abstraction implemented in the import library for the DLL.
If you take a look at GdiPlus's export table with the Dependency Walker tool (Windows SDK), or similar, you will see
GdipGetPenColor
GdipSetPenColor
etc.
So it is basically no different than the legacy exports, like MessageBeep.

Hooking LoadLibrary API call

I want to load a different version of a DLL than is present in the working directory of the application. For this I need to hook the LoadLibrary call so that when the application makes a call to load the DLL I can substitute it with the newer version of that DLL transparently. I tried using NCodeHook and have the following code in my DLL which I inject into the application using NInjectLib but it crashes while loading kernel32.dll. Can anybody please tell me if this is the correct way of injecting the call or are there any other alternatives.
// CodeHook.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include <NCodeHookInstantiation.h>
#include "CodeHook.h"
#ifdef _MANAGED
#pragma managed(push, off)
#endif
typedef HMODULE (WINAPI *LoadLibraryFPtr)(LPCTSTR dllName);
#pragma data_seg("SHARED")
LoadLibraryFPtr origFunc = NULL;
#pragma data_seg()
#pragma comment(linker, "/section:SHARED,RWS")
HMODULE WINAPI LoadLibraryHook(LPCTSTR dllName)
{
if (origFunc != NULL)
{
return origFunc(dllName);
}
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
CODEHOOK_API void Initialize (void)
{
NCodeHookIA32 nch;
origFunc = nch.createHookByName("kernel32.dll", "LoadLibrary", LoadLibraryHook);
}
#ifdef _MANAGED
#pragma managed(pop)
#endif
I don't know the NCodeHook library, but one important thing to know is that there are actually 2 versions of the LoadLibrary function: LoadLibraryA(LPCSTR) and LoadLibraryW(LPCWSTR). Make sure you hook the correct one and use the appropriate function definition. You may also need to hook LoadLibraryExA/LoadLibraryExW
Detours is a more widely known library for API hooking. Also see this article for more hooking techniques.
I had similar problems of crashes in kernel32.dll when using a hand-written hooking/detours library. I found a good explanation of the problem in the discussion pages of the MinHook library:
As far I understand it, your detour library does not account for the possibility that a function it tries to hook is implemented using a short jump opcode (apparently the LoadLibrary(Ex)W is implemented this way). This will lead to different bytes which need to be replaced during hooking.
Using MinHook for my hooking of LoadLibrary and friends works for me:
HMODULE WINAPI LoadLibraryA_replacement(_In_ LPCTSTR lpFileName)
{
// do your stuff
return loadLibraryA_original(lpFileName);
}
bool installLoadLibraryHook()
{
// Initialize MinHook.
if (MH_Initialize() != MH_OK)
return false;
if (MH_CreateHook(&LoadLibraryA, &LoadLibraryA_replacement,
reinterpret_cast<LPVOID*>(&loadLibraryA_original)) != MH_OK)
return false;
if (MH_EnableHook(&LoadLibraryA) != MH_OK)
return false;
// same for LoadLibraryW, LoadLibraryExW, LoadLibraryExA
return true;
}
There are lots of pitfalls associated with API hooking. I don't know specifics about the NCodeHook implementation, but there is potential for trouble if the API hooking code doesn't properly deal with non-writable pages. One would assume that the library would call VirtualProtect and that the OS would properly handle copy-on-write, but it's hard to say.
I agree with the comment that this might not be the best solution to your problem. API hooking relies on the application binary interface, which is quasi-documented at best. I would not recommend it for a commercial app that is intended for production use.
Side-by-side assemblies would definitely be useful, as the strong name removes any ambiguities about which DLL needs to be loaded. Alternatively, consider using LoadLibraryEx with an absolute path to the DLL and the LOAD_WITH_ALTERED_SEARCH_PATH flag.