sighook
Sighook is a runtime patching crate focused on:
- instruction-level instrumentation via trap instruction + signal handler
- function-entry inline detours (near and far jump)
It is designed for low-level experimentation, reverse engineering, and custom runtime instrumentation workflows.
Features
patchcode(address, opcode)for raw instruction patchinginstrument(address, callback)to trap and then execute original opcodeinstrument_no_original(address, callback)to trap and skip original opcodeinline_hook(addr, replace_fn)with automatic far-jump fallback- zero-copy context remap (
HookContext) in callbacks - architecture-specific callback context (
aarch64andx86_64layouts)
Platform Support
aarch64-apple-darwin: full API support (patchcode/instrument/instrument_no_original/inline_hook)aarch64-apple-ios: full API support (patchcode/instrument/instrument_no_original/inline_hook)aarch64-unknown-linux-gnu: full API support (patchcode/instrument/instrument_no_original/inline_hook)aarch64-linux-android: full API support (patchcode/instrument/instrument_no_original/inline_hook)x86_64-unknown-linux-gnu: full API support; CI smoke validatespatchcode/instrument/instrument_no_original/inline_hookexamples- single-thread model (
static mutinternal state)
Installation
[]
= "0.4.0"
Quick Start
1) BRK instrumentation (execute original opcode)
use ;
extern "C"
let target_instruction = 0x1000_0000_u64;
let _original = instrument?;
# Ok::
2) BRK instrumentation (do not execute original opcode)
use ;
extern "C"
let target_instruction = 0x1000_0010_u64;
let _original = instrument_no_original?;
# Ok::
3) Inline function hook
use inline_hook;
extern "C"
let function_entry = 0x1000_1000_u64;
let replacement_addr = replacement as usize as u64;
let _original = inline_hook?;
# Ok::
Example Loading Model
The examples are cdylib payloads that auto-run hook install logic via constructor sections:
- Apple targets (macOS/iOS) use
__DATA,__mod_init_func+ dyld preload/injection flow - Linux/Android targets use
.init_array+LD_PRELOAD-style flow
When your preload library resolves symbols from the target executable via dlsym, compile the target executable with -rdynamic on Linux/Android.
Android Guide (arm64-v8a)
For authorized security research and your own binaries only.
If your workflow is “build a hook payload .so with sighook, then inject it into an existing target .so with patchelf”, use this pattern:
- Build hook payload
The output is usually:
target/aarch64-linux-android/release/libsighook_payload.so
- Ensure constructor-based init in payload
- Android uses
.init_arrayconstructor flow. - Put hook-install logic in an init function (same pattern as this repo examples).
- Keep hook target symbols stable (for AArch64 examples, prefer explicit patchpoint symbols instead of hardcoded offsets).
- Inject payload into target
.so
Verify DT_NEEDED:
|
- Package both
.sofiles into APK
- Place both files under the same ABI directory:
lib/arm64-v8a/. - Keep SONAME / filenames consistent with what
DT_NEEDEDreferences.
- Re-sign and install APK, then verify
- Sign with your own cert, install on test device, and inspect
logcatfor payload init logs.
Android-specific notes
- Android linker namespace rules may block unexpected library paths/dependencies; keep payload dependencies minimal.
patchelfdoes not bypass SELinux, code-signing, or app sandbox boundaries.- For app-level preload-style experiments, Android
wrap.sh(debuggable app) is another option, butpatchelfpatching is usually more deterministic for fixed target libs.
Linux AArch64 Patchpoint Note
For AArch64 Linux examples, calc-based demos export a dedicated calc_add_insn symbol and patch that symbol directly. This avoids brittle fixed-offset assumptions in toolchain-generated function layout.
API Notes
instrument(...)executes original instruction through an internal trampoline.instrument_no_original(...)skips original instruction unless callback changes control-flow register (pc/rip).inline_hook(...)uses architecture-specific near jump first, then far-jump fallback.
Safety Notes
This crate performs runtime code patching and raw context mutation.
- Ensure target addresses are valid runtime addresses.
- Ensure callback logic preserves ABI expectations.
- Test on disposable binaries first.
License
GPL-2.0-only