ewf-image
A pure-Rust library for reading and writing Expert Witness Format (EWF) forensic images.

ewf-image reads and writes the EWF/E01 image formats used in digital
forensics — the physical, logical, SMART, and EWF2 families — with no unsafe
code and no external tool dependencies. It exposes focused APIs for raw stream
access, metadata inspection, logical single-file catalogs, and EWF output
creation.
Highlights
- Full format coverage. Reads and writes EWF1 (
.E01,.L01,.S01) and EWF2 (.Ex01,.Lx01), including raw, zlib, BZip2, and pattern-fill chunks. - Streaming reads. Immutable
Imagehandles offer positioned reads,Read + Seekcursors, and bounded decoded-chunk caching. - Rich metadata. Inspect acquisition headers, stored MD5/SHA1 hashes, acquisition errors, sessions, and tracks.
- Integrity verification. Recompute and compare stored hashes with a single
Image::verify()call. - Flexible writing. Compression, segment splitting, secondary/shadow mirroring, authored metadata, and resume-by-rewrite.
- Safe by construction.
#![forbid(unsafe_code)], linted under clippy pedantic/nursery, and tested against external EWF tool oracles.
This release ships the Rust library. Command-line, mount, and service runtime layers are planned but not yet implemented.
Installation
[]
= "0.1"
The default verify feature enables streamed MD5/SHA1 verification through
Image::verify(). Drop it if you don't need that API:
[]
= { = "0.1", = false }
Quick Start
Open an image, inspect its format, and read from the logical media stream:
use Read;
let image = open?;
let info = image.info;
println!;
// Read the first sector from the cursor...
let mut first_sector = vec!;
image.cursor.read_exact?;
// ...or read directly at any offset.
let mut sector_at_offset = vec!;
image.read_at?;
Read forensic metadata and verify stored hashes:
let image = open?;
if let Some = image.header_value
let result = image.verify?;
println!;
Write a new compressed EWF2 image from raw bytes:
use File;
let mut input = open?;
let mut options = default;
options.format = Ewf2Physical;
options.compression = Zlib;
options.metadata.set_header_value;
let mut writer = create?;
copy?;
let result = writer.finish?;
println!;
See examples/ for complete, runnable programs, including reading,
raw export, logical inspection, and mirrored secondary output.
Supported Formats
| Family | Read | Write | Notes |
|---|---|---|---|
EWF1 physical .E01 / EVF |
✓ | ✓ | Segment discovery, raw/zlib chunks, metadata, hashes, acquisition errors, sessions, tracks, and split output. |
EWF1 logical .L01 / LVF |
✓ | ✓ | Logical single-file catalogs and path lookup. |
EWF1 SMART .S01 |
✓ | ✓ | SMART media profile handling. |
EWF2 physical .Ex01 |
✓ | ✓ | Raw, zlib, BZip2, and pattern-fill chunks; EWF2 metadata, memory extents, and split output. |
EWF2 logical .Lx01 |
✓ | ✓ | Logical single-file catalogs and auxiliary single-file tables. |
The writer additionally supports SMART output, compression, segment splitting, secondary/shadow mirroring, authored metadata, stored hashes, incomplete EWF1 output, and resume-by-rewrite.
Limitations
- Encrypted EWF2 images are detected and rejected; decryption is not yet implemented.
- Encrypted writing is not yet implemented.
- Base-plus-overlay delta/shadow images are not yet implemented.
- EWF2 BZip2 chunks are supported locally, but some external EWF tools cannot generate or export BZip2 fixtures, so external oracle coverage for them is tracked separately.
See docs/limitations.md for details.
Testing
Compatibility is covered by local synthetic fixtures, writer round trips, and optional external EWF tool oracle tests. The routine checks are:
RUSTDOCFLAGS="-D warnings"
External corpus and tool oracle checks are ignored by default, since they require local fixtures and installed EWF tools. See docs/testing.md and docs/compatibility.md.
Documentation
Contributing
Contributions are welcome. See CONTRIBUTING.md to get started, and SECURITY.md for reporting security issues.
License
Licensed under the Apache License, Version 2.0. See LICENSE.