basic_hook/
basic_hook.rs

1use substrate::hook_function;
2use std::sync::atomic::{AtomicUsize, Ordering};
3
4static CALL_COUNT: AtomicUsize = AtomicUsize::new(0);
5static mut ORIGINAL_ADD: *mut u8 = std::ptr::null_mut();
6
7unsafe extern "C" fn original_add(a: i32, b: i32) -> i32 {
8    a + b
9}
10
11unsafe extern "C" fn hooked_add(a: i32, b: i32) -> i32 {
12    CALL_COUNT.fetch_add(1, Ordering::Relaxed);
13    println!("hooked_add called with: {} + {}", a, b);
14
15    if !ORIGINAL_ADD.is_null() {
16        let original: extern "C" fn(i32, i32) -> i32 = std::mem::transmute(ORIGINAL_ADD);
17        let result = original(a, b);
18        println!("Original result: {}", result);
19        result + 1000
20    } else {
21        a + b + 1000
22    }
23}
24
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}