hadris-apfs
hadris-apfs is an experimental, read-only reader for APFS containers and
volumes. It supports synchronous and asynchronous I/O and can be used in
no_std environments with an allocator. Its API is outside the Hadris 2.x
stability promise and may change in a minor release.
The crate is suitable for inspecting unencrypted APFS images made by macOS. It is not a recovery, repair or forensic implementation.
Supported scope
- Container superblocks, the checkpoint descriptor ring and checkpoint maps.
- Container and volume object maps, resolved at the volume's transaction.
- Physical and virtual B-trees, including sealed volumes with hashed index entries and nodes stored without object headers.
- Directory listing and path lookup, case-insensitive on volumes formatted
that way. Path lookup handles
.and.., clamps parent traversal at the volume root, and requires directories for intermediate components and trailing slashes. Symlinks are returned without following them. - Inode metadata: mode, owner, BSD flags, timestamps and data-stream size.
- File data from extents, with sparse extents and uncovered ranges read as zeros.
- Symlink targets and hard links.
- Space manager summaries and chunk-info blocks.
Limitations
- The reader is read-only. Creating, modifying and repairing volumes are not supported.
- Compressed files (
decmpfs) are reported asApfsError::Unsupportedrather than decoded. - Encrypted volumes and encrypted B-tree nodes are rejected.
- Case-insensitive lookup folds case but not Unicode normalization, so a name must use the same normalization form as the one stored on disk.
- Snapshots, Fusion tier-2 devices, extended attributes other than symlink targets, and named data streams are not exposed.
- Every lookup walks the whole filesystem tree. Large volumes are slow.
Do not rely on this crate alone for recovery or forensic conclusions from damaged, adversarial, compressed or encrypted volumes.
Example
use File;
use Container;
use SeekBlockDevice;
use ;
let file = open?;
let sectors = file.metadata?.len / 512;
let geometry = new;
let mut container = open?;
let latest = container.latest_superblock?;
for volume in container.volume_superblocks?
# Ok::
The image must start with the APFS container. For a whole-disk image, open the
APFS partition first, for example with hadris-part.
Feature flags
| Feature | Default | Description |
|---|---|---|
std |
Yes | Standard library support (enables alloc) |
alloc |
Yes | Heap allocation; required by the B-tree and file readers |
read |
Yes | The container readers |
sync |
Yes | Synchronous readers in hadris_apfs::sync |
async |
No | Asynchronous readers in hadris_apfs::r#async |
Documentation
License
Licensed under the MIT license.