Forensic Carving Guide
File carving is the process of recovering files from raw storage media — disk images, block devices, memory dumps — without relying on the filesystem's own metadata. When a file is deleted, the filesystem typically marks its directory entry as free and releases its cluster chain, but the underlying bytes are rarely zeroed immediately. Those bytes remain on disk until new writes overwrite them. Carving finds those remnant byte patterns and reconstructs the original files.
s0 implements five independent carving engines, each tuned for a different scenario. Whether you're recovering JPEGs from a formatted USB drive, salvaging Office documents from a BitLocker-decrypted partition, or extracting ELF binaries from a corrupted Linux volume, the right engine choice dramatically affects both speed and recovery depth.
Supported File Types
s0 recognizes the following file types by their binary signatures:
| Extension | Description | Magic Bytes (hex) | Max Carve Size |
|---|---|---|---|
jpg |
JPEG Image | FF D8 FF |
30 MB |
png |
PNG Image | 89 50 4E 47 0D 0A 1A 0A |
30 MB |
pdf |
PDF Document | 25 50 44 46 2D (%PDF-) |
50 MB |
zip |
ZIP / Office OpenXML | 50 4B 03 04 (PK\x03\x04) |
100 MB |
gif |
GIF Image | 47 49 46 38 (GIF8) |
20 MB |
gz |
GZIP Archive | 1F 8B 08 |
50 MB |
bmp |
BMP Image | 42 4D (BM) |
30 MB |
elf |
ELF Executable | 7F 45 4C 46 (\x7fELF) |
50 MB |
sqlite |
SQLite Database | 53 51 4C 69 74 65 20 66 6F 72 6D 61 74 20 33 00 |
100 MB |
mp3 |
MP3 Audio | 49 44 33 (ID3) |
15 MB |
ZIP covers more than ZIP
The zip signature covers any format built on the ZIP container: .zip, .docx, .xlsx, .pptx, .jar, .apk. A recovered *.zip file may in fact be a Word document — rename and inspect if the contents show XML entries like word/document.xml.
Custom File Signatures
When investigating proprietary forensic evidence, specialized container formats, or uncataloged file types, s0 allows investigators to define custom binary file signatures with arbitrary magic header and footer bytes.
Signature Definition Format
Custom signatures can be provided as a JSON file or inline JSON object with the following schema:
[
{
"name": "Proprietary Encrypted Vault",
"extension": "psv",
"category": "archive",
"header_hex": "53 45 43 56 41 55 4C 54",
"footer_hex": "45 4E 44 56 41 55 4C 54",
"min_size": 64,
"max_size": 104857600
}
]
Field Specifications:
name(string, required): Descriptive label for the artifact (appears in forensic reports and audit logs).extension(string, required): Target file extension without leading dot (e.g.psv,dat,kdbx).category(string, optional): Categorization enum (document,image,archive,audio,video,executable, orcustom).header_hex(string or bytes, required): Hexadecimal magic header bytes (spaces or0xprefixes optional, e.g.FF D8 FForffd8ff).footer_hex(string or bytes, optional): Hexadecimal trailer/footer bytes indicating end-of-file boundary.min_size(integer, optional, default: 32): Minimum candidate byte length to consider valid.max_size(integer, optional, default: 50MB): Maximum allocation window to search for footers.
Invocation via CLI & Web Dashboard
In the Forensic File Carver tab, expand ➕ Custom File Signatures (Magic Bytes Header / Footer): 1. Click + Add Custom Signature. 2. Enter the format name, extension, category, and raw hexadecimal header/footer bytes. 3. The extension is automatically synced into the active extension filter. 4. Click Start Forensic Carving Scan — the engine injects custom signatures into the scanning loop automatically.
The Five Carving Engines
Engine Overview
| Engine | Filesystem | Strategy | Speed |
|---|---|---|---|
| Signature | Any / Unknown / Corrupted | Raw byte scan for magic bytes | 160–175 MB/s |
| ext4 Structure | Linux ext4 | Reads inode tables directly | 1.5–2.2 GB/s |
| NTFS Structure | Windows NTFS | Parses $MFT, handles multi-fragment runlists |
1.8–2.5 GB/s |
| FAT32 Structure | USB / SD card (FAT32) | Scans deleted directory entries | — |
| exFAT Structure | Large USB / SDXC | Parses directory entry sets | — |
Auto-Detection Logic
s0 probes the image automatically. The detection order is:
Offset 1080 (byte offset in image) → superblock magic 0xEF53 → ext4
Boot sector offset 3 → OEM ID "NTFS " → NTFS
BPB + cluster count calculation → FAT type determination → FAT32
Offset 3 → OEM ID "EXFAT " → exFAT
No match → Signature engine (fallback)
You can bypass auto-detection and force the Signature engine with --engine signature.
Choosing the Right Engine
flowchart TD
A[Start: What is the source?] --> B{Known filesystem?}
B -- No / Corrupted / Unknown --> SIG["Signature Engine\nSlowest — most universal"]
B -- Yes --> C{Which filesystem?}
C -- Linux ext4 --> EXT4["ext4 Structure Engine\n1.5–2.2 GB/s"]
C -- Windows NTFS --> NTFS["NTFS Structure Engine\n1.8–2.5 GB/s"]
C -- "FAT32\nUSB · SD Card" --> FAT["FAT32 Structure Engine\nDeleted directory entries"]
C -- "exFAT\nLarge USB · SDXC" --> EXFAT["exFAT Structure Engine\nDirectory entry sets"]
EXT4 --> D{Recovery depth good?}
NTFS --> D
FAT --> D
EXFAT --> D
D -- Yes --> DONE[Done]
D -- No / Missing files --> SIG
Always follow up with the Signature engine
Structure engines skip allocated (live) files and focus on deleted entries. If a structure carve misses expected files, run a Signature scan on the same image as a second pass — it operates entirely independently and may recover fragments the structure engine cannot locate.
Step-by-Step: Carving from a Forensic Image
This is the most common workflow. You have a .dd, .raw, .img, or .E01 image acquired from the target drive.
1. Verify the image integrity first
Compare against the acquisition hash. Never carve from an unverified image — a corrupt image produces corrupt output.
2. Run s0 carve
# Carve deleted files with auto-detected filesystem parsing
s0 carve --target suspect_drive.dd --out-dir ./recovered/
s0 auto-detects the filesystem and selects the appropriate engine. Output:
[s0] Probing filesystem...
[s0] Detected: NTFS (OEM ID at offset 3)
[s0] Engine: NTFS Structure + Signature fallback
[s0] Scanning $MFT...
[s0] 2,847 deleted MFT entries found
...
[s0] Carve complete: 1,203 files recovered
[s0] Output: ./recovered/
[s0] Manifest: carving_manifest_a3f2bc91.json
3. Restrict target file extensions (optional)
4. Adjust confidence threshold
By default, s0 saves any file scoring ≥ 50 confidence points. For court-quality evidence, raise this:
# Carve with high confidence threshold for court-admissible evidence
s0 carve --target image.dd --out-dir ./recovered/ --min-confidence 75
For maximum recovery at the cost of more false positives (e.g., exploring an unknown image):
# Carve with lowered threshold to maximize recovery of damaged media
s0 carve --target image.dd --out-dir ./recovered/ --min-confidence 30
5. Review the output table
ID EXT SIZE CONF% SHA256 FILENAME
0001 jpg 2.4 MB 94% a3f2bc91... file_0001.jpg
0002 pdf 512 KB 87% d94e1200... file_0002.pdf
0003 zip 18.2 MB 72% f00ba300... file_0003.zip
0004 jpg 31 KB 48% ... file_0004.jpg ← below default threshold unless lowered
Step-by-Step: Carving from a Live Block Device
Write-blocking is mandatory
Always attach the target drive through a hardware write blocker before connecting it to your forensic workstation. Mounting a device read-write, even briefly, can alter access times, trigger journal commits, and overwrite the very data you are trying to recover. s0 does not substitute for a write blocker.
1. Identify the device node
# Enumerate storage devices, sizes, filesystems, and mountpoints
lsblk -o NAME,SIZE,FSTYPE,LABEL,MOUNTPOINT
Example output:
Here sdb is the target.
2. Carve directly from the block device
# Carve deleted files directly from unmounted block device
sudo s0 carve --target /dev/sdb --out-dir ./usb_recovery/
Do not mount the device
Do not run mount /dev/sdb before carving. On FAT32/exFAT, the Linux kernel's mount operation can modify directory entry timestamps and the FAT allocation table, destroying the forensic state.
3. Optionally image first, then carve
For repeatable, auditable evidence collection, capture the image first:
# Acquire image (read-only pass)
sudo dd if=/dev/sdb of=evidence.dd bs=4M status=progress conv=noerror,sync
# Verify
sha256sum evidence.dd > evidence.dd.sha256
# Carve the image (not the live device)
s0 carve evidence.dd --out-dir ./recovered/
This preserves the original device state and gives you a permanent artifact.
Understanding Confidence Scores
Every recovered file receives a score from 0–100. The score is additive across four independent criteria:
graph LR
A["Header Match\n+30 pts\nMagic bytes present at offset 0"] --> SCORE["Total Score\n0–100"]
B["Footer Match\n+30 pts\nTerminator bytes found\ne.g. FF D9 for JPEG"] --> SCORE
C["Size Plausibility\n+20 pts\nFile size within\nmin–max for type"] --> SCORE
D["Shannon Entropy\n+20 pts\nEntropy matches\nexpected for type"] --> SCORE
Score Interpretation Guide
| Score Range | Meaning | Recommended Action |
|---|---|---|
| 85–100 | High-confidence — header, footer, size, and entropy all match | Treat as reliable evidence |
| 65–84 | Good — 3 of 4 criteria met, or all 4 with partial matches | Inspect file; likely valid |
| 50–64 | Marginal — typically missing footer or entropy anomaly | Manually verify before relying on it |
| 30–49 | Low — only header matched reliably | Use only for exploration; do not use as primary evidence |
| < 30 | Very low — likely a false positive or truncated fragment | Discard unless critical |
Entropy and what it tells you
Shannon entropy measures the randomness of the byte distribution in the file:
- High entropy (> 7.5 bits/byte): expected for JPEG, PNG, ZIP, GIF, MP3 — already compressed or encrypted. A high-entropy block claiming to be a JPEG scores full entropy points.
- Medium entropy (4–7 bits/byte): expected for PDF, ELF, SQLite — structured binary with repeated patterns.
- Low entropy (< 2 bits/byte): typical of zero-filled blocks, slack space, or uninitialized sectors. s0 penalizes these heavily because they are almost certainly not real files.
When to lower --min-confidence
Lower the threshold to 30–40 when:
- Recovering from heavily used consumer SD cards where wear-leveling has scattered file footers
- Investigating JPEG fragments where the file was truncated mid-stream (footer missing)
- Doing exploratory triage before you know what file types to expect
Keep the default (50) or raise it for formal evidence submission.
Understanding recovery_index.json
Every carving session produces a recovery_index.json in the output directory. This is a machine-readable catalogue of every recovered file.
{
"session_id": "a3f2bc91-...",
"carved_at": "2026-09-09T13:44:02Z",
"source": "suspect_drive.dd",
"engine": "ntfs_structure",
"files": [
{
"id": "0001",
"extension": "jpg",
"size_bytes": 2516582,
"confidence": 94,
"sha256": "a3f2bc91d4e500fa...",
"filename": "file_0001.jpg",
"offset": 2147483648
},
{
"id": "0002",
"extension": "pdf",
"size_bytes": 524288,
"confidence": 87,
"sha256": "d94e1200c31ab7...",
"filename": "file_0002.pdf",
"offset": 3758096384
}
]
}
Key fields:
| Field | Description |
|---|---|
session_id |
UUID linking this index to its signed manifest |
source |
Path of the image or device carved |
engine |
Which carving engine was used |
id |
Sequential identifier; matches the filename prefix |
offset |
Byte offset within the source where the file was found |
sha256 |
Hash of the carved file — use for deduplication and integrity checks |
confidence |
The 0–100 scoring result |
Linking index to manifest
The session_id in recovery_index.json matches the UUID suffix in carving_manifest_<UUID8>.json. The manifest is Ed25519-signed, making the entire session tamper-evident. See the Security Model for details.
Scenario-Specific Tips
Recovering Office Documents from NTFS
Office Open XML formats (.docx, .xlsx, .pptx) use the ZIP container. s0 carves them as .zip files.
# Carve ZIP containers (including Word/Excel/PowerPoint) with confidence >= 65
s0 carve --target ntfs_image.dd --out-dir ./office_recovery/ --extensions zip --min-confidence 65
After recovery:
# Rename .zip to .docx and verify
mv file_0042.zip recovered_doc.docx
python3 -c "import zipfile; z=zipfile.ZipFile('recovered_doc.docx'); print(z.namelist())"
Look for word/document.xml (Word), xl/workbook.xml (Excel), or ppt/presentation.xml (PowerPoint) in the ZIP listing to confirm the type.
Recovering JPEGs from a Formatted USB Drive
FAT32 format operations typically zero only the FAT tables and directory entries — raw data clusters are untouched. The FAT32 Structure engine reads deleted directory entries to find the original cluster chain, while the Signature engine catches anything the directory scan misses.
# First pass: structure-aware (fast)
s0 carve /dev/sdc --engine fat32 --out-dir ./usb_photos/ --min-confidence 60
# Second pass: signature scan for orphaned clusters
s0 carve /dev/sdc --engine signature --out-dir ./usb_photos_sig/ --min-confidence 50
Compare the two output directories — the signature pass often recovers additional partial JPEGs.
Extracting Evidence from an NTFS Partition
For a specific partition within a multi-partition drive:
# Find partition offsets
mmls suspect_drive.dd
# Carve only the NTFS partition (e.g., starting at sector 2048, 512-byte sectors)
s0 carve suspect_drive.dd --offset $((2048 * 512)) --out-dir ./ntfs_evidence/
The NTFS engine parses the $MFT and handles multi-fragment runlists — files spread across non-contiguous clusters are reassembled correctly, something raw signature carving cannot do.
Limitations of File Carving
Understanding what carving cannot do is as important as knowing what it can.
Heavily Fragmented Files
The Signature engine carves contiguous byte runs. A file that was fragmented into many non-adjacent clusters before deletion will produce a truncated or corrupt output — the engine stops at the end of the first contiguous run unless a valid footer appears.
Structure engines (ext4, NTFS) handle fragmentation better because they read the original cluster maps. But once those maps are overwritten or the inode/MFT entry is reused, fragmented recovery fails for structure engines too.
Fragmentation is the primary failure mode
On heavily used volumes with frequent write-delete cycles (application temp directories, browser caches, virtual machine storage), expect significant fragmentation. Confidence scores for fragmented files will be low — size plausibility will fail because only a fragment was captured.
Overwritten Sectors
If new data has been written over the sectors where a deleted file resided, the original data is gone at the application layer. Carving cannot recover data from overwritten sectors.
No carving tool recovers overwritten data
Despite marketing claims by some commercial tools, carving does not perform magnetic remanence recovery (that technique has been proven ineffective at modern track densities). If the sectors have been overwritten, the data is unrecoverable without specialized hardware that is beyond the scope of any software tool.
Encrypted Volumes
On volumes encrypted with VeraCrypt, BitLocker, or LUKS, s0 sees a uniform stream of high-entropy bytes. The Signature engine finds no magic bytes; no files are carved. This is correct and expected behavior — encryption is working as designed.
Decrypt first, then carve
If you have the decryption key, decrypt the volume to a plaintext image first, then run s0 carve on the plaintext image.
Copy-on-Write Filesystems
On Btrfs, ZFS, and APFS, deleting a file does not overwrite its blocks — it merely removes the reference. The blocks are returned to the free pool and reclaimed lazily by the CoW engine. A "deleted" file's blocks may remain physically intact for an extended period, but s0 cannot predict when a CoW filesystem reclaimed them.
CoW snapshot artifacts
Files that appear deleted may still exist in filesystem snapshots. Check for snapshots before carving:
Snapshot enumeration often yields complete, intact files faster than carving.
Journaling Remnants
ext4 and NTFS maintain journals for crash recovery. The journal may contain metadata (inode records, directory entries, MFT entries) for recently deleted files even after the filesystem has committed the deletion. s0 does not specifically parse journal structures — use dedicated journal forensics tools for this layer.
Network-Mounted Paths
If the suspect path is on a network share (NFS, SMB/CIFS), s0's write patterns do not translate to physical sector operations. The network filesystem layer mediates all I/O, and the actual physical layout on the remote server is inaccessible. Carve the remote server's storage directly.