| Crates.io | dylex |
| lib.rs | dylex |
| version | 0.4.0 |
| created_at | 2026-01-05 05:36:27.971193+00 |
| updated_at | 2026-01-06 22:09:21.084274+00 |
| description | A high-performance dyld shared cache extractor for macOS and iOS |
| homepage | https://github.com/anomalyco/dylex |
| repository | https://github.com/anomalyco/dylex |
| max_upload_size | |
| id | 2023180 |
| size | 326,368 |
A high-performance dyld shared cache extractor for macOS and iOS, written in Rust.
dylex extracts individual Mach-O binaries from Apple's dyld shared cache with full symbol table reconstruction, pointer rebasing, and proper LINKEDIT optimization. Extracted binaries are suitable for reverse engineering, analysis, and research.
cargo install dylex
git clone https://github.com/19h/dylex
cd dylex
cargo install --path .
# List available architectures in the system cache
dylex arches
# Show cache information
dylex info -a arm64e
# List all images containing "UIKit"
dylex list -a arm64e -f UIKit
# Extract a single library
dylex extract -a arm64e -i libobjc.A.dylib -o libobjc.A.dylib
# Extract all MapKit-related frameworks with preserved paths
dylex extract -a arm64e -f MapKit -o ./extracted
dylex extractExtract images from the dyld shared cache.
Usage: dylex extract [OPTIONS] [CACHE]
Arguments:
[CACHE] Path to the dyld shared cache (file or directory).
If not specified, searches default system locations.
Options:
-i, --image <IMAGE> Image to extract (e.g., "UIKit" or full path)
-f, --filter <FILTER> Filter images by substring match
-a, --arch <ARCH> Architecture (arm64e, arm64, x86_64)
-o, --output <OUTPUT> Output path (file or directory)
--preserve-paths <BOOL> Preserve directory structure [default: auto]
-v, --verbosity <LEVEL> Verbosity (0=quiet, 1=warn, 2=info, 3=debug)
-j, --jobs <N> Parallel jobs (default: CPU count)
-h, --help Print help
# Extract single image to specific file
dylex extract -a arm64e -i libobjc.A.dylib -o /tmp/libobjc.dylib
# Extract by full path
dylex extract -a arm64e -i /System/Library/Frameworks/UIKit.framework/UIKit
# Extract all Foundation-related images
dylex extract -a arm64e -f Foundation -o ./foundation_libs
# Extract everything (warning: large!)
dylex extract -a arm64e -f "" -o ./all_binaries
# Extract with verbose output
dylex extract -a arm64e -i CoreFoundation -v 2
# Use custom cache path
dylex extract -a arm64e -i libobjc.A.dylib /path/to/dyld_shared_cache_arm64e
dylex listList images in the cache.
Usage: dylex list [OPTIONS] [CACHE]
Options:
-a, --arch <ARCH> Architecture to use
-f, --filter <FILTER> Filter images by name
-A, --addresses Show virtual addresses
-b, --basenames Show only basenames (not full paths)
-h, --help Print help
# List all images
dylex list -a arm64e
# List with addresses
dylex list -a arm64e -A
# Filter and show basenames
dylex list -a arm64e -f Swift -b
# Count images matching filter
dylex list -a arm64e -f Framework | wc -l
dylex infoDisplay detailed cache information.
Usage: dylex info [OPTIONS] [CACHE]
Options:
-a, --arch <ARCH> Architecture to use
-h, --help Print help
Dyld Shared Cache Information
==============================
Path: /System/Volumes/Preboot/Cryptexes/OS/System/Library/dyld/dyld_shared_cache_arm64e
Architecture: arm64e
Images: 3554
Mappings: 22
Subcaches: 2
Total size: 5307.38 MB
Mappings:
[ 0] 0x0000000180000000 - 0x00000001e6660000 ( 1.6G) r-x
[ 1] 0x00000001e6660000 - 0x00000001e8874000 ( 34.1M) r-- [slide]
...
Subcaches:
[ 1] dyld_shared_cache_arm64e.01 (2543.53 MB)
[ 2] dyld_shared_cache_arm64e.02 (196.12 MB)
dylex archesList available cache architectures.
Usage: dylex arches [PATH]
Arguments:
[PATH] Directory to search. If not specified, uses system default.
Available architectures in /System/Volumes/Preboot/Cryptexes/OS/System/Library/dyld:
arm64e - dyld_shared_cache_arm64e
x86_64 - dyld_shared_cache_x86_64
dylex lookupFind which image contains a specific address.
Usage: dylex lookup [OPTIONS] <ADDRESS> [CACHE]
Arguments:
<ADDRESS> Address to lookup (hex, e.g., 0x180000000)
Options:
-a, --arch <ARCH> Architecture to use
-h, --help Print help
When no cache path is specified, dylex searches these locations in order:
/System/Volumes/Preboot/Cryptexes/OS/System/Library/dyld (macOS Ventura+)/System/Library/dyld (older macOS)/var/db/dyldThe --arch flag uses substring matching:
| Flag | Matches |
|---|---|
-a arm64e |
arm64e only |
-a arm64 |
arm64 and arm64e |
-a x86 |
x86_64 and x86_64h |
If multiple architectures match, you'll be prompted to be more specific.
By default, single images are extracted to the current directory with their basename:
dylex extract -a arm64e -i libobjc.A.dylib
# Creates: ./libobjc.A.dylib
When using -f/--filter, directory structure is preserved by default:
dylex extract -a arm64e -f MapKit -o ./extracted
# Creates:
# ./extracted/System/Library/Frameworks/MapKit.framework/Versions/A/MapKit
# ./extracted/System/Library/Frameworks/_MapKit_SwiftUI.framework/Versions/A/_MapKit_SwiftUI
# ./extracted/usr/lib/swift/libswiftMapKit.dylib
# ...
Use --preserve-paths false to flatten:
dylex extract -a arm64e -f MapKit -o ./flat --preserve-paths false
# Creates:
# ./flat/MapKit
# ./flat/_MapKit_SwiftUI
# ./flat/libswiftMapKit.dylib
When extracting an image, dylex performs these operations:
OBJC_IMAGE_OPTIMIZED_BY_DYLD flagdylex can be used as a library:
use dylex::{DyldContext, extract_image_with_options, ExtractionOptions};
fn main() -> anyhow::Result<()> {
// Open the cache
let cache = DyldContext::open("/path/to/dyld_shared_cache_arm64e")?;
// List images
for image in cache.iter_images() {
println!("{}: {:#x}", image.path, image.address);
}
// Extract an image
let options = ExtractionOptions::default();
extract_image_with_options(
&cache,
"/usr/lib/libobjc.A.dylib",
"libobjc.A.dylib",
options,
)?;
Ok(())
}
dylex is designed for speed:
Typical extraction times on Apple M1:
| Feature | dylex | dsc_extractor | DyldExtractor |
|---|---|---|---|
| Language | Rust | C++ | Python |
| Speed | Fast | Medium | Slow |
| LINKEDIT rebuild | Yes | Partial | Yes |
| Slide info v5 | Yes | Yes | Yes |
| Parallel extraction | Yes | No | No |
| Library API | Yes | No | Yes |
The default cache locations may not exist on your system. Specify the path explicitly:
dylex info /path/to/cache/directory
Be more specific with the architecture:
# Instead of -a arm64 (matches arm64 and arm64e)
dylex info -a arm64e
Extracted binaries are not code-signed. For research/analysis only:
# Re-sign for local execution (macOS)
codesign -f -s - extracted_binary
Some libraries (like libobjc) include large shared ObjC metadata segments. This is expected behavior.
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
MIT License - see LICENSE for details.