Skip to main content

dobby_rs_framework/hook_utils/
builder.rs

1use super::{Callback, HookHandle, install_raw, registry};
2use crate::{Error, Result};
3use core::ffi::c_void;
4use log::{debug, info};
5use std::sync::Arc;
6
7pub struct HookBuilder {
8    target: *mut c_void,
9    detour: *mut c_void,
10    before: Option<Callback>,
11    after: Option<Callback>,
12}
13
14impl HookBuilder {
15    pub fn new(target: *mut c_void, detour: *mut c_void) -> Self {
16        Self {
17            target,
18            detour,
19            before: None,
20            after: None,
21        }
22    }
23    pub fn before<F: Fn() + Send + Sync + 'static>(mut self, callback: F) -> Self {
24        self.before = Some(Arc::new(callback));
25        self
26    }
27    pub fn after<F: Fn() + Send + Sync + 'static>(mut self, callback: F) -> Self {
28        self.after = Some(Arc::new(callback));
29        self
30    }
31    pub unsafe fn install(self) -> Result<HookHandle> {
32        if self.target.is_null() || self.detour.is_null() {
33            return Err(Error::NullPointer);
34        }
35        if registry::contains(self.target as usize, self.detour as usize) {
36            return Err(Error::AlreadyHooked);
37        }
38        debug!(
39            "installing hook target={:p} detour={:p}",
40            self.target, self.detour
41        );
42        let h = install_raw(self.target, self.detour, self.before, self.after)?;
43        info!(
44            "hook installed target={:p} detour={:p}",
45            h.target_ptr(),
46            h.detour_ptr()
47        );
48        Ok(h)
49    }
50}