il2cpp_bridge_rs/memory/info/
image.rs1use dashmap::DashMap;
2use once_cell::sync::Lazy;
3
4static CACHE: Lazy<DashMap<String, usize>> = Lazy::new(DashMap::new);
5
6pub fn get_image_base(name: &str) -> Option<usize> {
10 if let Some(entry) = CACHE.get(name) {
11 return Some(*entry);
12 }
13
14 let addr = platform::find_image_base(name)?;
15 CACHE.insert(name.into(), addr);
16 Some(addr)
17}
18
19pub fn get_image_path(name: &str) -> Option<String> {
24 platform::find_image_path(name)
25}
26
27#[cfg(any(target_os = "macos", target_os = "ios"))]
29mod platform {
30 use mach2::dyld::{_dyld_get_image_header, _dyld_get_image_name, _dyld_image_count};
31 use std::ffi::CStr;
32
33 pub fn find_image_base(name: &str) -> Option<usize> {
34 unsafe {
35 let count = _dyld_image_count();
36 for i in 0..count {
37 let c_name = _dyld_get_image_name(i);
38 if c_name.is_null() {
39 continue;
40 }
41 let path = CStr::from_ptr(c_name).to_string_lossy();
42 if path.contains(name) {
43 let header = _dyld_get_image_header(i);
44 if !header.is_null() {
45 return Some(header as usize);
46 }
47 }
48 }
49 }
50 None
51 }
52
53 pub fn find_image_path(_name: &str) -> Option<String> {
54 None
55 }
56}
57
58#[cfg(any(target_os = "linux", target_os = "android"))]
60mod platform {
61 use std::ffi::CStr;
62
63 pub fn find_image_base(name: &str) -> Option<usize> {
64 struct CallbackData {
65 name: String,
66 result: Option<usize>,
67 }
68
69 unsafe extern "C" fn callback(
70 info: *mut libc::dl_phdr_info,
71 _size: libc::size_t,
72 data: *mut libc::c_void,
73 ) -> libc::c_int {
74 let data = &mut *(data as *mut CallbackData);
75 let dlpi_name = (*info).dlpi_name;
76 if dlpi_name.is_null() {
77 return 0;
78 }
79 let path = CStr::from_ptr(dlpi_name).to_string_lossy();
80 if path.contains(&data.name) {
81 data.result = Some((*info).dlpi_addr as usize);
82 return 1;
83 }
84 0
85 }
86
87 let mut data = CallbackData {
88 name: name.to_string(),
89 result: None,
90 };
91
92 unsafe {
93 libc::dl_iterate_phdr(Some(callback), &mut data as *mut _ as *mut libc::c_void);
94 }
95
96 data.result
97 }
98
99 pub fn find_image_path(name: &str) -> Option<String> {
100 struct CallbackData {
101 name: String,
102 result: Option<String>,
103 }
104
105 unsafe extern "C" fn callback(
106 info: *mut libc::dl_phdr_info,
107 _size: libc::size_t,
108 data: *mut libc::c_void,
109 ) -> libc::c_int {
110 let data = &mut *(data as *mut CallbackData);
111 let dlpi_name = (*info).dlpi_name;
112 if dlpi_name.is_null() {
113 return 0;
114 }
115 let path = CStr::from_ptr(dlpi_name).to_string_lossy();
116 if path.contains(&data.name) {
117 data.result = Some(path.into_owned());
118 return 1;
119 }
120 0
121 }
122
123 let mut data = CallbackData {
124 name: name.to_string(),
125 result: None,
126 };
127
128 unsafe {
129 libc::dl_iterate_phdr(Some(callback), &mut data as *mut _ as *mut libc::c_void);
130 }
131
132 data.result
133 }
134}
135
136#[cfg(target_os = "windows")]
138mod platform {
139 use std::ffi::CString;
140 use windows_sys::Win32::System::LibraryLoader::GetModuleHandleA;
141
142 pub fn find_image_base(name: &str) -> Option<usize> {
143 let c_name = CString::new(name).ok()?;
144 unsafe {
145 let handle = GetModuleHandleA(c_name.as_ptr() as *const u8);
146 if handle == 0 {
147 None
148 } else {
149 Some(handle as usize)
150 }
151 }
152 }
153
154 pub fn find_image_path(_name: &str) -> Option<String> {
155 None
156 }
157}
158
159#[cfg(not(any(
161 target_os = "macos",
162 target_os = "ios",
163 target_os = "linux",
164 target_os = "android",
165 target_os = "windows",
166)))]
167mod platform {
168 pub fn find_image_base(_name: &str) -> Option<usize> {
169 None
170 }
171
172 pub fn find_image_path(_name: &str) -> Option<String> {
173 None
174 }
175}