vmdk-forensic 0.5.1

Forensic integrity analysis for VMware VMDK images — redundant-grain-directory adjudication, dangling-pointer scan, recovery triage, and header provenance
Documentation
vmdk-forensic-0.5.1 has been yanked.

vmdk-forensic

Crates.io docs.rs License: MIT CI Sponsor

Forensic integrity analysis for VMware VMDK images. The evidence-grade layer on top of the vmdk reader — it reparses the raw structure (so it works on images too damaged to open cleanly) and reports the redundant-grain-directory, dangling-pointer, recovery, and header-provenance findings that qemu-img and libvmdk discard.

Quick start

[dependencies]
vmdk-forensic = "0.1"
use vmdk_forensic::{VmdkIntegrity, Severity};

let mut a = VmdkIntegrity::new(std::fs::File::open("disk.vmdk")?);

for anomaly in a.analyse()? {
    if anomaly.severity >= Severity::Warning {
        println!("[{:?}] {:?}{}", anomaly.severity, anomaly.kind, anomaly.detail);
    }
}
# Ok::<(), std::io::Error>(())

What it detects

analyse() aggregates every check into a severity-graded Vec<VmdkAnomaly> (sorted worst-first); each finding carries its kind and a plain-language detail of its forensic significance.

Severity AnomalyKind Meaning
Error RedundantGdMismatch The redundant grain directory diverges from the primary — the grain tables they reference hold different contents (compared by content, not pointers, so healthy two-copy images don't false-positive)
Error DanglingGrainTable A grain-table pointer points beyond end-of-file (truncation or tampering)
Error DanglingGrain A grain pointer points beyond end-of-file
Error PrimaryGdUnrecoverable The primary grain directory is damaged with no RGD recovery available
Error FtpAsciiMangled Header newline-detection bytes were rewritten by an ASCII-mode FTP transfer
Warning PrimaryGdRecoverableViaRgd The primary grain directory is damaged but recoverable via the redundant copy
Warning UncleanShutdown uncleanShutdown flag set — the disk was not closed cleanly

Individual checks

Each finding is also available directly:

use vmdk_forensic::VmdkIntegrity;

let mut a = VmdkIntegrity::new(std::fs::File::open("disk.vmdk")?);

// Redundant-GD adjudication: are the grain tables the GD and RGD reference identical?
let rgd_ok = a.validate_rgd()?;

// Recovery triage: how much of a damaged primary GD can the RGD recover?
let rec = a.grain_directory_recovery()?;
println!("{} damaged, {} recoverable via RGD", rec.primary_damaged, rec.recoverable_via_rgd);

// Structural integrity: dangling GD/GT/grain pointers (VMDK4 sparse + seSparse).
let integ = a.check_integrity()?;
assert!(integ.is_ok());

// Header provenance: unclean-shutdown flag, FTP-ASCII-mangling, flag bits.
if let Some(p) = a.header_provenance()? {
    println!("unclean shutdown: {}", p.unclean_shutdown);
}
# Ok::<(), std::io::Error>(())

Reader vs. analyzer

This is the same split as vhdx/vhdx-forensic and ewf/ewf-forensic:

  • vmdk — the lean Read + Seek reader. Use it to read virtual-disk bytes, including the opt-in RGD-fallback recovery read path.
  • vmdk-forensic — this crate. Use it to audit an image before trusting it: tamper/corruption detection, recovery triage, and provenance. It re-exports vmdk::VmdkReader, so one dependency covers read + analysis.

Security

Built to run on untrusted, potentially crafted images: every offset derived from a header field uses saturating arithmetic and is bounds-checked before any read or allocation; the grain-directory size is capped; zero unsafe.


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