Manual, low-level recovery of deleted jpeg images

I have an old 128 meg thumbdrive I haven’t used in years. It had pictures on it once, but they were deleted a long time ago. I want to recover whatever images are still on the disk that didn’t get written over.

First, make a copy of the device or partition you want to scavenge from. You don’t want to accidentally write over whatever is left on the original device.

dd if=/dev/sda3 of=/tmp/sda3.dd

256977+0 records in
256977+0 records out
131572224 bytes (132 MB) copied, 144.036 s, 913 kB/s

Here’s a rough estimate of how many jpeg’s may still exist on the disk using xxd to search for “ffd8″, followed by 4 bytes, then “4a46″. This indicates the beginning of a jpeg header.

JPEG-JFIF is “ffd8 ffe0″, while JPEG-DCF, which is what cameras will spit out onto their media cards, will be “ffd8 ffe1″.

xxd sda3.dd | grep “ffd8 …. …. 4a46″

0300400: ffd8 ffe0 0010 4a46 4946 0001 0101 0048  ......JFIF.....H
030e400: ffd8 ffe0 0010 4a46 4946 0001 0200 0064  ......JFIF.....d
0700400: ffd8 ffe0 0010 4a46 4946 0001 0200 0064  ......JFIF.....d
1b44200: ffd8 ffe0 0010 4a46 4946 0001 0201 0048  ......JFIF.....H
1b4c200: ffd8 ffe0 0010 4a46 4946 0001 0201 012c  ......JFIF.....,
1b4c540: 0001 ffd8 ffe0 0010 4a46 4946 0001 0201  ........JFIF....
1b5c200: ffd8 ffe0 0010 4a46 4946 0001 0101 0060  ......JFIF.....`
1b68200: ffd8 ffe0 0010 4a46 4946 0001 0200 0064  ......JFIF.....d
1b6c200: ffd8 ffe0 0010 4a46 4946 0001 0201 0061  ......JFIF.....a
1b78200: ffd8 ffe0 0010 4a46 4946 0001 0201 0048  ......JFIF.....H
1b88200: ffd8 ffe0 0010 4a46 4946 0001 0101 0048  ......JFIF.....H
1b8c200: ffd8 ffe0 0010 4a46 4946 0001 0101 0060  ......JFIF.....`
1b98200: ffd8 ffe0 0010 4a46 4946 0001 0200 0064  ......JFIF.....d
1b9c200: ffd8 ffe0 0010 4a46 4946 0001 0101 012c  ......JFIF.....,
1ba4200: ffd8 ffe0 0010 4a46 4946 0001 0100 0001  ......JFIF......

There’s a bunch of jpeg headers on there, so that’s a good sign. I may be able to recover full jpegs, or perhaps pictures only partially overwritten. I’ll use the first one on the disk for example.

ffd8 starts the header, and it was found at the beginning of a line, so I don’t have to offset it, I can start where that line starts, which is 0300400. Converting that from hex I get 3146752

echo “ibase=16;0300400″ | bc

3146752

Skipping to that address, I’ll search for ffd9 which should be the end of the file. It may be part of some other file that got written in the middle of my jpeg, but that will become apparent once I try to view the picture. For now, lets just see the address of that ffd9.

xxd -s 3146752 sda3.dd | grep ffd9 | head -1

03ec300: ffd9 e732 689f b729 74e1 a6c9 3365 2511  ...2h..)t...3e%.

03ec300 is the beginning of the line, so add two bytes to include the “ff” and “d9″ to capture that too (however, most picture viewers won’t care if its missing!) oh I almost forgot, bc wants capital letters, so make the “ec” into “EC” for example.

Converting it from base 16 hexidecimal…

echo “ibase=16;03EC300″ | bc

4113152

Subtracting one from the other, you get the offset between the beginning and end. This is the length of the file.

echo “3146752-4113152″ | bc

-966400

Now I can copy from the start to the end of what I think might be a picture file using dd.

dd if=sda3.dd of=pic1.jpg bs=1 count=966400 skip=3146752

966400+0 records in
966400+0 records out
966400 bytes (966 kB) copied, 2.32158 s, 416 kB/s

Now I can view it in any image viewer or editor and find out if it’s worth keeping…

eog pic1.jpg

There’s plenty of tools out there that will do this for you, so it might be a waste of time to write your own script to do this, but at least I can do it now, and basically from any linux/unix machine I can get my hands on.

Posted by admica   @   19 June 2009

1 Comments

Comments
Jun 25, 2009
10:32 am
#1 Barry :

Hi

I’m not a regular reader. I found this through a google search. Just wanted to say thanks for writing this. I had been trying to do the same but went astray outputting xxd -s ?? -l ?? > file and trying to convert that dump file back into the actual file. Never occured to me to use the offsets with dd.

Doh :)

Leave a Comment

Name

Email

Website

Previous Post
« Motion capture and time lapse with a basic webcam
Next Post
cpp fails sanity check solved for pecl installations! »
Powered by Wordpress   |   Lunated designed by ZenVerse