57 lines
1.6 KiB
Rust
57 lines
1.6 KiB
Rust
use std::sync::LazyLock;
|
|
|
|
pub static LIBG_BASE: LazyLock<usize> =
|
|
LazyLock::new(|| get_module_base("libg.so").expect("failed to get libg.so base address"));
|
|
|
|
#[repr(transparent)]
|
|
pub struct Nullable<T>(*const T);
|
|
|
|
impl<T> Nullable<T> {
|
|
pub fn get(&self) -> Option<&T> {
|
|
(!self.0.is_null()).then(|| unsafe { &*self.0 })
|
|
}
|
|
|
|
pub fn get_mut(&mut self) -> Option<&mut T> {
|
|
(!self.0.is_null()).then(|| unsafe { &mut *self.0.cast_mut() })
|
|
}
|
|
|
|
pub fn set(&mut self, value: *const T) {
|
|
self.0 = value;
|
|
}
|
|
}
|
|
|
|
macro_rules! import {
|
|
($name:ident($($arg_name:ident: $arg_type:ty),*) -> $ret_type:ty = $rva:expr) => {
|
|
pub fn $name($($arg_name: $arg_type,)*) -> $ret_type {
|
|
unsafe {
|
|
type FuncType = unsafe extern "cdecl" fn($($arg_type,)*) -> $ret_type;
|
|
::std::mem::transmute::<usize, FuncType>(*crate::ffi_util::LIBG_BASE + $rva)($($arg_name,)*)
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
pub(crate) use import;
|
|
|
|
pub fn get_module_base(shared_object_name: &str) -> Option<usize> {
|
|
use std::{
|
|
fs::File,
|
|
io::{self, BufRead},
|
|
};
|
|
|
|
let file = File::open("/proc/self/maps").expect("failed to open /proc/self/maps");
|
|
let reader = io::BufReader::new(file);
|
|
|
|
for line in reader.lines() {
|
|
let line = line.ok()?;
|
|
if line.contains(shared_object_name) {
|
|
let address_str = line.split_whitespace().next().unwrap_or("");
|
|
let address =
|
|
usize::from_str_radix(&address_str.split('-').next().unwrap_or(""), 16).ok()?;
|
|
|
|
return Some(address);
|
|
}
|
|
}
|
|
|
|
None
|
|
}
|