File recovery from formatted hard drive


  • testdisk did nothing, found no recoverable partition and then cannot restore files
  • foremost doesn't manage plain ascii text (they don't probably have real markers or whatever)

Now, the happy story:

  • I accidentally formatted the wrong hard drive, ok, that's not that bad.
  • And reinstalled debian on it. Upgraded packages, installed, done some service configurations, mysql, nginx. Oops...
  • I haven't backupped some asterisk configuration because this hard drive wasn't supposed to be formatted.
  • I needed to recover theses files.


  • The poor hard drive (/dev/sda)
  • Another hard drive (in my case two USB drives, /mnt/usb1 and /mnt/usb2, each with enough to store the full /dev/sda)
  • I preferred to have two hard drives, one to store the image and another to store whatever extracted from it, may help for usb speed
  • dd, strings, cp, etc.
  • A pizza. (I ate one, this may help you too)


dd if=/dev/sda of=/mnt/usb1/hdd.bin bs=1M

Make indexes

When finished, you remember some patterns of your config file, right ?

In my case it was something like [], don't remember the case, if there where a dash or whatever.

Extract all strings matching this:

strings -t d /mnt/usb1/hdd.bin | grep -i "ovh" | grep "\[" | grep "\]" | tee /mnt/usb2/

-t d will print a decimal offset, we will use that to get some "index" in the hdd.bin file.

After long times, we may have some things:

19527608307 exten => _0[67]X.,1,NoOp(SIP/To-Ovh/P_${EXTEN}, ${TIMEOUT}, ${DIAL_OPTS})
19527609393 [Dp-From-Ovh]

Not really automatic extraction

Now is the best part, start with:

dd if=/mnt/usb1/hdd.bin bs=1 count=100 skip=19527608307

bs will stay at 1, count is the number of bs to show after skip (our "index").

What i've done is to round the index, like 19527608307 then 19527608300 then 19527608000, etc.

In backward, because you want to get the start of the file. Round as close as possible of the top without getting too many garbage.

You will finally get the start of the file, then increment the count, 100, 1000, 10000, 10500, 11000 etc.

Finally you will may end with SOME VERSION of your config file, there is multiple version, or "revisions" as you edited them in the past.

You will need to do that for every repetitting index found in the file like:

19527627416 [sip-ovh](!)            ; OVH Template
19527627812 [To-Ovh](sip-ovh)
19527627878 [From-Ovh](sip-ovh)
21673001628 [sip-ovh](!)            ; OVH Template
21673002024 [To-Ovh](sip-ovh)
21673002043 [From-Ovh](sip-ovh)
21673005724 [sip-ovh](!)            ; OVH Template
21673006120 [To-Ovh](sip-ovh)
21673006139 [From-Ovh](sip-ovh)

Then do the dd bs count skip for every index (the one matching ; OVH Template, for example), then diff them and found the latest.

You will not have any timestamp or anything unless your config have it in plain text.

Have fun.