apm-forensic 0.2.1

Forensic-grade Apple Partition Map (APM) reader — Driver Descriptor Map + partition entries (name, type, start, count) from a byte buffer
Documentation

Crates.io docs.rs License: MIT CI Sponsor

Pure-Rust forensic Apple Partition Map (APM) reader — Driver Descriptor Map and partition entries from a byte buffer.

Reads the partition scheme on Apple hybrid optical discs and APM-formatted media, with no unsafe — and goes beyond enumeration to flag the structural anomalies a forensic examiner cares about: map-count mismatches, overlapping or out-of-bounds partitions, residual (deleted) entries, and unmapped regions that could hide data.

APM Forensic Analysis
  block size     : 512 bytes
  device blocks  : 6144

Partition map (2 entries):
  [0] Apple                Apple_partition_map      blocks          1..=63
  [1] disk image           Apple_HFS                blocks         64..=6143

Anomalies: none

Highest severity: none (clean)

apm-forensic is a library (use apm_forensic::report::text_report to render the above). For a ready-made command line that auto-detects the scheme and prints this for any disk, install the unified disk4n6 tool (cargo install disk-forensic).

Install

[dependencies]
apm-forensic = "0.1"

Quick start

// `data` begins at the device's first byte (block 0 = Driver Descriptor Map).
let data: Vec<u8> = std::fs::read("disk.img")?;

if let Some(map) = apm_forensic::parse(&data) {
    println!("{}-byte blocks, {} partitions", map.block_size, map.partitions.len());
    for p in &map.partitions {
        println!("  {:<24} {}  start {} ({} blocks)", p.type_name, p.name, p.start_block, p.block_count);
    }
    if let Some(hfs) = map.hfs_partition() {
        println!("Apple_HFS at block {}", hfs.start_block);
    }
}

What it parses

Capability Notes
Driver Descriptor Map ER signature, device block size
Partition entries PM entries: name, type, start block, block count
HFS lookup hfs_partition() finds the first Apple_HFS slice

Forensic anomaly detection

parse() gives you the layout; analyse() (byte slice) and analyse_reader() (any Read + Seek, for composing with container crates) add a severity-ranked anomaly pass:

let report = apm_forensic::analyse(&std::fs::read("disk.img")?)?;
for a in &report.anomalies {
    println!("[{}] {}: {}", a.severity, a.code, a.note);
}
# Ok::<(), apm_forensic::Error>(())
Anomaly Code Severity
Overlapping partitions APM-PART-OVERLAP Critical
Partition out of bounds APM-PART-OOB High
Residual (deleted) entry APM-PART-RESIDUAL High
Missing Apple_partition_map self-entry APM-NO-MAP-ENTRY High
pmMapBlkCnt disagreement APM-MAP-COUNT Medium
Unmapped region (possible hidden data) APM-UNMAPPED Medium
Zero-length partition APM-PART-ZEROLEN Low
Unknown partition type APM-PART-UNKNOWN Info

Partition-type strings are validated against the forensicnomicon knowledge base. The reader is fuzz-tested (cargo fuzz) to never panic on malformed input.

Validation

Tested against a real hdiutil-created APM (Apple_partition_map + Apple_HFS entries), so the layout is checked against genuine Apple output.

Related

Part of the Security Ronin forensic toolkit. Sibling partition readers: gpt-forensic, mbr-forensic. The disk-forensic orchestrator auto-detects the scheme and dispatches to whichever of the three fits. Filesystems: hfsplus-forensic, udf-forensic. Consumed by iso9660-forensic for Apple hybrid discs.


Privacy Policy · Terms of Service · © 2026 Security Ronin Ltd