The blockreader crate provides a minimal, zero-dependency, read-only random-access byte source for forensic disk images.
Acquisitions of block devices, and disk images in general, can be written in many different formats. Some of the most common include Expert Witness Format (EWF/.E01), the Advanced Forensic Format 4 (.aff4), raw disk images (.dd), UDIF (.dmg) and more. A tool seeking to read data from a disk image will benefit from a generic interface that just serves bytes at given offsets, without needing to know anything about the format of the disk image container storing those bytes. The blockreader crate is a definition of that interface, implemented in Rust.
blockreader is used to connect an arbitrary forensic container format to a parser that might read partition tables or filesystem structures from it.
See aff4-blockreader code for an example of how a forensic container parser can implement the BlockReader trait.
Then, on the other side, a parser can read bytes from it. Here's an example function that uses blockreader to get check partition table format:
use blockreader::{BlockReader, FileSource, read_exact_at};
// Takes any byte source. Never names a container format.
fn is_gpt(source: &dyn BlockReader) -> bool {
// The GPT header lives at LBA 1, so its byte offset depends on
// the sector size the source reports.
let at = u64::from(source.sector_size());
let mut signature = [0u8; 8];
match read_exact_at(source, at, &mut signature) {
Ok(()) => &signature == b"EFI PART",
Err(_) => false,
}
}
let source = FileSource::open("evidence.dd").unwrap();
println!("{} bytes, GPT: {}", source.size(), is_gpt(&source));Project code generated by Claude Opus 4.8 and Opus 5. Current version should be considered experimental. Validate results with alternate tools.
Released under the MIT License with special enthusiasm for the part in all caps.