PolyHook2.NET 1.0.4

There is a newer version of this package available.
See the version list below for details.
dotnet add package PolyHook2.NET --version 1.0.4
                    
NuGet\Install-Package PolyHook2.NET -Version 1.0.4
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="PolyHook2.NET" Version="1.0.4" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="PolyHook2.NET" Version="1.0.4" />
                    
Directory.Packages.props
<PackageReference Include="PolyHook2.NET" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add PolyHook2.NET --version 1.0.4
                    
#r "nuget: PolyHook2.NET, 1.0.4"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package PolyHook2.NET@1.0.4
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=PolyHook2.NET&version=1.0.4
                    
Install as a Cake Addin
#tool nuget:?package=PolyHook2.NET&version=1.0.4
                    
Install as a Cake Tool

<div align="center">

<img src="logo.png" alt="Logo (original by 100 Capybaras)" width="128" height="128"/>

PolyHook2.NET

PolyHook2.NET is a managed .NET wrapper around the CPolyHook2 library (a C API for PolyHook2). <br/>

CI/CD Release NuGet Coverage Tech Stack Platform License
pipeline status latest release NuGet Downloads coverage report .NET 4.8.1 .NET 4.8.1 C# Static Badge Windows Static Badge License: LGPLv2

</div>

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, and more.

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.
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):

private static X64Detour? _hook;

[Fact]
public void Detour_RedirectsAndRestoresCorrectly()
{
    delegate* unmanaged[Cdecl]<int, int, int> fnAddress = &OriginalFunction;
    delegate* unmanaged[Cdecl]<int, int, int> 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();
}

/// <summary>
/// The original function we intend to hook. It returns the sum of its inputs.
/// </summary>
[UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvCdecl) })]
private static int OriginalFunction(int a, int b)
{
    return a + b;
}

/// <summary>
/// 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.
/// </summary>
[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]<int, int, int>)_hook!.TrampolineAddress)(a, b) * 10;
}
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Framework net48 is compatible.  net481 was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (3)

Showing the top 3 NuGet packages that depend on PolyHook2.NET:

Package Downloads
Nice3point.TUnit.Revit

.NET testing framework for Revit

Nice3point.BenchmarkDotNet.Revit

.NET benchmarking library for Revit

PolyHook2.NET.Attributes

Provides attribute-based, high-performance hooking for PolyHook2.NET using a source generator.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.1.3 549 11/19/2025
1.1.2 159 9/27/2025
1.1.0 137 9/27/2025
1.0.6 273 9/22/2025
1.0.5 212 9/22/2025
1.0.4 190 9/20/2025
1.0.1 245 9/19/2025