🔬 Manual JPEG File Carving — Hands-On Lab
File Carving Module
Step 1 — What Is File Carving?

File carving is the recovery of files from raw disk data without relying on the filesystem. When a file is deleted, the OS removes its directory entry and marks the space as available — but the actual bytes often remain untouched until overwritten.

Carving works by scanning raw storage for known file signatures (sometimes called "magic bytes") that mark the beginning and end of specific file types, then extracting everything in between.

You'll use this technique when recovering deleted files from unallocated space, working with damaged or corrupt filesystems, or imaging flash media like SD cards where the FAT has been wiped.

⚠️ Fragmentation: Manual carving assumes the file is stored in contiguous clusters. Fragmented files require more advanced recovery. JPEG files on flash media are typically contiguous.
Step 2 — JPEG File Signatures

Every file type has a unique byte pattern at its start and (often) its end. These are documented in Gary Kessler's File Signature Table — the go-to reference for forensic analysts.

For JPEG files, the signatures are:

MarkerHex SignatureDescription
SOF FF D8 FF Start of File — first 3 bytes of every JPEG
EOF FF D9 End of File — last 2 bytes of every JPEG
⚠️ False EOF warning: The byte sequence FF D9 can appear inside compressed image data. When carving, always use the last occurrence of FF D9 after your SOF as the true end of file.
💡 These same signatures are what tools like Foremost, Scalpel, and PhotoRec are configured to search for. Understanding them manually helps you know why those tools work — and how to recover files when they don't.
Step 3 — Examine the Disk Image

The hex dump on the right shows a raw sector from an evidence disk image (evidence.img). This is what you'd see opening a disk image in a hex editor like HxD or WinHex, or through the hex view in Autopsy.

The dimmed bytes at the top and bottom are slack space — unallocated data with no meaningful content. Somewhere in between, a JPEG is embedded. Your job is to find it using its signatures.

The layout follows standard hex editor format:
Offset  |  Hex bytes (16 per row, grouped in 8)  |  ASCII

💡 In a Linux terminal you can search for JPEG signatures directly:
grep -obUaP "\xFF\xD8\xFF" evidence.img
Step 4 — Locate the SOF

Scan the hex dump and find the JPEG Start of File signature: FF D8 FF

👆 Click the first FF byte of that 3-byte sequence to mark your SOF offset.

SOF located! The JPEG begins at offset 0x0020 (decimal 32). Note this offset — it's your carve starting point.
SOF Offset
Signature Found
Step 5 — Locate the EOF

Now find the JPEG End of File signature: FF D9

Scan forward from your SOF at 0x0020 and find the last FF D9 sequence.

👆 Click the FF byte that begins that final FF D9 pair.

EOF located! The JPEG ends at offset 0x00F8–0x00F9 (decimal 248–249). Note this as your carve end point — the last byte of the file is at 0x00F9.
SOF Offset
0x0020
EOF Offset
Step 6 — Calculate Size & Carve

With both offsets confirmed, you can calculate the exact file size and extract the bytes.

SOF (first byte)
0x0020 (32)
EOF (last byte)
0x00F9 (249)
📐 File size formula:
(EOF last byte offset) − (SOF offset) + 1
249 − 32 + 1 = 218 bytes

In practice, you'd select all bytes between your SOF and EOF offsets in your hex editor, copy them, paste into a new file, and save it with a .jpg extension.

From the command line:

dd if=evidence.img bs=1 skip=32 count=218 of=carved.jpg

Step 7 — Verify the Carved File

Before documenting your findings, verify the carved file is structurally valid and generate hashes for your chain of custody record.

Structural check: Confirm the carved file starts with FF D8 FF and ends with FF D9. ✅

Hash the file: Generate MD5 and/or SHA1 hashes to document the file's integrity. These go in your case notes so anyone can verify the carved file hasn't been modified.

Validate it opens: Run file carved.jpg on Linux, or simply open it in an image viewer. A valid JPEG will be recognized and render correctly.

📄 evidence.img — Sector 0x0000
Slack SOF EOF Carved Range