Add an API to add custom hooks to CoreADI
Dadoum

Dadoum commited on 2026-09-28 02:37:16
Showing 2 changed files, with 56 additions and 1 deletions.

... ...
@@ -88,6 +88,40 @@ pub enum ADIError {
88 88
     UnknownError(i32) = -1,
89 89
 }
90 90
 
91
+impl ADIError {
92
+    /// Returns the native ADI error code, preserving unknown values.
93
+    pub const fn code(&self) -> i32 {
94
+        match self {
95
+            Self::InvalidParameters => -45001,
96
+            Self::InvalidParameters2 => -45002,
97
+            Self::InvalidTK => -45003,
98
+            Self::PTMTKPairMismatch => -45006,
99
+            Self::ThreadingError => -45012,
100
+            Self::UnreachableADID => -45016,
101
+            Self::MachMessageError => -45017,
102
+            Self::InvalidEncryptionScheme => -45018,
103
+            Self::InvalidFunctionCode => -45019,
104
+            Self::InvalidParameterBody => -45020,
105
+            Self::InvalidSession => -45025,
106
+            Self::EmptySession => -45026,
107
+            Self::InvalidEncryptedBlockHeader => -45031,
108
+            Self::InvalidEncryptedBlockLength => -45032,
109
+            Self::InvalidEncryptedBlockContent => -45033,
110
+            Self::InvalidADICall => -45034,
111
+            Self::InvalidTime => -45036,
112
+            Self::InvalidHardwareIdentifiers => -45046,
113
+            Self::FilesystemError => -45054,
114
+            Self::NotProvisioned => -45061,
115
+            Self::NoProvisioningToErase => -45062,
116
+            Self::PendingSession => -45063,
117
+            Self::TerminatedSession => -45066,
118
+            Self::LibraryLoadingError => -45075,
119
+            Self::UnsupportedCoreADI => -45076,
120
+            Self::UnknownError(code) => *code,
121
+        }
122
+    }
123
+}
124
+
91 125
 impl From<i32> for ADIError {
92 126
     fn from(value: i32) -> Self {
93 127
         match value {
... ...
@@ -283,3 +317,16 @@ pub trait ADIProxy {
283 317
     /// Exclusive to Apple's ADI implementations: compute a 2FA code.
284 318
     fn generate_2fa_code(&self, ds_id: i64) -> ADIResult<u32>;
285 319
 }
320
+
321
+#[cfg(test)]
322
+mod error_code_tests {
323
+    use super::ADIError;
324
+
325
+    #[test]
326
+    fn native_error_codes_round_trip() {
327
+        for code in -45100..=0 {
328
+            assert_eq!(ADIError::from(code).code(), code);
329
+        }
330
+        assert_eq!(ADIError::UnknownError(-49876).code(), -49876);
331
+    }
332
+}
... ...
@@ -80,7 +80,7 @@ impl Display for AndroidCoreADILoadingError {
80 80
 impl Error for AndroidCoreADILoadingError {}
81 81
 
82 82
 impl<T: Deref<Target = [u8]>> AndroidCoreADIProxy<T> {
83
-    pub fn load_library(core_adi_data: T) -> Result<Self, AndroidCoreADILoadingError> {
83
+    pub fn build_hook_table() -> HashMap<&'static str, *const c_void> {
84 84
         let mut hooks = HashMap::new();
85 85
         hooks.insert("arc4random", android_arc4random as *const c_void);
86 86
         hooks.insert("chmod", chmod as *const c_void);
... ...
@@ -111,6 +111,14 @@ impl<T: Deref<Target = [u8]>> AndroidCoreADIProxy<T> {
111 111
         hooks.insert("pthread_rwlock_unlock", nil_fn as *const c_void);
112 112
         hooks.insert("pthread_rwlock_wrlock", nil_fn as *const c_void);
113 113
 
114
+        hooks
115
+    }
116
+
117
+    pub fn load_library(core_adi_data: T) -> Result<Self, AndroidCoreADILoadingError> {
118
+        Self::load_library_with_hooks(core_adi_data, Self::build_hook_table())
119
+    }
120
+
121
+    pub fn load_library_with_hooks(core_adi_data: T, hooks: HashMap<&'static str, *const c_void>) -> Result<Self, AndroidCoreADILoadingError> {
114 122
         let core_adi = AndroidCoreADIProxy(
115 123
             _AndroidCoreADIProxyTryBuilder {
116 124
                 data: core_adi_data,
117 125