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
19#[cfg(any(target_os = "macos", target_os = "ios"))]
21mod platform {
22 use mach2::dyld::{_dyld_get_image_header, _dyld_get_image_name, _dyld_image_count};
23 use std::ffi::CStr;
24
25 pub fn find_image_base(name: &str) -> Option<usize> {
26 unsafe {
27 let count = _dyld_image_count();
28 for i in 0..count {
29 let c_name = _dyld_get_image_name(i);
30 if c_name.is_null() {
31 continue;
32 }
33 let path = CStr::from_ptr(c_name).to_string_lossy();
34 if path.contains(name) {
35 let header = _dyld_get_image_header(i);
36 if !header.is_null() {
37 return Some(header as usize);
38 }
39 }
40 }
41 }
42 None
43 }
44}
45
46#[cfg(any(target_os = "linux", target_os = "android"))]
48mod platform {
49 use std::ffi::CStr;
50
51 pub fn find_image_base(name: &str) -> Option<usize> {
52 struct CallbackData {
53 name: String,
54 result: Option<usize>,
55 }
56
57 unsafe extern "C" fn callback(
58 info: *mut libc::dl_phdr_info,
59 _size: libc::size_t,
60 data: *mut libc::c_void,
61 ) -> libc::c_int {
62 let data = &mut *(data as *mut CallbackData);
63 let dlpi_name = (*info).dlpi_name;
64 if dlpi_name.is_null() {
65 return 0;
66 }
67 let path = CStr::from_ptr(dlpi_name).to_string_lossy();
68 if path.contains(&data.name) {
69 data.result = Some((*info).dlpi_addr as usize);
70 return 1;
71 }
72 0
73 }
74
75 let mut data = CallbackData {
76 name: name.to_string(),
77 result: None,
78 };
79
80 unsafe {
81 libc::dl_iterate_phdr(Some(callback), &mut data as *mut _ as *mut libc::c_void);
82 }
83
84 data.result
85 }
86}
87
88#[cfg(target_os = "windows")]
90mod platform {
91 use std::ffi::CString;
92 use windows_sys::Win32::System::LibraryLoader::GetModuleHandleA;
93
94 pub fn find_image_base(name: &str) -> Option<usize> {
95 let c_name = CString::new(name).ok()?;
96 unsafe {
97 let handle = GetModuleHandleA(c_name.as_ptr() as *const u8);
98 if handle == 0 {
99 None
100 } else {
101 Some(handle as usize)
102 }
103 }
104 }
105}
106
107#[cfg(not(any(
109 target_os = "macos",
110 target_os = "ios",
111 target_os = "linux",
112 target_os = "android",
113 target_os = "windows",
114)))]
115mod platform {
116 pub fn find_image_base(_name: &str) -> Option<usize> {
117 None
118 }
119}