在 dd 图像中搜索字符串,并从中提取数据

在 dd 图像中搜索字符串,并从中提取数据

我正在尝试恢复因断电而损坏的文本文件的内容。文件大小仍然正确(14 MB),但下半部分的文本已被空格替换。

我的灵感来自:

我的 dd 映像快完成了。我已对整个分区进行了映像,大约 850 MB。

现在,我不知道如何搜索。理想情况下(如果它仍然存在……),我希望取回大约 260k 行的一大块,即整个后半部分。虽然如果这个太大而无法提取,文件中间的 10 000 行就足够了。

我必须承认我不熟悉“偏移量”、十六进制/十进制等。即使是 grep 手册对我来说也不是那么容易理解;尽管我会坚持下去!

无论如何。你会推荐什么?我并不只关注 dd image 和 grep;我欢迎任何建议!谢谢。

答案1

如果相关文件是纯文本文件(Linux 可以理解,即 UTF-8)并且您复制的文件系统dd既未加密也未压缩,请strings在图像上使用。

对于给定的每个文件,GNUstrings都会打印至少 4 个字符长(或使用下面选项给出的数量)且后跟不可打印字符的可打印字符序列。

(来源:man 1 strings

你想要类似这样的东西:

strings -aw -e S -n 512 ddimage >extracted

(或pv ddimage | strings -aw -e S -n 512 >extracted查看进度)。

然后extracted将得到一个您可以使用来查看less、使用grep等来搜索的文件。在我的测试中,-e S检测包含多字节字符的 UTF-8 文本至关重要。

可能存在的问题:

  • 您查找的数据可能零散,散布在文件各处,不一定按顺序排列。可能有旧版本,可能有其他文件的片段(垃圾,包括二进制文件的文本片段);所有这些都可能交错。这将是一个文本拼图。考虑使用-s--output-separator)选项,但请记住,如果图像中有不相关的片段严格相邻,那么您将不会在它们之间得到分隔符,就好像它们是一块更大的块一样。

  • 如果您复制的文件系统dd位于 SSD 上,并且 TRIM 是在事故发生后但在您复制之前执行的,那么您想要恢复的数据可能会丢失。这是一个糟糕的情况。

    另一方面,如果文件系统位于 SSD 上,并且在发生故障之前执行了 TRIM,而故障和复制之间没有 TRIM,那么 TRIM 可能会清除不相关的旧数据、旧版本的文件等,但不会清除您想要的数据。实际上,您将获得更少的垃圾。这是一个好的情况。

    如您所见,SSD 可能是一个缺点,也可能是一个优点。对于 HDD,这些情况并不适用。虚拟磁盘可能支持类似于 TRIM 的功能。

  • -n 512告诉工具打印至少 512 个字节长的序列。手册上说的是“字符”,但我对 UTF-8 多字节字符的测试表明它肯定是“字节”。数字越小,您得到的垃圾就越多。另一方面,您不应该超过映像文件系统使用的块大小,该块大小至少为 512(块设备的最小常见扇区大小)。您没有提到文件系统,它的块大小可能是 4096 或 8192。关键是您的文件可能会碎片化,并且-n如果文本块恰好位于非文本数据之间,则块大小大于该值将丢失文本块。如果您的文件很小(比-n您使用的要小),那么您可能会完全错过它。同样,如果所需文件的尾部恰好不与其他文本相邻,您可能会错过该部分。

    仍然-n 512应该能让你找到几乎所有现有的文件残余(不需要的垃圾和碎片可能比丢失的部分更成问题)。除非……

  • 一开始我写的是“文件系统 […] 既未加密也未压缩”。加密或压缩的文件系统将以非纯文本形式存储文本数据,因此strings毫无用处。我猜某些文件系统的其他一些功能可能会降低您的机会或导致一些额外的垃圾。

  • extracted可能相对较大。我strings -awe S -n 4096在大约 477 GiB 的系统驱动器上执行,输出超过 10 GiB。建议进行一些过滤,例如grep -av '[[:lower:]][[:upper:]]'是一个合理的过滤器(但请注意,它会过滤掉包含kHzkBmacOS的行MacGyver);在我的情况下,它将 10+ GiB 减少到 6 GiB。

    我注意到你的整个图像大约有 850 MB,而不是非常大。您的文件extracted不会更大。即使经过过滤,它仍然可能太大,无法进行“手动”检查。最终,您可能需要使用好的文本编辑器或分页器(能够处理大型文本文件)以交互方式搜索您知道的字符串,这些字符串存在于要恢复的文件中。这样,您就有希望找到相关的片段。

    考虑复制extracted/dev/shm(或使用vmtouch -l) 来加快您的工作。

相关内容