#disk-image #forensics #encase #e01

ewf

Pure Rust reader for Expert Witness Format (E01/EWF) forensic disk images

3 unstable releases

0.2.0 Apr 1, 2026
0.1.1 Mar 5, 2026
0.1.0 Mar 5, 2026

#350 in Filesystem

Download history 44/week @ 2026-03-01 11/week @ 2026-03-08 1/week @ 2026-03-29 486/week @ 2026-04-05

487 downloads per month
Used in 4 crates

MIT license

185KB
3K SLoC

ewf

Crates.io docs.rs License: MIT CI Coverage Sponsor

Pure Rust reader for Expert Witness Format (E01/EWF) forensic disk images. Zero GPL dependencies. Includes a CLI and MCP server for AI-assisted forensic analysis.

Install

CLI (pre-built binary)

# macOS (Homebrew)
brew install SecurityRonin/tap/ewf

# macOS / Linux (install script)
curl -sSL https://raw.githubusercontent.com/SecurityRonin/ewf/main/install.sh | bash

# Windows (winget)
winget install SecurityRonin.ewf

# Debian / Ubuntu
sudo dpkg -i ewf-cli_*.deb

# From source (requires Rust)
cargo install ewf-cli

Rust library

[dependencies]
ewf = "0.2"

CLI usage

ewf info image.E01              # Metadata, hashes, case info
ewf verify image.E01            # Full-media MD5/SHA-1 verification
ewf read image.E01 -o 510 -l 16 # Hex dump at offset
ewf sections image.E01          # List internal EWF sections
ewf search image.E01 55aa       # Search for byte pattern
ewf extract image.E01 -o 0 -l 512 -O mbr.bin  # Extract bytes to file
ewf info image.E01 --json       # JSON output for scripting

MCP server

The ewf mcp subcommand starts an MCP server for AI-assisted forensic image inspection over JSON-RPC stdio.

Tool Description
ewf_info Image metadata, geometry, stored hashes, acquisition errors
ewf_verify Full-media hash verification (MD5 + SHA-1)
ewf_read_sectors Read hex bytes at any offset
ewf_list_sections List all section descriptors across segments
ewf_search Byte-pattern search with hex input
ewf_extract Extract byte range to file

Register with Claude Code

claude mcp add ewf -- ewf mcp

Claude Desktop configuration

{
  "mcpServers": {
    "ewf": {
      "command": "ewf",
      "args": ["mcp"]
    }
  }
}

Library quick start

use std::io::{Read, Seek, SeekFrom};

let mut reader = ewf::EwfReader::open("disk.E01")?;

// Read the first sector
let mut mbr = [0u8; 512];
reader.read_exact(&mut mbr)?;

// Seek anywhere — O(1) via flat chunk index
reader.seek(SeekFrom::Start(1_048_576))?;

EwfReader implements Read + Seek, so it plugs directly into crates like ntfs, fatfs, or anything expecting a seekable stream.

Library features

  • EWF v1 format — reads images from EnCase, FTK Imager, Guymager, ewfacquire, etc.
  • EWF v2 format (Ex01/Lx01) — reads EnCase 7+ images with format auto-detection
  • L01 logical evidence files — opens .L01/.l01 files (same container, logical acquisition)
  • Multi-segment — auto-discovers .E01 through .EZZ (v1) and .Ex01 through .EzZZ (v2)
  • zlib decompression with LRU caching (configurable, default 100 chunks ~ 3.2 MB)
  • O(1) seeking — flat chunk table indexed by offset / chunk_size
  • Hash verificationverify() streams all media data through MD5/SHA-1 and compares against stored hashes
  • Stored hashes — reads MD5 and SHA-1 from hash/digest sections (v1) and Md5Hash/Sha1Hash sections (v2)
  • Case metadata — parses case number, examiner, description, notes, acquisition dates from header (v1) and CaseData (v2) sections
  • Acquisition errors — extracts read-error entries from error2 sections
  • table + table2 resilience — handles both section types, deduplicates correctly
  • DoS-safe — guards against malformed images with absurd table entry counts
  • MIT licensed — no GPL, safe for proprietary DFIR tooling

Library API examples

Verify image integrity

let mut reader = ewf::EwfReader::open("case001.E01")?;
let result = reader.verify()?;
if let Some(true) = result.md5_match {
    println!("MD5 verified: {:02x?}", result.computed_md5);
}

Read case metadata

let reader = ewf::EwfReader::open("case001.E01")?;
let meta = reader.metadata();
println!("Case: {:?}", meta.case_number);
println!("Examiner: {:?}", meta.examiner);
println!("Software: {:?}", meta.acquiry_software);

Check stored hashes

let reader = ewf::EwfReader::open("case001.E01")?;
let hashes = reader.stored_hashes();
if let Some(md5) = hashes.md5 {
    println!("Stored MD5: {:02x?}", md5);
}

Tune cache for large images

// 1000 chunks ~ 32 MB cache — useful for sequential scans
let mut reader = ewf::EwfReader::open_with_cache_size("case001.E01", 1000)?;

With the ntfs crate

use ewf::EwfReader;
use ntfs::Ntfs;

let mut reader = EwfReader::open("disk.E01")?;
// Seek to NTFS partition offset, then:
let ntfs = Ntfs::new(&mut reader)?;

Feature flags

Flag Default Description
verify Yes Enables verify() method (adds md-5 and sha-1 dependencies)

To disable hash verification and reduce dependencies:

[dependencies]
ewf = { version = "0.2", default-features = false }

Format support

Format Status
E01 (EWF v1) Supported
E01 multi-segment (.E01-.EZZ) Supported
Ex01 (EWF v2) Supported
L01 (logical evidence, v1) Supported
Lx01 (logical evidence, v2) Supported
S01 (SMART) Not yet

Testing

  • 127 tests (92 unit + 27 e2e + 8 validation) with 99.86% line coverage (694/695 lines)
  • Full-media MD5 comparison against libewf and The Sleuth Kit confirms bit-identical output across 6 public forensic images (303+ GiB of media)
  • Test images sourced from Digital Corpora and The Evidence Locker (Kevin Pagano)
  • Three small images are committed as test fixtures and run in CI

See docs/VALIDATION.md for detailed results, image sources, and reproduction steps.

Acknowledgments

Architecture informed by Velocidex/go-ewf (Apache-2.0).

License

MIT

Dependencies

~1.5–2.2MB
~38K SLoC