A simple yet powerful C# utility for hooking .NET methods in any assembly at runtime. This tool works by directly manipulating machine code in memory to redirect a target method's execution flow to a custom "detour" method.
It's a practical demonstration of low-level programming concepts within the high-level .NET environment.
The core logic is based on runtime code patching. The process is as follows:
- Load Assembly: The target .NET assembly (
.exeor.dll) is loaded into the application's memory space usingAssembly.UnsafeLoadFrom. - Find Method: .NET Reflection is used to find the metadata of the target method you want to intercept.
- Get Function Pointer: The Just-In-Time (JIT) compiler's function pointer for the native machine code of the method is retrieved.
- Patch Memory: The first few bytes of the original method's machine code are overwritten with a
JMP(unconditional jump) instruction that points to the memory address of our detour method. - Execution: Now, whenever the application calls the original method, the CPU executes the
JMPinstruction and immediately jumps to our custom code instead.
The tool correctly generates the appropriate JMP instruction for both 32-bit (x86) and 64-bit (x64) architectures.
- Runtime Method Hooking: Intercept and alter method behavior on-the-fly.
- x86 & x64 Support: Automatically detects the process architecture and applies the correct machine code patch.
- No Dependencies: Built with standard .NET Framework libraries only.
- Memory Safe: Uses
VirtualProtectto safely change memory permissions before writing and restores them afterward.
- Clone this repository.
- Open the solution in Visual Studio (2019 or newer is recommended).
- Select the target platform (
x64orx86) that matches the target application you intend to hook. - Build the solution (
Build>Build Solution).
The tool is a command-line application. It requires a single argument: the path to the target assembly.
UniversalHooker.exe <path_to_target_assembly>Let's say we have a simple target application, TargetApp.exe, with the following code:
Syntax:
// TargetApp.exe
using System;
public class response_class
{
// This is the method we want to hook.
public bool get_success()
{
return false; // Originally, it returns false.
}
}
public class Program
{
public static void Main()
{
var rc = new response_class();
Console.WriteLine($"The original method returned: {rc.get_success()}");
Console.ReadKey();
}
}When you run TargetApp.exe directly, the output is:
The original method returned: False
Now, let's run it through our hooker. The hooker is hardcoded to replace the logic of get_success with one that always returns true.
UniversalHooker.exe C:\path\to\TargetApp.exeThe output will be:
[+] Assembly loaded: TargetApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
[+] Successfully hooked: response_class.get_success
The original method returned: True <-- The result has been changed by the hook!
[+] Hook disabled successfully.
As you can see, our detour method was executed instead of the original one, changing the program's output without modifying the target executable on disk.
This project is intended for educational and research purposes only. Modifying the runtime behavior of applications can lead to instability and unexpected crashes. The author is not responsible for any damage or misuse of this software. Use it at your own risk and always respect software licensing agreements.