# PolyHook2.NET
**Repository Path**: keyestore/PolyHook2.NET
## Basic Information
- **Project Name**: PolyHook2.NET
- **Description**: cPolyHook2 的简单 PInvoke 封装类
- **Primary Language**: C#
- **License**: MIT
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-07-28
- **Last Updated**: 2026-07-28
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README

# PolyHook2.NET
**PolyHook2.NET** is a managed .NET wrapper around the [CPolyHook2](https://gitlab.com/Rawra/cpolyhook2) library (a C API for [PolyHook2](https://github.com/stevemk14ebr/PolyHook_2_0)).
| CI/CD | Release | NuGet | Coverage | Tech Stack | Platform | License |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| [](https://gitlab.com/Rawra/PolyHook2.NET/-/pipelines) | [](https://gitlab.com/Rawra/PolyHook2.NET/-/releases) | [](https://www.nuget.org/packages/PolyHook2.NET/) | [](https://gitlab.com/Rawra/PolyHook2.NET/-/commits/main) |     |   | [](https://opensource.org/licenses/MIT)
This project exposes PolyHook2's core C++ classes and functionality through a managed interface.
## Features
This library provides direct, P/Invoke wrappers for major PolyHook2 components, including:
* **Detours:** `X86Detour`, `X64Detour`, `NATDetour`
* **PE Hooks:** `IATHook`, `EATHook`
* **Exception-Based Hooks:** `BreakPointHook->SWPB`, `HWBreakPointHook->HWBP`, `AVehHook->VEHHook`
* **Virtual Function/Table Hooks:** `VFuncSwapHook`, `VTableSwapHook`
* **Utilities:** `MemAccessor`, `ILCallback`, `RangeAllocator`, `ErrorLog` and more.
## Add-ons
Check out the following add-ons that build upon PolyHook2.NET.
* **[PolyHook2.NET.Attributes](https://gitlab.com/Rawra/polyhook2.net.attributes):** Attribute-driven detour creation.
## Building the Project
The project is configured for a straightforward build process using standard .NET tooling. No special dependencies outside of the .NET SDK are required.
### Prerequisites
* **.NET 8 SDK (or later):** The SDK is required to build, test, and pack the project. The .NET 8 SDK includes the necessary compilers and targeting packs for both `.NET 8` and `.NET Framework 4.8`. [Download .NET SDK](https://dotnet.microsoft.com/download).
#### Building with Visual Studio / Rider
1. **Clone the repository:**
`git clone https://gitlab.com/Rawra/PolyHook2.NET.git`
2. **Navigate to the directory:**
`cd PolyHook2.NET`
3. **Open the Solution:**
Open the `PolyHook2.NET.sln` file in your IDE.
4. **Build the Solution:**
* Set the solution configuration to **Release**.
* Build the solution using the build command (e.g., `Ctrl+Shift+B` in Visual Studio or from the `Build` menu).
#### Building with the Command Line (.NET CLI)
1. **Clone the repository:**
`git clone https://gitlab.com/Rawra/PolyHook2.NET.git`
2. **Navigate to the directory:**
`cd PolyHook2.NET`
3. **Restore NuGet Packages:**
Run the `restore` command to download all required dependencies.
`dotnet restore`
4. **Build the Project:**
Execute the `build` command. Using the `Release` configuration is recommended for an optimized build.
`dotnet build --configuration Release`
### Build Output
After a successful build, the compiled artifacts will be located in the `bin/` folder at the root of the solution directory. The structure will be as follows:
```
/bin
└───/Release
├───/net48
│ └─── PolyHook2.NET.dll
│
└───/net8.0
└─── PolyHook2.NET.dll
```
Don't forget to include the `runtimes` folder where ever you put the managed library.
### Example Usage
This example showcases a simple X64Detour (Taken from the UnitTests):
```csharp
private static X64Detour? _hook;
[Fact]
public void Detour_RedirectsAndRestoresCorrectly()
{
delegate* unmanaged[Cdecl] fnAddress = &OriginalFunction;
delegate* unmanaged[Cdecl] fnCallback = &HookedFunction;
Assert.Equal(15, fnAddress(10, 5));
_hook = new X64Detour((ulong)fnAddress, (ulong)fnCallback);
Assert.True(_hook.Hook());
Assert.NotEqual((UInt64)0, _hook.TrampolineAddress);
// Calling the original pointer should now execute our hook.
// Our hook calls the original (10 + 5 = 15) and multiplies the result by 10.
Assert.Equal(150, fnAddress(10, 5));
Assert.True(_hook.UnHook());
// The original function pointer should now be restored to its original behavior.
Assert.Equal(15, fnAddress(10, 5));
_hook.Dispose();
}
///
/// The original function we intend to hook. It returns the sum of its inputs.
///
[UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvCdecl) })]
private static int OriginalFunction(int a, int b)
{
return a + b;
}
///
/// Our detour callback. It must have the exact same signature as the original.
/// It calls the original function via the trampoline and modifies its result.
///
[UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvCdecl) })]
private static int HookedFunction(int a, int b)
{
// Call the original function via the trampoline and multiply the result.
return ((delegate* unmanaged[Cdecl])_hook!.TrampolineAddress)(a, b) * 10;
}
```