1pub mod arch;
2pub mod debug;
3pub mod disasm;
4pub mod error;
5pub mod hook;
6pub mod symbol;
7pub mod utils;
8
9use error::{Result, SubstrateError};
10use std::ffi::CStr;
11use std::os::raw::{c_char, c_int, c_void};
12use std::ptr;
13use std::sync::atomic::{AtomicBool, Ordering};
14
15pub type MSImageRef = *const c_void;
16
17static MS_DEBUG: AtomicBool = AtomicBool::new(false);
18
19#[no_mangle]
20pub static mut MSDebug: bool = false;
21
22pub fn set_debug(enabled: bool) {
23 MS_DEBUG.store(enabled, Ordering::Relaxed);
24 unsafe { MSDebug = enabled; }
25}
26
27pub fn is_debug() -> bool {
28 MS_DEBUG.load(Ordering::Relaxed)
29}
30
31#[no_mangle]
32pub unsafe extern "C" fn MSHookFunction(
33 symbol: *mut c_void,
34 replace: *mut c_void,
35 result: *mut *mut c_void,
36) {
37 if symbol.is_null() {
38 return;
39 }
40
41 let result_ptr = if result.is_null() {
42 ptr::null_mut()
43 } else {
44 result as *mut *mut u8
45 };
46
47 #[cfg(target_arch = "x86_64")]
48 {
49 let _ = arch::x86_64::hook_function_x86_64(
50 symbol as *mut u8,
51 replace as *mut u8,
52 result_ptr,
53 );
54 }
55
56 #[cfg(target_arch = "arm")]
57 {
58 let symbol_addr = symbol as usize;
59 if (symbol_addr & 0x1) == 0 {
60 let _ = arch::arm::hook_function_arm(
61 symbol as *mut u8,
62 replace as *mut u8,
63 result_ptr,
64 );
65 } else {
66 let _ = arch::thumb::hook_function_thumb(
67 (symbol_addr & !0x1) as *mut u8,
68 replace as *mut u8,
69 result_ptr,
70 );
71 }
72 }
73
74 #[cfg(target_arch = "aarch64")]
75 {
76 let _ = arch::aarch64::hook_function_aarch64(
77 symbol as *mut u8,
78 replace as *mut u8,
79 result_ptr,
80 );
81 }
82}
83
84#[no_mangle]
85pub unsafe extern "C" fn A64HookFunction(
86 symbol: *mut c_void,
87 replace: *mut c_void,
88 result: *mut *mut c_void,
89) {
90 MSHookFunction(symbol, replace, result);
91}
92
93#[no_mangle]
94pub unsafe extern "C" fn MSFindSymbol(_image: MSImageRef, name: *const c_char) -> *mut c_void {
95 if name.is_null() {
96 return ptr::null_mut();
97 }
98
99 let _symbol_name = match CStr::from_ptr(name).to_str() {
100 Ok(s) => s,
101 Err(_) => return ptr::null_mut(),
102 };
103
104 ptr::null_mut()
105}
106
107#[no_mangle]
108pub unsafe extern "C" fn MSGetImageByName(_file: *const c_char) -> MSImageRef {
109 ptr::null()
110}
111
112#[no_mangle]
113pub unsafe extern "C" fn MSHookProcess(_pid: c_int, _library: *const c_char) -> bool {
114 false
115}
116
117pub unsafe fn hook_function<T>(symbol: *mut T, replace: *mut T) -> Result<*mut T> {
118 if symbol.is_null() || replace.is_null() {
119 return Err(SubstrateError::NullPointer);
120 }
121
122 let mut result: *mut T = ptr::null_mut();
123
124 #[cfg(target_arch = "x86_64")]
125 {
126 arch::x86_64::hook_function_x86_64(
127 symbol as *mut u8,
128 replace as *mut u8,
129 &mut result as *mut *mut T as *mut *mut u8,
130 )?;
131 }
132
133 #[cfg(target_arch = "arm")]
134 {
135 let symbol_addr = symbol as usize;
136 if (symbol_addr & 0x1) == 0 {
137 arch::arm::hook_function_arm(
138 symbol as *mut u8,
139 replace as *mut u8,
140 &mut result as *mut *mut T as *mut *mut u8,
141 )?;
142 } else {
143 arch::thumb::hook_function_thumb(
144 (symbol_addr & !0x1) as *mut u8,
145 replace as *mut u8,
146 &mut result as *mut *mut T as *mut *mut u8,
147 )?;
148 }
149 }
150
151 #[cfg(target_arch = "aarch64")]
152 {
153 arch::aarch64::hook_function_aarch64(
154 symbol as *mut u8,
155 replace as *mut u8,
156 &mut result as *mut *mut T as *mut *mut u8,
157 )?;
158 }
159
160 #[cfg(not(any(target_arch = "x86_64", target_arch = "arm", target_arch = "aarch64")))]
161 {
162 return Err(SubstrateError::HookFailed("Architecture not implemented".to_string()));
163 }
164
165 Ok(result)
166}
167
168pub fn find_symbol_in_process(
169 pid: libc::pid_t,
170 library: &str,
171 symbol: &str,
172) -> Result<*mut c_void> {
173 let addr = symbol::finder::find_symbol_address(pid, symbol, library)?;
174 Ok(addr as *mut c_void)
175}