{"id":51595172,"url":"https://github.com/securityronin/aff4-forensic","last_synced_at":"2026-07-11T18:01:38.834Z","repository":{"id":368399892,"uuid":"1284945948","full_name":"SecurityRonin/aff4-forensic","owner":"SecurityRonin","description":"Pure-Rust read-only AFF4 disk-image reader (aff4) + forensic integrity analyzer (aff4-forensic)","archived":false,"fork":false,"pushed_at":"2026-06-30T11:08:32.000Z","size":3215,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-30T12:25:38.232Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SecurityRonin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-30T10:39:25.000Z","updated_at":"2026-06-30T11:08:36.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/SecurityRonin/aff4-forensic","commit_stats":null,"previous_names":["securityronin/aff4-forensic"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/SecurityRonin/aff4-forensic","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SecurityRonin%2Faff4-forensic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SecurityRonin%2Faff4-forensic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SecurityRonin%2Faff4-forensic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SecurityRonin%2Faff4-forensic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SecurityRonin","download_url":"https://codeload.github.com/SecurityRonin/aff4-forensic/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SecurityRonin%2Faff4-forensic/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35370428,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-11T02:00:05.354Z","response_time":104,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-07-11T18:01:37.134Z","updated_at":"2026-07-11T18:01:38.815Z","avatar_url":"https://github.com/SecurityRonin.png","language":"Rust","funding_links":["https://github.com/sponsors/h4x0r"],"categories":[],"sub_categories":[],"readme":"[![Crates.io](https://img.shields.io/crates/v/aff4.svg)](https://crates.io/crates/aff4)\n[![Docs.rs](https://img.shields.io/docsrs/aff4)](https://docs.rs/aff4)\n[![License: Apache-2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)\n[![CI](https://github.com/SecurityRonin/aff4-forensic/actions/workflows/ci.yml/badge.svg)](https://github.com/SecurityRonin/aff4-forensic/actions/workflows/ci.yml)\n[![Sponsor](https://img.shields.io/badge/sponsor-h4x0r-ea4aaa?logo=github-sponsors)](https://github.com/sponsors/h4x0r)\n\n**Pure-Rust read-only AFF4 reader (`aff4`) + integrity analyzer (`aff4-forensic`) — Map streams, Snappy/LZ4/Deflate, symbolic fills, AFF4-Logical, and self-hash verification.**\n\nDecodes AFF4 (Advanced Forensic Format 4) Standard v1.0 containers produced by Evimetry, aff4-imager, and pyaff4: `aff4:Map` virtual address mapping, all four chunk codecs, symbolic-stream fills (Zero / `0xFF` / `SymbolicStream{XX}` / UnknownData / UnreadableData), URL-encoded ZIP entry names, and AFF4-Logical (AFF4-L) file containers. Exposes a `Read + Seek` interface over the virtual sector stream. Zero unsafe code, no C bindings. The analyzer recomputes each declared `aff4:hash` and reports tampering / unreadable regions.\n\n```toml\n[dependencies]\naff4 = \"0.2\"            # the reader\naff4-forensic = \"0.1\"   # the integrity analyzer (optional)\n```\n\n---\n\n## Usage\n\n### Open an AFF4 image and read sectors\n\n```rust\nuse aff4::Aff4Reader;\nuse std::io::{Read, Seek, SeekFrom};\n\nlet mut reader = Aff4Reader::open(\"disk.aff4\".as_ref())?;\n\nprintln!(\"Virtual disk size: {} bytes\", reader.virtual_disk_size());\n\n// Read the first sector\nlet mut sector = [0u8; 512];\nreader.read_exact(\u0026mut sector)?;\n\n// Seek anywhere\nreader.seek(SeekFrom::Start(1_048_576))?;\n# Ok::\u003c(), aff4::Aff4Error\u003e(())\n```\n\n`Aff4Reader` implements `Read + Seek`, so it drops directly into any crate that accepts a reader (e.g. a filesystem parser).\n\n### Audit an image's integrity\n\n```rust\nuse aff4_forensic::audit_image;\n\nfor finding in audit_image(\"disk.aff4\".as_ref())? {\n    // AFF4-HASH-MISMATCH (stored hash ≠ recomputed) or\n    // AFF4-HASH-UNREADABLE (a region could not be acquired)\n    println!(\"{}: {}\", finding.code, finding.note);\n}\n# Ok::\u003c(), aff4::Aff4Error\u003e(())\n```\n\n### Read logical files (AFF4-L)\n\n```rust\nuse aff4::LogicalContainer;\n\nlet mut container = LogicalContainer::open(\"logical.aff4\".as_ref())?;\nfor entry in container.files().to_vec() {\n    let bytes = container.read_file(\u0026entry)?;\n    println!(\"{} ({} bytes)\", entry.original_file_name, bytes.len());\n}\n# Ok::\u003c(), aff4::Aff4Error\u003e(())\n```\n\n### Decrypt an encrypted container (AES-XTS)\n\n`Aff4Reader::open` refuses encrypted images by design; decryption is the explicit,\nkey-bearing path (a wrong password errors, never yields garbage):\n\n```rust\nuse aff4::LogicalContainer;\n\nlet mut container = LogicalContainer::open_encrypted(\"secret.aff4\".as_ref(), \"password\")?;\nlet files = container.files().to_vec();\nlet bytes = container.read_file(\u0026files[0])?;\n# Ok::\u003c(), aff4::Aff4Error\u003e(())\n```\n\n---\n\n## Supported features\n\n| Feature | Status |\n|---------|:------:|\n| AFF4 v1 Standard (Evimetry 3.0 reference images) | ✓ |\n| 12-byte bevy index (`(offset, length)` per chunk) | ✓ |\n| `aff4:Map` virtual address mapping | ✓ |\n| Symbolic `aff4:Zero` / `SymbolicStreamFF` / `SymbolicStream{XX}` | ✓ |\n| `aff4:UnknownData` / `UnreadableData` tile fills (pyaff4-exact) | ✓ |\n| ExabyteSparse images (≤ 9.2 EiB virtual size) | ✓ |\n| Snappy / LZ4 frame / Deflate (zlib) / Null codecs | ✓ |\n| URL-encoded ZIP entry names (`aff4%3A%2F%2F…`) | ✓ |\n| AFF4-Logical (AFF4-L) file containers | ✓ |\n| `aff4:hash` verification → `AFF4-HASH-MISMATCH` / `-UNREADABLE` | ✓ |\n| Encrypted volumes (`aff4:EncryptedStream`, AES-XTS + password keybag) | decrypt |\n\nRead-only. Validated Tier-1 against the AFF4 reference corpus and pyaff4 — see the [reader](https://securityronin.github.io/aff4-forensic/corpus-validation/) and [audit](https://securityronin.github.io/aff4-forensic/validation/) validation docs.\n\n---\n\n## Related crates\n\n### Container readers\n\n| Crate | Format | Notes |\n|-------|--------|-------|\n| [`ewf`](https://github.com/SecurityRonin/ewf-forensic) | E01 / EWF / Ex01 | Dominant professional forensic acquisition format |\n| [`vmdk`](https://github.com/SecurityRonin/vmdk-forensic) | VMware VMDK | Monolithic sparse disk images from VMware Workstation / ESXi |\n| [`qcow2`](https://github.com/SecurityRonin/qcow2) | QCOW2 v2/v3 | QEMU / KVM / libvirt disk images |\n\n### Forensic analysers\n\n| Crate | Format | Notes |\n|-------|--------|-------|\n| [`ewf-forensic`](https://github.com/SecurityRonin/ewf-forensic) | E01 | Structural integrity audit, hash verification, and in-memory repair |\n| [`vhdx-forensic`](https://github.com/SecurityRonin/vhdx-forensic) | VHDX | Forensic integrity analyser and in-memory repair tool for VHDX containers |\n\n---\n\n[Privacy Policy](https://securityronin.github.io/aff4-forensic/privacy/) · [Terms of Service](https://securityronin.github.io/aff4-forensic/terms/) · © 2026 Security Ronin Ltd\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsecurityronin%2Faff4-forensic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsecurityronin%2Faff4-forensic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsecurityronin%2Faff4-forensic/lists"}