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.
InjectHook
is a C++ library designed to facilitate function interception within injected DLLs, enabling modification of target application behavior at runtime.
- Add the
InjectHook.h
andInjectHook.cpp
files to your DLL project. - Include
InjectHook.h
wherever you intend to leverage the hooking functionalities.
Your DLL should have an entry point, typically the DllMain
function, which is called upon injection:
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
// Actions to perform when the DLL is injected
break;
case DLL_PROCESS_DETACH:
// Actions to perform when the DLL is unloaded
break;
// Handle other cases if required
}
return TRUE;
}
Inside the DLL_PROCESS_ATTACH
case or another suitable location, use the InstallHook
function to initiate a hook:
bool InstallHook(void* targetFunction, void* hookFunction, HookType type);
targetFunction
: Memory address of the function you aim to hook in the target process.hookFunction
: Pointer to yournaked
function that will control flow redirection and push registers.type
: Type of hook. Currently, onlyJMP_LONG
is supported, but additional jump types can be added by the user as needed.
Example:
__declspec(naked) void MyNakedFunction() { // Just an example
const continueAddress = 0x12345678;
const endFunctionAdress = 0x12345123;
__asm {
// Restore the overwritten assembly here
mov eax, dword ptr ds:[ebp-0214h]
sar eax, 2
// Push some registers, etc
push dword ptr ss:[ebp+8]
mov eax, dword ptr ss:[ebp+0ch]
push eax
lea edx
// Call the __stdcall hook handler.
call HookHandlerFunction
// Test the return of the hook handler
test eax, eax
je canContinue
jmp endFunctionAdress
canContinue:
// Continue the normal execution flow
jmp continueAddress
}
}
void __stdcall HookHandlerFunction(int *param1, int param2, int ¶m3) {
// This is the function that gets called from the naked function.
// Use __stdcall calling convention, so you won't need to clean up the stack
// Your hook handling code here.
*param1 <<= 2;
param3 *= 2;
return param2 > 0;
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
DWORD TargetFunctionAddress = 0x12345678; // Use the target address of the main program
InstallHook((void*)TargetFunctionAddress, &MyNakedFunction, HookLib::JMP_LONG);
break;
}
return TRUE;
}
To revert to the original behavior:
bool RemoveHook(void* targetFunction);
targetFunction
: Memory address of the function you previously hooked.
Example:
RemoveHook((void*)TargetFunctionAddress);
- When using
InjectHook
to hook a function, any overwritten content of the original function will need management within thenaked
hook function. - Ensure no threads are actively executing the hooked functions when setting or removing hooks to prevent unpredictable behaviors.
- The library is tailored for the x86 architecture. Ensure compatibility with your target environment.
- The hooking mechanism in
InjectHook
currently supports theJMP_LONG
type, and this will work for most cases. However, users can extend the library to support additional jump types as needed. - You need to inject your generated dll into the target executable, using LoadLibrary.