Hi!
I'm playing with detouring functions using the detour-rs crate. I'm now thinking of a situation where I want to keep track of some state in the function I detour to. So far the only thing have found that works is using static mutable variables. I have modified a detour-rs example below to illustrate what I want to do (replace add5
with add_extra
that instead adds 5 + something extra).
Another option I considered was passing state as a mutable borrow to the add_extra
function. The hooked close then however becomes FnMut while the static detour initialization requires it to be Fn.
I am aware that the solution I got to work is not safe. And now I'm wondering if there is a better/safer solution, or is this the best I can achieve?
use std::error::Error;
use detour::static_detour;
static_detour! {
static Test: /* extern "X" */ fn(i32) -> i32;
}
static mut EXTRA_SUM: i32 = 0;
fn add5(val: i32) -> i32 {
val + 5
}
fn add_extra_static(val: i32) -> i32 {
unsafe { EXTRA_SUM += 1} ;
Test.call(val) + unsafe { EXTRA_SUM }
}
fn main() -> Result<(), Box<dyn Error>> {
let hooked = |val| add_extra_static(val);
unsafe { Test.initialize(add5, hooked)?.enable()? };
assert_eq!(add5(1), 7);
assert_eq!(add5(1), 8);
Ok(())
}