├── InjectHook.h ├── LICENSE ├── InjectHook.cpp └── README.md /InjectHook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace HookLib { 4 | // Enum for different jump types. Additional jump types can be added as needed by the user. 5 | enum HookType { 6 | JMP_LONG 7 | }; 8 | 9 | // Installs a hook on a specific function. 10 | bool InstallHook(void* targetFunction, void* hookAddress, HookType type); 11 | 12 | // Removes the hook. 13 | bool RemoveHook(void* targetFunction); 14 | } 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Bruno Garcia 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /InjectHook.cpp: -------------------------------------------------------------------------------- 1 | #include "InjectHook.h" 2 | #include 3 | #include 4 | 5 | namespace HookLib { 6 | 7 | struct HookData { 8 | BYTE originalBytes[5]; 9 | void* targetFunction; 10 | }; 11 | 12 | std::map hooks; 13 | 14 | bool InstallHook(void* targetFunction, void* hookAddress, HookType type) { 15 | DWORD oldProtect; 16 | HookData data; 17 | 18 | // Save the original bytes of the target function. 19 | memcpy(data.originalBytes, targetFunction, 5); 20 | data.targetFunction = targetFunction; 21 | hooks[targetFunction] = data; 22 | 23 | // Change memory protection to read/write. 24 | VirtualProtect(targetFunction, 5, PAGE_EXECUTE_READWRITE, &oldProtect); 25 | 26 | // Apply the hook based on the specified type. 27 | switch (type) { 28 | case JMP_LONG: { 29 | DWORD relativeAddress = ((DWORD)hookAddress - (DWORD)targetFunction) - 5; 30 | *(BYTE*)targetFunction = 0xE9; 31 | *(DWORD*)((DWORD)targetFunction + 1) = relativeAddress; 32 | break; 33 | } 34 | // Additional jump types can be added here. 35 | default: 36 | break; 37 | } 38 | 39 | // Restore the original memory protection. 40 | VirtualProtect(targetFunction, 5, oldProtect, &oldProtect); 41 | 42 | return true; 43 | } 44 | 45 | bool RemoveHook(void* targetFunction) { 46 | auto it = hooks.find(targetFunction); 47 | if (it == hooks.end()) return false; 48 | 49 | DWORD oldProtect; 50 | VirtualProtect(targetFunction, 5, PAGE_EXECUTE_READWRITE, &oldProtect); 51 | memcpy(targetFunction, it->second.originalBytes, 5); 52 | VirtualProtect(targetFunction, 5, oldProtect, &oldProtect); 53 | 54 | hooks.erase(it); 55 | 56 | return true; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # InjectHook 2 | A lightweight C++ library designed for function interception within injected DLLs, providing a streamlined approach to modifying application behavior at runtime. Ideal for educational purposes, debugging, and dynamic software analysis. 3 | 4 | 5 | # InjectHook: C++ Function Hooking Library for DLL Injection 6 | 7 | `InjectHook` is a C++ library designed to facilitate function interception within injected DLLs, enabling modification of target application behavior at runtime. 8 | 9 | ## Table of Contents 10 | - [Installation](#installation) 11 | - [Usage](#usage) 12 | - [Preparing for DLL Injection](#preparing-for-dll-injection) 13 | - [Hooking a Function](#hooking-a-function) 14 | - [Removing a Hook](#removing-a-hook) 15 | - [Notes](#notes) 16 | 17 | ## Installation 18 | 19 | 1. Add the `InjectHook.h` and `InjectHook.cpp` files to your DLL project. 20 | 2. Include `InjectHook.h` wherever you intend to leverage the hooking functionalities. 21 | 22 | ## Usage 23 | 24 | ### Preparing for DLL Injection 25 | 26 | Your DLL should have an entry point, typically the `DllMain` function, which is called upon injection: 27 | 28 | ```cpp 29 | BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { 30 | switch (ul_reason_for_call) { 31 | case DLL_PROCESS_ATTACH: 32 | // Actions to perform when the DLL is injected 33 | break; 34 | case DLL_PROCESS_DETACH: 35 | // Actions to perform when the DLL is unloaded 36 | break; 37 | // Handle other cases if required 38 | } 39 | return TRUE; 40 | } 41 | ``` 42 | 43 | ### Hooking a Function 44 | 45 | Inside the `DLL_PROCESS_ATTACH` case or another suitable location, use the `InstallHook` function to initiate a hook: 46 | 47 | ```cpp 48 | bool InstallHook(void* targetFunction, void* hookFunction, HookType type); 49 | ``` 50 | 51 | - `targetFunction`: Memory address of the function you aim to hook in the target process. 52 | - `hookFunction`: Pointer to your `naked` function that will control flow redirection and push registers. 53 | - `type`: Type of hook. Currently, only `JMP_LONG` is supported, but additional jump types can be added by the user as needed. 54 | 55 | **Example**: 56 | 57 | ```cpp 58 | 59 | __declspec(naked) void MyNakedFunction() { // Just an example 60 | const continueAddress = 0x12345678; 61 | const endFunctionAdress = 0x12345123; 62 | __asm { 63 | // Restore the overwritten assembly here 64 | mov eax, dword ptr ds:[ebp-0214h] 65 | sar eax, 2 66 | 67 | // Push some registers, etc 68 | push dword ptr ss:[ebp+8] 69 | mov eax, dword ptr ss:[ebp+0ch] 70 | push eax 71 | lea edx 72 | 73 | // Call the __stdcall hook handler. 74 | call HookHandlerFunction 75 | 76 | // Test the return of the hook handler 77 | test eax, eax 78 | je canContinue 79 | 80 | jmp endFunctionAdress 81 | 82 | canContinue: 83 | // Continue the normal execution flow 84 | jmp continueAddress 85 | } 86 | } 87 | 88 | void __stdcall HookHandlerFunction(int *param1, int param2, int ¶m3) { 89 | // This is the function that gets called from the naked function. 90 | // Use __stdcall calling convention, so you won't need to clean up the stack 91 | // Your hook handling code here. 92 | 93 | *param1 <<= 2; 94 | param3 *= 2; 95 | 96 | return param2 > 0; 97 | } 98 | 99 | BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { 100 | switch (ul_reason_for_call) { 101 | case DLL_PROCESS_ATTACH: 102 | DWORD TargetFunctionAddress = 0x12345678; // Use the target address of the main program 103 | InstallHook((void*)TargetFunctionAddress, &MyNakedFunction, HookLib::JMP_LONG); 104 | break; 105 | } 106 | return TRUE; 107 | } 108 | ``` 109 | 110 | ### Removing a Hook 111 | 112 | To revert to the original behavior: 113 | 114 | ```cpp 115 | bool RemoveHook(void* targetFunction); 116 | ``` 117 | 118 | - `targetFunction`: Memory address of the function you previously hooked. 119 | 120 | **Example**: 121 | 122 | ```cpp 123 | RemoveHook((void*)TargetFunctionAddress); 124 | ``` 125 | 126 | ## Notes 127 | 128 | 1. When using `InjectHook` to hook a function, any overwritten content of the original function will need management within the `naked` hook function. 129 | 2. Ensure no threads are actively executing the hooked functions when setting or removing hooks to prevent unpredictable behaviors. 130 | 3. The library is tailored for the x86 architecture. Ensure compatibility with your target environment. 131 | 4. The hooking mechanism in `InjectHook` currently supports the `JMP_LONG` type, and this will work for most cases. However, users can extend the library to support additional jump types as needed. 132 | 5. You need to inject your generated dll into the target executable, using LoadLibrary. 133 | 134 | --------------------------------------------------------------------------------