Expand description
§crabapple
crabapple is a Rust library for reading, inspecting, and extracting data from encrypted iOS backups created by Finder, Apple Devices, or iTunes.
Inspired by imessage-exporter, crabapple provides a flexible foundation for any project that needs to access iOS backup data.
§Features
- Load and parse the backup’s
Manifest.plistto obtain metadata, device info, and encryption parameters - Derive encryption keys using
PBKDF2(HMAC-SHA256thenHMAC-SHA1) and unwrap protection class keys via AES Key Wrap (RFC 3394) - Decrypt and query the
AES-256encryptedManifest.db, exposing backup file metadata viarusqlite - Retrieve and decrypt individual files by protection class (per-file
AES-CBCwithPKCS7padding) - Cross-platform support for macOS, Windows, and Linux
§Installation
This library is available on crates.io.
§Documentation
Documentation is available on docs.rs.
§Quick Start
use std::{io::copy, fs::File};
use crabapple::{Backup, Authentication};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize a backup session for a device UDID with a password
let udid_folder = "/Users/you/Library/Application Support/MobileSync/Backup/DEVICE_UDID";
let auth = Authentication::Password("your_password".into());
let backup = Backup::open(udid_folder, &auth)?;
// List all files in the backup
let entries = backup.entries()?;
for entry in &entries {
println!("{} - {}/{}", entry.file_id, entry.domain, entry.relative_path);
}
// Decrypt and read a file entry as a stream
if let Some(entry) = entries.first() {
let mut stream = backup.decrypt_entry_stream(&entry)?;
// Write the stream to a file
let mut file = File::create("decrypted.txt")?;
copy(&mut stream, &mut file)?;
}
// Alternatively, decrypt and read a file entry into memory
if let Some(entry) = entries.get(2) {
let data = backup.decrypt_entry(&entry)?;
println!("Decrypted {} ({} bytes)", entry.relative_path, data.len());
}
// Get the derived key for use elsewhere:
let derived_key = backup.decryption_key_hex();
Ok(())
}§Using a Pre-derived Key
Pre-derived keys bypass the expensive key derivation process:
use crabapple::{Backup, Authentication};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let udid_folder = "/path/to/backup";
let hex_key = "abcdef0123456789...";
let auth = Authentication::DerivedKey(hex_key.to_string());
let backup = Backup::open(udid_folder, &auth)?;
// ... proceed as normal
Ok(())
}§Getting Basic Device Information
You can retrieve device metadata (like device name, iOS version, and UDID) without opening the full backup database:
use std::path::Path;
use crabapple::backup::device::get_device_basic_info;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let udid_folder = Path::new("/Users/you/Library/Application Support/MobileSync/Backup/DEVICE_UDID");
let info = get_device_basic_info(udid_folder)?;
println!("Device: {} (iOS {})", info.device_name, info.product_version);
println!("UDID: {}", info.unique_device_id);
Ok(())
}This information is also present on a decrypted Backup instance:
use crabapple::{Backup, Authentication};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let udid_folder = "/path/to/backup";
let hex_key = "abcdef0123456789...";
let auth = Authentication::DerivedKey(hex_key.to_string());
let backup = Backup::open(udid_folder, &auth)?;
println!("Device: {} (iOS {})",
backup.lockdown().device_name,
backup.lockdown().product_version
);
println!("UDID: {}", backup.udid()?);
Ok(())
}§Error Handling
crabapple uses a custom BackupError enum for error reporting. You can match on specific cases:
use crabapple::{Backup, Authentication};
use crabapple::error::BackupError;
match Backup::open("/bad/path", &Authentication::Password("pass".into())) {
Ok(b) => println!("Loaded backup successfully"),
Err(BackupError::ManifestPlistNotFound(path)) => eprintln!("Missing Manifest.plist: {}", path),
Err(err) => eprintln!("Error initializing backup: {}", err),
}§Targeted Versions
This library targets the current latest public release for iOS. It should work with backups from iOS 10.2 or later, but all features may not be available.
§Crabapple Tree

Re-exports§
pub use backup::Backup;pub use backup::models::auth::Authentication;