Search code examples
linuxfilerecoveryfat

How to recover deleted file from FAT image?


I would like to know to recover deleted file from FAT. I created fat.img as below.

cd /tmp
dd if=/dev/zero of=fat.img bs=1024 count=100
mkfs.msdos fat.img
mkdir -p /tmp/fs
sudo mount -t msdos fat.img /tmp/fs -o umask=000,loop

Now i am creating file with some text.

cd/tmp/fs
echo "hello world"> name

Using hexdump to see how it was saved

cd ..
hexdump -C fat.img 

00000000  eb 3c 90 6d 6b 66 73 2e  66 61 74 00 02 04 01 00  |.<.mkfs.fat.....|
00000010  02 00 02 c8 00 f8 01 00  20 00 40 00 00 00 00 00  |........ .@.....|
00000020  00 00 00 00 80 01 29 3c  69 e6 fb 4e 4f 20 4e 41  |......)<i..NO NA|
00000030  4d 45 20 20 20 20 46 41  54 31 32 20 20 20 0e 1f  |ME    FAT12   ..|
00000040  be 5b 7c ac 22 c0 74 0b  56 b4 0e bb 07 00 cd 10  |.[|.".t.V.......|
00000050  5e eb f0 32 e4 cd 16 cd  19 eb fe 54 68 69 73 20  |^..2.......This |
00000060  69 73 20 6e 6f 74 20 61  20 62 6f 6f 74 61 62 6c  |is not a bootabl|
00000070  65 20 64 69 73 6b 2e 20  20 50 6c 65 61 73 65 20  |e disk.  Please |
00000080  69 6e 73 65 72 74 20 61  20 62 6f 6f 74 61 62 6c  |insert a bootabl|
00000090  65 20 66 6c 6f 70 70 79  20 61 6e 64 0d 0a 70 72  |e floppy and..pr|
000000a0  65 73 73 20 61 6e 79 20  6b 65 79 20 74 6f 20 74  |ess any key to t|
000000b0  72 79 20 61 67 61 69 6e  20 2e 2e 2e 20 0d 0a 00  |ry again ... ...|
000000c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000001f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 aa  |..............U.|
00000200  f8 ff ff 00 f0 ff 00 00  00 00 00 00 00 00 00 00  |................|
00000210  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000400  f8 ff ff 00 f0 ff 00 00  00 00 00 00 00 00 00 00  |................|
00000410  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000600  4e 41 4d 45 20 20 20 20  20 20 20 20 00 00 00 00  |NAME        ....|
00000610  00 00 00 00 00 00 21 86  91 4b 03 00 0c 00 00 00  |......!..K......|
00000620  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00004e00  68 65 6c 6c 6f 20 77 6f  72 6c 64 0a 00 00 00 00  |hello world.....|
00004e10  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00019000

After deleting file name we can see change in hexdump

00000600  4e 41 4d 45 20 20 20 20  20 20 20 20 00 00 00 00  |.AME        ....|
00000610  00 00 00 00 00 00 21 86  91 4b 03 00 0c 00 00 00  |......!..K......|
00000620  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

And here is my question do you have any suggestion how can i change fat.img to .AME to NAME to recovery my file?


Solution

  • how can i change fat.img to .AME to NAME to recovery my file?

    The short answer is with dd, an example with the necessary caveats follows below.

    Adding to Martin's answer, while manipulating the bytes to restore the file within the floppy image is a relatively straight-forward proposition with dd, computing where and what within the file allocation table(s) needs to be restored is the challenge. Walking through the use of dd to restore the file itself, knowing what bytes need attention is illustrated by the following example.

    Creating a floppy image to work with saves you from having to experiment on your actual image. Simply duplicate your image you wish to work with, or create a new one within a file on your hard drive. You can do that easily with mkfs.msdos (adjust the filesystem type as needed), and then mount the file within your filesystem as follows, e.g.

    $ mkfs.msdos -C /home/david/tmp/tt/floppy_144.img 1440
    $ sudo mount /home/david/tmp/tt/floppy_144.img /mnt/fd
    

    Now let's add the NAME file:

    $ echo "hello world" > NAME
    $ sudo cp -a NAME /mnt/fd
    $ ls -l /mnt/fd
    total 1
    -rwxr-xr-x  1 root root   12 Dec 17 13:55 NAME
    $ cat /mnt/fd/NAME
    hello world
    

    Before deleting the file from your image, hexdump the contents so you can see exactly what needs to be restored. (this is what you must compute in order to know where and what to restore with your original image, you will need to consult a reference for the precise filesystem at issue)

    $ hexdump -C floppy_144.img >flpwname.txt
    

    Now delete the file from your image and again save a hexdump showing the changes.

    $ sudo rm /mnt/fd/NAME
    $ hexdump -C floppy_144.img >flpwoname.txt
    

    Now you can examing the difference with diff. What you find is you must restore more than the first name of the file that was deleted, you will need to restore the file allocation table entries so that the restored file can again be located within the filesystem (both copies of the FAT), e.g.

    $ diff flpwname.txt flpwoname.txt
    16c16
    < 00000200  f0 ff ff 00 f0 ff 00 00  00 00 00 00 00 00 00 00  |................|
    ---
    > 00000200  f0 ff ff 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    19c19
    < 00001400  f0 ff ff 00 f0 ff 00 00  00 00 00 00 00 00 00 00  |................|
    ---
    > 00001400  f0 ff ff 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    22c22
    < 00002600  4e 41 4d 45 20 20 20 20  20 20 20 20 00 00 fa 9e  |NAME        ....|
    ---
    > 00002600  e5 41 4d 45 20 20 20 20  20 20 20 20 00 00 fa 9e  |.AME        ....|
    

    Note above the entries for the file allocation table(s) at 0x204 and 0x1404 were zeroed when the file was removed. Restoring the bytes to the original can be easily done with dd but pay attention to your options. Specifically your block size (bs), output block size (obs), count and seek must all be in bytes (specified by appending c) to the number and you must set the notrunc conversion option to prevent truncating your image following the changes you make. Lastly, all sizes must be specified in decimal not hexadecimal.

    Further, if you are using bash, you can use a process redirection to specify the bytes to replace (e.g. if=<(printf "\xf0\xff") to write the hex bytes f0 and ff), otherwise, you will have to prepare input files containing your replacement strings. The dd commands to restore the FAT and the first character of the filename are fairly simple (consult man 1 dd for option explanation).

    Below we restore the first copy of the FAT, then the second, and finally restore the first character of the filename. The seek (offset) values are just those provided by hexdump converted to decimal. (you should unmount your filesystem before making changes. you can make changes while your floppy image is mounted, but they won't be reflected until you remount)

    $ sudo umount /mnt/fd
    
    $ dd if=<(printf "\xf0\xff") of=floppy_144.img \
    bs=1c obs=1c count=2c seek=516c conv=notrunc
    
    $ dd if=<(printf "\xf0\xff") of=floppy_144.img \
    bs=1c obs=1c count=2c seek=5124c conv=notrunc
    
    $ dd if=<(printf "N") of=floppy_144.img \
    bs=1c obs=1c count=1c seek=9728c conv=notrunc
    

    Now you can create a hexdump of the repaired floppy image and compare that to the original. If all has gone as it should, there will be no difference.

    $ hexdump -C floppy_144.img >flprepair.txt
    $ diff flpwname.txt flprepair.txt
    

    Finally, just remount your filesystem and confirm the file has been restored.

    $ sudo mount /home/david/tmp/tt/floppy_144.img /mnt/fd
    $ ls -l /mnt/fd
    total 1
    -rwxr-xr-x 1 root root 12 Dec 17 13:55 NAME
    $ cat /mnt/fd/NAME
    hello world
    

    That's it. I hope this is what you were looking for. There are a number of tools that automate this process for you, but dd and a pencil and paper can get you by.

    The full hexdumps follow for completeness:

    Original/Restored

    $ cat flpwname.txt
    00000000  eb 3c 90 6d 6b 66 73 2e  66 61 74 00 02 01 01 00  |.<.mkfs.fat.....|
    00000010  02 e0 00 40 0b f0 09 00  12 00 02 00 00 00 00 00  |...@............|
    00000020  00 00 00 00 00 01 29 2c  72 18 ba 4e 4f 20 4e 41  |......),r..NO NA|
    00000030  4d 45 20 20 20 20 46 41  54 31 32 20 20 20 0e 1f  |ME    FAT12   ..|
    00000040  be 5b 7c ac 22 c0 74 0b  56 b4 0e bb 07 00 cd 10  |.[|.".t.V.......|
    00000050  5e eb f0 32 e4 cd 16 cd  19 eb fe 54 68 69 73 20  |^..2.......This |
    00000060  69 73 20 6e 6f 74 20 61  20 62 6f 6f 74 61 62 6c  |is not a bootabl|
    00000070  65 20 64 69 73 6b 2e 20  20 50 6c 65 61 73 65 20  |e disk.  Please |
    00000080  69 6e 73 65 72 74 20 61  20 62 6f 6f 74 61 62 6c  |insert a bootabl|
    00000090  65 20 66 6c 6f 70 70 79  20 61 6e 64 0d 0a 70 72  |e floppy and..pr|
    000000a0  65 73 73 20 61 6e 79 20  6b 65 79 20 74 6f 20 74  |ess any key to t|
    000000b0  72 79 20 61 67 61 69 6e  20 2e 2e 2e 20 0d 0a 00  |ry again ... ...|
    000000c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    *
    000001f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 aa  |..............U.|
    00000200  f0 ff ff 00 f0 ff 00 00  00 00 00 00 00 00 00 00  |................|
    00000210  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    *
    00001400  f0 ff ff 00 f0 ff 00 00  00 00 00 00 00 00 00 00  |................|
    00001410  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    *
    00002600  4e 41 4d 45 20 20 20 20  20 20 20 20 00 00 fa 9e  |NAME        ....|
    00002610  91 4b 91 4b 00 00 f5 9e  91 4b 03 00 0c 00 00 00  |.K.K.....K......|
    00002620  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    *
    00004400  68 65 6c 6c 6f 20 77 6f  72 6c 64 0a 00 00 00 00  |hello world.....|
    00004410  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    *
    00168000
    

    After NAME Deletion

    $ cat flpwoname.txt
    00000000  eb 3c 90 6d 6b 66 73 2e  66 61 74 00 02 01 01 00  |.<.mkfs.fat.....|
    00000010  02 e0 00 40 0b f0 09 00  12 00 02 00 00 00 00 00  |...@............|
    00000020  00 00 00 00 00 01 29 2c  72 18 ba 4e 4f 20 4e 41  |......),r..NO NA|
    00000030  4d 45 20 20 20 20 46 41  54 31 32 20 20 20 0e 1f  |ME    FAT12   ..|
    00000040  be 5b 7c ac 22 c0 74 0b  56 b4 0e bb 07 00 cd 10  |.[|.".t.V.......|
    00000050  5e eb f0 32 e4 cd 16 cd  19 eb fe 54 68 69 73 20  |^..2.......This |
    00000060  69 73 20 6e 6f 74 20 61  20 62 6f 6f 74 61 62 6c  |is not a bootabl|
    00000070  65 20 64 69 73 6b 2e 20  20 50 6c 65 61 73 65 20  |e disk.  Please |
    00000080  69 6e 73 65 72 74 20 61  20 62 6f 6f 74 61 62 6c  |insert a bootabl|
    00000090  65 20 66 6c 6f 70 70 79  20 61 6e 64 0d 0a 70 72  |e floppy and..pr|
    000000a0  65 73 73 20 61 6e 79 20  6b 65 79 20 74 6f 20 74  |ess any key to t|
    000000b0  72 79 20 61 67 61 69 6e  20 2e 2e 2e 20 0d 0a 00  |ry again ... ...|
    000000c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    *
    000001f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 aa  |..............U.|
    00000200  f0 ff ff 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    00000210  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    *
    00001400  f0 ff ff 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    00001410  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    *
    00002600  e5 41 4d 45 20 20 20 20  20 20 20 20 00 00 fa 9e  |.AME        ....|
    00002610  91 4b 91 4b 00 00 f5 9e  91 4b 03 00 0c 00 00 00  |.K.K.....K......|
    00002620  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    *
    00004400  68 65 6c 6c 6f 20 77 6f  72 6c 64 0a 00 00 00 00  |hello world.....|
    00004410  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    *
    00168000