Liuw's Thinkpad

想要赢就先学会输,想要成功就先学会失败

Archive for the ‘recover’ tag

用Grep去找Raw Data的一个小实验

with one comment

在某处看到一篇文章,使用grep来找回没有分区表的硬盘中的文本文件内容。基本命令是:

grep "keyword" /dev/DEVICE

有可能需要加上其他的一些选项。

能这样做是因为在Unix中万物皆文件,即使没有Filesystem的信息,也可以通过bypass掉Filesystem的方法去读取block,得到raw data。

这个方法是有局限的。Filesystem处理数据时以block为单位,而多block的文件,block的分布不一定是连续的。也就是说grep也许能找到一部分数据,但是不大可能把所有的数据都找回来。当然,一个block一般是1K或者4K找回来的数据量对于一个文本文件来说也是相当可观的了。

为了证实我的想法,我做了以下的实验。

dd if=/dev/urandom of=hd.img bs=1M count=10

之所以用urandom而不是zero做输入,是为了增加数据,模拟真实的Filesystem。

losetup hd.img /dev/loop0

把这个文件连接到loop0,成为一个设备。

mkfs.ext3 -b 1024 /dev/loop0
mount /dev/loop0 /mnt
echo -e "This is a small file for testing.\nsecond line\nthird line" > /mnt/f1
umount /mnt

建立block大小为1024的ext3分区,然后挂载,向里面写入少量数据(少于1个block)。

grep --binary-files=text -z "file" /dev/loop0

不用-z的话,只会grep一行。

这样确实可以看到原来文件的内容。假如文件修改过有几个版本的话,可能还可以看到几个版本的内容。也许这是一个提高Filesystem效率的措施。

再测试大于1 block的文件。

perl -e 'print "string1 " x 128; print "string2 " x 128' > /mnt/f2
perl -e 'print "string3 " x 128; print "string4 " x 128' > /mnt/f3
for i in `seq 4 9`; do echo "$i" > "f$i" ; done
perl -e 'print "paddin" x 128' >> /mnt/f2
perl -e 'print " ssssss " x 128' >> /mnt/f2
...

上面其实进行了很多操作,这里就不一一列出了。block大小为1K,用stat可以看到它们的I/O block。之所以做多个文件,是为了防止ext3 bitmap在再次分配block的时候分配连续block,模拟真实环境。写完文件之后记得sync或者umount,把cache都flush到硬盘上。

再grep一次,可以发现各种数据是夹杂在一起的。

所以,最好还是注意保护自己的Filesystem吧。这些技巧只能解决小问题。

Written by liuw

August 29th, 2010 at 6:49 pm

Posted in Security,UNIX-like

Tagged with , , ,