ReagentX/crabapple

GitHub: ReagentX/crabapple

crabapple 是一个 Rust 库,用于读取、解密和提取由 Finder、iTunes 或 Apple Devices 创建的加密 iOS 备份数据。

Stars: 69 | Forks: 1

# crabapple `crabapple` 是一个 Rust 库,用于读取、检查和提取由 Finder、Apple Devices 或 iTunes 创建的加密 iOS 备份数据。 受 [`imessage-exporter`](https://github.com/ReagentX/imessage-exporter) 启发,`crabapple` 为任何需要访问 iOS 备份数据的项目提供了灵活的基础。 ## 功能 - 加载并解析备份的 `Manifest.plist` 以获取元数据、设备信息和加密参数 - 使用 `PBKDF2`(先 `HMAC-SHA256` 后 `HMAC-SHA1`)派生加密密钥,并通过 AES Key Wrap (`RFC 3394`) 解包保护类密钥 - 解密并查询 `AES-256` 加密的 `Manifest.db`,通过 `rusqlite` 暴露备份文件元数据 - 按保护类检索单个文件并解密(基于单个文件的带有 `PKCS7` 填充的 `AES-CBC`) - 跨平台支持 macOS、Windows 和 Linux ## 安装 该库可在 [crates.io](https://crates.io/crates/crabapple) 上获取。 ## 文档 文档可在 [docs.rs](https://docs.rs/crabapple) 上查看。 ## 快速开始 ``` use std::{io::copy, fs::File}; use crabapple::{Backup, Authentication}; fn main() -> Result<(), Box> { // 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(()) } ``` ### 使用预派生密钥 预派生密钥可以绕过耗时的密钥派生过程: ``` use crabapple::{Backup, Authentication}; fn main() -> Result<(), Box> { 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(()) } ``` ### 获取基本设备信息 您无需打开完整的备份数据库即可检索设备元数据(例如设备名称、iOS 版本和 UDID): ``` use std::path::Path; use crabapple::backup::device::get_device_basic_info; fn main() -> Result<(), Box> { 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(()) } ``` 此信息也存在于已解密的 `Backup` 实例中: ``` use crabapple::{Backup, Authentication}; fn main() -> Result<(), Box> { 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(()) } ``` ### 错误处理 `crabapple` 使用自定义的 `BackupError` 枚举进行错误报告。您可以针对特定情况进行匹配: ``` 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), } ``` ## 目标版本 该库针对 iOS 当前最新的公开发布版本。它应适用于 iOS 10.2 或更高版本的备份,但可能并非所有功能都可用。 ## Crabapple 树 ![我的 Crabapple 树](/resources/crabapple.png)
标签:iOS备份, Rust库, SQLite, 可视化界面, 密码学解密, 数据提取, 数据解析, 通知系统