Skip to content

sxck36/zig-hook

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

zig-hook

A thin Zig wrapper around MinHook for runtime function hooking on Windows.

Requirements

  • Zig 0.16.0 or newer
  • MSVC ABI (Windows only)
  • Prebuilt MinHook libraries are bundled with this repo

Installation

Fetch the package and save it to your build.zig.zon:

zig fetch --save git+https://github.com/sxck36/zig-hook

Then wire it up in your build.zig:

const zighook = b.dependency("zighook", .{
    .target = target,
    .optimize = optimize,
});
mod.addImport("zighook", zighook.module("zighook"));

Usage

Below is a complete example that hooks kernel32!Sleep, logs the requested delay, calls the original, then uninstalls the hook cleanly.

const std = @import("std");
const win = @import("win32").everything;
const zh = @import("zighook");

var sleep_o: *const fn (u32) callconv(.c) void = undefined;

fn detourSleep(ms: u32) callconv(.c) void {
    std.log.info("sleep hooked: {}ms", .{ms});
    sleep_o(ms);
}

pub fn main() !void {
    var status = zh.initialize();
    if (status != .MH_OK) {
        std.log.err("zh.initialize failed: {}", .{status});
        return;
    }

    const target: ?*anyopaque = @ptrCast(@constCast(&win.Sleep));
    var original: ?*anyopaque = null;

    status = zh.createHook(target, @ptrCast(@constCast(&detourSleep)), &original);
    if (status != .MH_OK) {
        std.log.err("zh.createHook failed: {}", .{status});
        return;
    }
    sleep_o = @ptrCast(original.?);

    status = zh.enableHook(target);
    if (status != .MH_OK) {
        std.log.err("zh.enableHook failed: {}", .{status});
        return;
    }

    std.log.info("hook installed", .{});
    win.Sleep(1000);

    status = zh.disableHook(target);
    if (status != .MH_OK) {
        std.log.err("zh.disableHook failed: {}", .{status});
        return;
    }

    status = zh.removeHook(target);
    if (status != .MH_OK) {
        std.log.err("zh.removeHook failed: {}", .{status});
        return;
    }
    std.log.info("hook removed", .{});

    status = zh.uninitialize();
    if (status != .MH_OK) {
        std.log.err("zh.uninitialize failed: {}", .{status});
        return;
    }
}

Credits

The MinHook library is © Tsuda Kageyu and is distributed under the BSD 2-Clause License. This repository bundles prebuilt MinHook binaries for convenience. The full MinHook license text can be found in MINHOOK_LICENCE.txt.

License

The zighook wrapper code is released into the public domain using The Unlicense. See the LICENCE.txt file for full details. MinHook retains its own BSD-2-Clause license as linked above.

About

A thin Zig wrapper around MinHook for runtime function hooking on Windows.

Resources

License

Stars

2 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages