hook_function

Function hook_function 

Source
pub unsafe fn hook_function<T>(
    symbol: *mut T,
    replace: *mut T,
) -> Result<*mut T>
Expand description

Type-safe Rust wrapper for hooking functions.

This is a generic wrapper around the C API that provides type safety and Result-based error handling. It’s the recommended way to use the hooking functionality from Rust code.

§Type Parameters

  • T - The function type to hook (typically a function pointer)

§Arguments

  • symbol - Pointer to the function to hook
  • replace - Pointer to your replacement function

§Returns

Ok(*mut T) containing the trampoline pointer to call the original function. Err(SubstrateError) if the hook installation fails.

§Safety

This function is unsafe because it modifies executable code at runtime. Both pointers must be valid function pointers of the correct type.

§Examples

use substrate::hook_function;

extern "C" fn original_func(x: i32) -> i32 { x }
extern "C" fn hooked_func(x: i32) -> i32 { x + 1 }

unsafe {
    let trampoline = hook_function(
        original_func as *mut _,
        hooked_func as *mut _
    ).expect("Hook failed");
}
Examples found in repository?
examples/basic_hook.rs (line 38)
25fn main() {
26    println!("=== Basic Function Hook Example ===\n");
27
28    unsafe {
29        let target = original_add as *mut u8;
30        let hook = hooked_add as *mut u8;
31
32        println!("Target function: {:p}", target);
33        println!("Hook function: {:p}", hook);
34
35        let result = original_add(5, 3);
36        println!("Before hook: 5 + 3 = {}", result);
37
38        match hook_function(target, hook) {
39            Ok(original) => {
40                ORIGINAL_ADD = original;
41                println!("\n✓ Hook installed successfully!");
42                println!("Trampoline (original): {:p}\n", original);
43
44                let result = original_add(5, 3);
45                println!("After hook: 5 + 3 = {}", result);
46
47                let calls = CALL_COUNT.load(Ordering::Relaxed);
48                println!("\nTotal hooked calls: {}", calls);
49            }
50            Err(e) => {
51                eprintln!("✗ Hook failed: {}", e);
52            }
53        }
54    }
55}
More examples
Hide additional examples
examples/error_handling.rs (line 9)
4fn demonstrate_error_handling() {
5    println!("=== Error Handling Example ===\n");
6
7    unsafe {
8        println!("1. Testing null pointer hook:");
9        match hook_function(std::ptr::null_mut::<u8>(), std::ptr::null_mut()) {
10            Ok(_) => println!("  Unexpected success"),
11            Err(SubstrateError::NullPointer) => println!("  ✓ Correctly caught null pointer"),
12            Err(e) => println!("  Different error: {}", e),
13        }
14
15        println!("\n2. Testing library not found:");
16        match utils::find_library("nonexistent.so") {
17            Ok(_) => println!("  Unexpected success"),
18            Err(SubstrateError::LibraryNotFound(name)) => {
19                println!("  ✓ Correctly caught missing library: {}", name)
20            }
21            Err(e) => println!("  Different error: {}", e),
22        }
23
24        println!("\n3. Testing invalid offset string:");
25        match utils::string_to_offset("not_a_hex") {
26            Ok(_) => println!("  Unexpected success"),
27            Err(SubstrateError::ParseError(msg)) => {
28                println!("  ✓ Correctly caught parse error: {}", msg)
29            }
30            Err(e) => println!("  Different error: {}", e),
31        }
32
33        println!("\n4. Testing valid hex parsing:");
34        match utils::string_to_offset("0x123ABC") {
35            Ok(offset) => println!("  ✓ Successfully parsed: 0x{:X}", offset),
36            Err(e) => println!("  ✗ Unexpected error: {}", e),
37        }
38    }
39
40    println!("\n=== All Error Cases Handled ===");
41}