Git · dadoum.zone
Repositories
Help
Report an Issue
apple-crates
Code
Commits
Branches
Tags
Search
Tree:
a74924e
Branches
Tags
main
apple-crates
android-coreadi
src
lib.rs
Refactor and unify a lot of things for another project and implement airdrop support
Dadoum
commited
a74924e
at 2026-10-25 22:15:58
lib.rs
Blame
History
Raw
#[cfg(target_os = "linux")] mod linux; mod linux_libc; #[cfg(all(target_family = "unix", not(target_os = "linux")))] mod unix; #[cfg(target_os = "windows")] mod windows; #[cfg(target_os = "linux")] use crate::linux::*; #[cfg(all(target_family = "unix", not(target_os = "linux")))] use crate::unix::*; #[cfg(target_os = "windows")] use crate::windows::*; use adi::core_adi::{CoreADIADIProxy, CoreADIParameters, CoreADIProxy}; use elf_loader::{Library, LibraryLoadingError, Symbol, linux_cc, linux_fn}; use ouroboros::self_referencing; use rand::Rng; use std::collections::HashMap; use std::ffi::{c_char, c_void}; use std::ops::Deref; use thiserror::Error; #[linux_cc] fn android_arc4random() -> u32 { rand::rng().random() } #[linux_cc] unsafe fn android_system_property_get(_name: *const c_char, value: *mut c_char) -> i32 { // Every property reads as "0". unsafe { *value = b'0' as c_char }; unsafe { *value.add(1) = 0 }; 1 } #[linux_cc] unsafe fn nil_fn() -> i32 { 0 } #[self_referencing] struct LoadedCoreADI<T: Deref<Target = [u8]> + 'static> { data: T, #[borrows(data)] #[covariant] library: Library<'this>, #[borrows(library)] #[covariant] dispatch_symbol: Symbol<'this, 'this, linux_fn! { fn(u32, *const CoreADIParameters) -> i32 }>, } pub struct AndroidCoreADIProxy<T: Deref<Target = [u8]> + 'static>(LoadedCoreADI<T>); #[derive(Debug, Error)] pub enum AndroidCoreADILoadingError { #[error("Provided data is not a valid library: {0}")] InvalidLibrary(LibraryLoadingError), #[error("Provided library is not a CoreADI library")] InvalidCoreADI, } impl<T: Deref<Target = [u8]>> AndroidCoreADIProxy<T> { /// The functions provided to CoreADI in place of Android's libc. pub fn build_hook_table() -> HashMap<&'static str, *const c_void> { HashMap::from([ ("arc4random", android_arc4random as *const c_void), ("chmod", chmod as *const c_void), ("close", close as *const c_void), ("free", free as *const c_void), ("fstat", fstat as *const c_void), ("ftruncate", ftruncate as *const c_void), ("gettimeofday", gettimeofday as *const c_void), ("lstat", lstat as *const c_void), ("malloc", malloc as *const c_void), ("mkdir", mkdir as *const c_void), ("open", open as *const c_void), ("read", read as *const c_void), ("strncpy", strncpy as *const c_void), ("umask", umask as *const c_void), ("write", write as *const c_void), ( "__system_property_get", android_system_property_get as *const c_void, ), ("__errno", errno as *const c_void), ("__errno_location", errno as *const c_void), // TODO: implement PThread functions ("pthread_rwlock_destroy", nil_fn as *const c_void), ("pthread_rwlock_init", nil_fn as *const c_void), ("pthread_rwlock_rdlock", nil_fn as *const c_void), ("pthread_rwlock_unlock", nil_fn as *const c_void), ("pthread_rwlock_wrlock", nil_fn as *const c_void), ]) } pub fn load_library(core_adi_data: T) -> Result<Self, AndroidCoreADILoadingError> { Self::load_library_with_hooks(core_adi_data, Self::build_hook_table()) } pub fn load_library_with_hooks( core_adi_data: T, hooks: HashMap<&'static str, *const c_void>, ) -> Result<Self, AndroidCoreADILoadingError> { LoadedCoreADITryBuilder { data: core_adi_data, library_builder: |data| { Library::load(data, |symbol| hooks.get(symbol).copied()) .map_err(AndroidCoreADILoadingError::InvalidLibrary) }, // The symbol is CoreADI's dispatcher, and lives alongside the library. dispatch_symbol_builder: |library| { unsafe { library.get("vdfut768ig") } .ok_or(AndroidCoreADILoadingError::InvalidCoreADI) }, } .try_build() .map(AndroidCoreADIProxy) } } impl<T: Deref<Target = [u8]>> Drop for AndroidCoreADIProxy<T> { fn drop(&mut self) { let _ = self.finalize(); } } impl<T: Deref<Target = [u8]>> CoreADIProxy for AndroidCoreADIProxy<T> { unsafe fn dispatch(&self, function_code: u32, parameters: *const CoreADIParameters) -> i32 { (self.0.borrow_dispatch_symbol().ptr)(function_code, parameters) } }