1use dobby_sys::ffi;
34use std::ffi::{c_void, CString};
35
36pub type Address = *mut c_void;
37
38pub fn resolve_symbol(image_name: &str, symbol_name: &str) -> Option<Address> {
43 let image_name = CString::new(image_name).unwrap();
44 let symbol_name = CString::new(symbol_name).unwrap();
45
46 let addr = unsafe { ffi::DobbySymbolResolver(image_name.as_ptr(), symbol_name.as_ptr()) };
47 if addr.is_null() {
48 None
49 } else {
50 Some(addr)
51 }
52}
53
54#[derive(Debug, thiserror::Error)]
55pub enum DobbyHookError {
56 #[error("hook error")]
57 HookError,
58}
59
60pub unsafe fn hook(addr: Address, replace: Address) -> Result<Address, DobbyHookError> {
64 let mut origin = std::ptr::null_mut();
65 hook_and_update_origin(addr, replace, &mut origin)?;
66 Ok(origin)
67}
68
69pub unsafe fn hook_and_update_origin(
73 addr: Address,
74 replace: Address,
75 origin: &mut Address,
76) -> Result<(), DobbyHookError> {
77 let ret = ffi::DobbyHook(addr, replace, origin as *mut _);
78 if ret == 0 {
79 Ok(())
80 } else {
81 Err(DobbyHookError::HookError)
82 }
83}
84
85pub unsafe fn unhook(addr: Address) -> Result<(), DobbyHookError> {
89 let ret = ffi::DobbyDestroy(addr);
90 if ret == 0 {
91 Ok(())
92 } else {
93 Err(DobbyHookError::HookError)
94 }
95}
96
97#[derive(Debug, thiserror::Error)]
98pub enum DobbyMemoryOperationError {
99 #[error("memory operation error")]
100 MemoryOperationError,
101 #[error("not enough memory")]
102 NotEnough,
103 #[error("not support allocate executable memory")]
104 NotSupportAllocateExecutableMemory,
105 #[error("unknown error")]
106 None,
107}
108
109pub unsafe fn patch_code(addr: Address, code: &[u8]) -> Result<(), DobbyMemoryOperationError> {
113 let ret = ffi::CodePatch(addr, code.as_ptr() as *mut _, code.len() as u32);
114 match ret {
115 ffi::MemoryOperationError_kMemoryOperationSuccess => Ok(()),
116 ffi::MemoryOperationError_kMemoryOperationError => {
117 Err(DobbyMemoryOperationError::MemoryOperationError)
118 }
119 ffi::MemoryOperationError_kNotEnough => Err(DobbyMemoryOperationError::NotEnough),
120 ffi::MemoryOperationError_kNotSupportAllocateExecutableMemory => {
121 Err(DobbyMemoryOperationError::NotSupportAllocateExecutableMemory)
122 }
123 ffi::MemoryOperationError_kNone => Err(DobbyMemoryOperationError::None),
124 _ => unreachable!(),
125 }
126}