Skip to content

Repository files navigation

ad1-forensic

Crates.io Docs.rs License: Apache-2.0 CI Fuzz Sponsor

Open AccessData AD1 logical images in Rust — the format TSK, libewf, and BitCurator can't read. List files, extract bytes, and verify the stored per-file hashes.

FTK Imager's AD1 ("Custom Content Image") is a logical evidence container — a tree of files with metadata and zlib-compressed data, not a disk image. Nothing in the open-source disk-forensics stack parses it. ad1-core does, with no unsafe and no C dependencies.

30 seconds to a file listing

# Cargo.toml
[dependencies]
ad1-core = "0.1"
use ad1::Ad1Reader;

let img = Ad1Reader::open(std::path::Path::new("evidence.ad1"))?;
for entry in img.entries() {
    let kind = if entry.is_dir { "DIR " } else { "FILE" };
    println!("{kind} {:>10}  {}", entry.size, entry.path);
}

// Read a file's bytes (only the overlapping zlib chunks are inflated):
if let Some(f) = img.entries().iter().find(|e| !e.is_dir) {
    let mut buf = vec![0u8; f.size as usize];
    let n = img.read_at(f, 0, &mut buf)?;
    println!("read {n} bytes of {}", f.path);
}
# Ok::<(), ad1::Ad1Error>(())

Ad1Reader::open discovers split segments (.ad1, .ad2, …), parses the file tree, and exposes each entry's path, size, stored MD5/SHA1, and timestamps. read_at is positioned — it inflates only the chunks your range overlaps, not the whole file.

Tamper detection

ad1-forensic recomputes each file's hash and compares it to the value stored in the image, emitting graded forensicnomicon findings:

for finding in ad1_forensic::audit(std::path::Path::new("evidence.ad1")) {
    println!("[{:?}] {} — {}", finding.severity, finding.code, finding.note);
}
Code Meaning
AD1-HASH-MISMATCH stored hash ≠ recomputed hash (tamper signal)
AD1-ENCRYPTED ADCRYPT image — content not verifiable
AD1-SEGMENT-MISSING a declared .adN segment is absent
AD1-SIZE-LIE fewer bytes decompressed than declared
AD1-UNREADABLE the structure could not be parsed

Built for untrusted input

  • No unsafe (#![forbid(unsafe_code)]), no C (pure-Rust zlib + hashes).
  • Panic-free on malformed input — bounds-checked reads, capped allocations, cycle guards. Two cargo-fuzz targets back this up.
  • Encrypted (ADCRYPT) images are refused, never decoded to garbage.

See docs/format.md for the on-disk layout and docs/validation.md for how correctness is established.


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

About

Pure-Rust reader + forensic auditor for AccessData AD1 logical images (FTK Imager Custom Content Image)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages