1use crate::error::{Result, SubstrateError};
2use std::ffi::CStr;
3use std::fs::File;
4use std::io::{BufRead, BufReader};
5use std::os::raw::{c_char, c_void};
6
7pub fn find_library(library_name: &str) -> Result<usize> {
8 let maps_file = File::open("/proc/self/maps").map_err(|e| {
9 SubstrateError::FileNotFound(format!("Failed to open /proc/self/maps: {}", e))
10 })?;
11
12 let reader = BufReader::new(maps_file);
13
14 for line in reader.lines() {
15 let line = line.map_err(|e| {
16 SubstrateError::ParseError(format!("Failed to read line: {}", e))
17 })?;
18
19 if line.contains(library_name) {
20 let parts: Vec<&str> = line.split_whitespace().collect();
21 if !parts.is_empty() {
22 if let Some(addr_str) = parts[0].split('-').next() {
23 return usize::from_str_radix(addr_str, 16).map_err(|e| {
24 SubstrateError::ParseError(format!("Failed to parse address: {}", e))
25 });
26 }
27 }
28 }
29 }
30
31 Err(SubstrateError::LibraryNotFound(library_name.to_string()))
32}
33
34pub fn get_absolute_address(library_name: &str, relative_addr: usize) -> Result<usize> {
35 let base = find_library(library_name)?;
36 Ok(base + relative_addr)
37}
38
39pub fn is_library_loaded(library_name: &str) -> bool {
40 if let Ok(file) = File::open("/proc/self/maps") {
41 let reader = BufReader::new(file);
42 for line in reader.lines().flatten() {
43 if line.contains(library_name) {
44 return true;
45 }
46 }
47 }
48 false
49}
50
51pub fn string_to_offset(s: &str) -> Result<usize> {
52 let s = s.trim_start_matches("0x").trim_start_matches("0X");
53 usize::from_str_radix(s, 16).map_err(|e| {
54 SubstrateError::ParseError(format!("Failed to parse offset: {}", e))
55 })
56}
57
58#[no_mangle]
59pub unsafe extern "C" fn findLibrary(library: *const c_char) -> usize {
60 if library.is_null() {
61 return 0;
62 }
63
64 let library_name = match CStr::from_ptr(library).to_str() {
65 Ok(s) => s,
66 Err(_) => return 0,
67 };
68
69 find_library(library_name).unwrap_or(0)
70}
71
72#[no_mangle]
73pub unsafe extern "C" fn getAbsoluteAddress(library: *const c_char, offset: usize) -> usize {
74 if library.is_null() {
75 return 0;
76 }
77
78 let library_name = match CStr::from_ptr(library).to_str() {
79 Ok(s) => s,
80 Err(_) => return 0,
81 };
82
83 get_absolute_address(library_name, offset).unwrap_or(0)
84}
85
86#[no_mangle]
87pub unsafe extern "C" fn isLibraryLoaded(library: *const c_char) -> bool {
88 if library.is_null() {
89 return false;
90 }
91
92 let library_name = match CStr::from_ptr(library).to_str() {
93 Ok(s) => s,
94 Err(_) => return false,
95 };
96
97 is_library_loaded(library_name)
98}
99
100#[no_mangle]
101pub unsafe extern "C" fn string2Offset(s: *const c_char) -> usize {
102 if s.is_null() {
103 return 0;
104 }
105
106 let string = match CStr::from_ptr(s).to_str() {
107 Ok(s) => s,
108 Err(_) => return 0,
109 };
110
111 string_to_offset(string).unwrap_or(0)
112}
113
114#[no_mangle]
115pub unsafe extern "C" fn hook(
116 offset: *mut c_void,
117 ptr: *mut c_void,
118 orig: *mut *mut c_void,
119) {
120 #[cfg(target_arch = "aarch64")]
121 {
122 crate::A64HookFunction(offset, ptr, orig);
123 }
124
125 #[cfg(not(target_arch = "aarch64"))]
126 {
127 crate::MSHookFunction(offset, ptr, orig);
128 }
129}