trash-core 0.1.0

Pure-Rust read-only Windows Recycle Bin $I index reader — parses pre-Win10 (v1) and Win10+ (v2) $I metadata and pairs $I/$R files to recover deleted-file path, size, and deletion time
Documentation

trash-core

trash-core trash-forensic Docs.rs License: Apache-2.0 CI Sponsor

A from-scratch, read-only Windows Recycle Bin $I index reader — recovers a deleted file's original path, size, and deletion time, and pairs $I/$R files by a directory scan. Pure Rust, no unsafe, no Windows host required: reads a $Recycle.Bin lifted from any image.

[dependencies]
trash-core = "0.1"
use trash_core::parse_index;

// raw bytes of a $I index file (e.g. $IAB12CD.docx)
let idx = parse_index(bytes)?;
println!("{} ({} bytes) deleted {:?}",
    idx.original_path, idx.original_size, idx.deleted_at);
// C:\Users\victim\Documents\secret plan.docx (1234 bytes) deleted Some(2024-01-15T10:30:00Z)
# Ok::<(), trash_core::Error>(())

What it parses

parse_index(&[u8]) -> Result<RecycleBinIndex, Error> decodes a single $I file: the 8-byte format version, original size, FILETIME deletion time, and the UTF-16LE original path — version 1 (pre-Win10, fixed 520-byte name field) and version 2 (Win10+, length-prefixed name) alike. A zero FILETIME surfaces as deleted_at: None rather than a bogus 1601 timestamp.

scan_pairs(&Path) -> io::Result<Vec<RecycleBinPair>> walks a $Recycle.Bin\<SID> directory and matches each $I index to its $R content file by the trailing identifier ($IAB12CD.docx$RAB12CD.docx); a $I with no $R yields a pair whose content_path is None.

The bare crate name trash is taken on crates.io, so the reader publishes as trash-core and imports as trash_core.

Trust, but verify

$I bytes are treated as attacker-controlled. #![forbid(unsafe_code)]; panic-free on crafted input (the workspace denies clippy::unwrap_used / expect_used in production code, every integer read is bounds-checked, and a hostile version-2 name length is rejected against a 32 768-char cap before allocation); a truncated or hostile file returns a typed Error that carries the offending value, never a panic or an out-of-bounds read. Fuzzed with cargo-fuzz (must not panic), and decoded paths/sizes/times are cross-checked against the C tool rifiuti2. See docs/validation.md.

Forensic analysis

Severity-graded anomaly auditing (purged content, path-traversal in the stored name, missing deletion time) lives in the sibling trash-forensic crate, built on this one — the reader/analyzer split mirrors ntfs-core/ntfs-forensic.


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