A framework to take the tedium out of code-injection in C++

Calculator Hook

I know I’ve been banging on about injection a lot recently, but I figured a good way to pinch off would be to present some code. After searching and failing, I took it upon myself to write a reusable C++ class to do most of the leg-work for Windows XP/2000/Vista32 DLL injection and hooking. The source is available on the project page.

The process of remote function hooking via a DLL is notoriously messy, so I’ve tried to encapsulate as much of the mess as possible into a C++ class. Here’s an example of some client code that injects a DLL into Windows Calculator, then installs two hooks (one by name and another by address):

// Create the injection object
DLLInjection injection("E:/Temp/HookDLL.dll");
 
// Find Calc.exe by its window
DWORD process_id = injection.GetProcessIDFromWindow("SciCalc", "Calculator");
 
// Inject the DLL
HMODULE remote_module = injection.InjectDLL(process_id);
 
// Hook a DLL function (User32!SetWindowTextW)
HDLLHOOK swtw_hook = injection.InstallDLLHook("C:/Windows/System32/User32.dll", "SetWindowTextW", "SetWindowTextHookW");
 
// Hook a function manually (Calc!0100F3CF)
HDLLHOOK manual_hook = injection.InstallCodeHook(reinterpret_cast <void*> (0x0100F3CF), "SomeOtherHook");
 
// Remove the hooks
injection.RemoveHook(swtw_hook);
injection.RemoveHook(manual_hook);

Testing has been limited so don’t be surprised to find bugs. If you do find any, please report them via email or comment.

11 Responses to “A framework to take the tedium out of code-injection in C++”

  1. Hello, happy new year, thank you very much for this clear and well documented code!
    This is better than a thousand words to understand how it works.

    There is something I do not understand. Let’s say I want to use this class to hook for example CreateDevice method from directx.
    I run a “launcher” which injects the hook dll in the target process, and installs the hook. Now when the target process calls CreateDevice, it calls CreateDeviceHook in my dll.
    But CreateDeviceHook needs to call the original function….DirectX CreateDevice.
    And unfortunately, only the launcher is able to remove the patch.

    I suppose the only way to use it properly (like in your previous DX hook example) would be to split code in two classes.
    One for injection, one for installing/uninstalling hook.

    Launcher uses injection class to inject dll.
    And dll uses hook class to install/uninstall hooks during initialization and later in hook functions.

  2. Hi Juls.

    Sorry for the delayed response - you’ll have to take my word for it when I say I’ve been very busy.

    But yes, you’re right. This functionality is desperately lacking. Even the cleanest solution would involve some level of inter-process communication, which would involve a bit more work, and so for the moment I can afford to do no more than put this task on the to-do list.

    If you need a quick fix I suggest you take a look at Microsoft’s Detours. From what I’ve gathered, it does much the same as the framework presented here but it also supports self-referencing as you require. So much for reinventing the wheel :(

  3. If the DLL installs and removes the hooks itself, there is no need for inter-process communication with the “injector”, right?

    I suppose that’s why fraps use SetWindowsHookEx injection. They want the DLL to install/uninstall hooks.
    They can not do it in DLL initialisation function because it is too heavy and DLL initialisation may be performed before target DLLs are loaded.

    That is maybe why they prefer to have a DLL function called regularly through windows hook chain.

  4. That’s true at first glance, but what I was really worried about is safely maintaining state. Situations exist where external installation of the hook is preferable, as do others when the DLL should be responsible. For this reason, I’d like to support both methods. However, the two interfaces shouldn’t really be treated separately or the design could lead to tricky bugs involving double-freeing or interlaced patching. Ideally, both the outside- and inside-elements would be aware of the global status of each patch (which is more complicated than a straightforward boolean, but that’s not too important). This way, the hook could be installed by the injector and removed from within the injectee, for example, without any crashes.

    Feasibly, the external interface could be made to work via the injected DLL’s interface, but I’d rather not force users to conform to strict standards on how their DLLs should be written. It’ll take a little brainstorming but I’m sure a good method will present itself. It’s just a matter of finding the time.

    Anyway, thanks for the approval and appreciation. It’s reassuring to know that my work is helping others :)

  5. Eh…yes, it could be very elegant if the “injector” was working via the injected DLL.
    If injection functions are exported in the DLL, and info about current hooks are stored in a memory area shared among all instances of the DLL. Then the “injector” application just has to call these functions, and the DLL loaded in the target thread knows eveything about current hooks and can uninstall/reinstall them at will.

    I have another question. Let’s say I hook a function in a DLL, replacing the first 5 bytes with a jump to my function. My function then does its job, restores the 5 bytes and calls the real DLL function, and changes again the 5 bytes. Like you did with this fraps-like hook.
    What happens if I use this on a DLL shared among processes, like kernel or user…multiple threads may call the hook at the same time. Using a semaphore to protect the hook function is not enough, because the semaphore is placed after the jump…it does not prevent other threads to execute instructions in the 5 bytes area which is modified.

    The only solution then is to use a hook with two jumps…a jump toward another jump (protected with a semaphore). Then only the second jump, protected, is changed to install/uninstall the hook.
    I did not check what microsoft detours does, but I suppose that’s what they call trampoline?

  6. Hem…in fact hooking user32 or kernel32 this way (replacing 5 bytes with a jump to a dll) should not work at all, because all processes calling this function will jump at the same place in their memory space, and the dll may be loaded at a different place.
    This is strange because microsoft detours is using this kind of hook, and it seems some people do it with user32 and kernel32 functions. I am lost.

  7. sorry for useless “comments”. I suppose user32 and kernel32 are not shared among processes, it would not work at all…they are just loaded at the same place in virtual memory. Detours Trampoline functions are nicer because they allow to call original function without uninstalling/reinstalling the hook, avoiding conflicts between threads.

  8. That’s a decent summary of what needs doing to bring this project up to scratch ;)

    For the record, no DLLs are shared between processes in their entirety anymore. It’s possible and not uncommon to share a data segment between all instances of a DLL, but no part of the user-mode core (user32, kernel32 or ntdll) is shared in any such way - not since the Windows 95 family. Nevertheless, this removable patch system won’t be very safe for any multi-threaded applications for exactly the same reasons, as you pointed out.

    And yes - Detours does some voodoo with trampolines and copied instances of function instructions (I don’t know the details), presumably to allow multi-threading, among other things. It’s a clever solution to a tricky problem but I’m reluctant to copy it at the risk of reinventing the wheel.

  9. I checked detours. They do several advanced hooks, but the basic principle is the same. Replace the firs 5 bytes of the target function with a jump.

    But to avoid unhooking/hooking all the time if you want to call the original function, they rebuild this original function somewhere else.
    They copy the 5 bytes of the original function (replaced with the hook) at the beginning of another function, followed by a jump to the remaining of the original function. That’s what they call a trampoline…it is just a way to call the original function without removing/reinstalling the hook.

    With this system, you can have problem with multithreaded apps only during hook install and remove, which happen only once. Looks a lot safer, faster! and not so much complicated if you override a dummy function from the dll to create the trampoline. In detours they create the trampoline function on the fly in memory.

  10. I’m not sure how to call a function in the dll after it has been hooked… Could this be explained any. Thanks!

  11. Will this inject a DLL into a 32-bit application on a x64 OS? (Just concerned about injection not the hooks)

Leave a Reply