Using GetProcAddress and EasyHook to hook class methods and constructors

2.3k views Asked by At

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()?

1

There are 1 answers

3
500 - Internal Server Error On

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.