hook.rs (1435B) - raw


      1 use std::sync::Mutex;
      2 
      3 pub static MUTEX: Mutex<()> = Mutex::new(());
      4 
      5 #[macro_export]
      6 macro_rules! def_hook {
      7     ($func:ident, $ret:ty, | $($arg:ident : $arg_type:ty),* | $body:block) => {
      8         paste::item! {
      9             #[allow(non_upper_case_globals)]
     10             static mut [<$func _original>]: std::option::Option<extern "C" fn($($arg_type),*) -> $ret> = None;
     11 
     12             fn $func($($arg: $arg_type),*) -> $ret {
     13                 {
     14                     #[allow(unused_unsafe)]
     15                     unsafe {
     16                         $body
     17                     }
     18                 }
     19             }
     20         }
     21     };
     22 }
     23 
     24 #[macro_export]
     25 macro_rules! dobby_hook {
     26     ($sym:expr, $hook:expr) => {
     27         paste::item! {
     28             unsafe {
     29                 if let Ok(_) = crate::hook::MUTEX.lock() {
     30                     if let Some(ptr) = dobby_rs::hook($sym, $hook as *mut std::ffi::c_void).ok().map(|x| x as *mut std::ffi::c_void) {
     31                         [<$hook _original>] = std::mem::transmute(ptr);
     32                     }
     33                 }
     34             }
     35         }
     36     };
     37 }
     38 
     39 #[macro_export]
     40 macro_rules! dobby_hook_sym {
     41     ($lib:expr, $sym:expr, $hook:expr) => {
     42         if let Some(hook_symbol) = dobby_rs::resolve_symbol($lib, $sym) {
     43             crate::dobby_hook!(hook_symbol, $hook);
     44             debug!("hooked symbol: {}", $sym);
     45         } else {
     46             panic!("Failed to resolve symbol: {}", $sym);
     47         }
     48     };
     49 }
     50