如何找到 ext4 文件系统的偏移量?

Ern*_*t A 12 filesystems partition ext4 data-recovery

我的硬盘出现故障,无法写入或读取磁盘的第一个扇区。它只会给出 I/O 错误,仅此而已。磁盘上还有其他区域(大部分)看起来不错。我正在尝试挂载一个分区 (ext4),看看我是否可以访问一些我想要恢复的文件。由于该mount命令支持一个offset选项,即使分区表不可读和不可写,我也应该能够挂载文件系统。问题是如何找到偏移量。ext4 工具似乎都没有这个特殊功能。

der*_*ert 15

本身没有标准的偏移量,当然你可以在任何你想要的地方启动分区。但是让我们暂时假设您正在寻找第一个分区,并且它的创建或多或少接受了默认值。假设您使用的是传统的 DOS 分区表,您可能会在两个地方找到它:

  1. 从(512 字节)扇区 63 开始。这是很长一段时间以来的传统,一直工作到有人想出了 4K 磁盘......
  2. 从(512 字节)扇区 2048 开始。这是新的传统,以容纳 4K 磁盘。
  3. 奖励选项!从扇区 56 开始。如果有人移动 63-start 分区以使其与 4K 扇区对齐,就会发生这种情况。

现在,要继续,您需要选择您最喜欢的 hex-dump 工具,并了解一些有关ext4 磁盘布局的知识。特别是,它以 1024 字节的填充开始,ext4 会忽略它。接下来是超级块。您可以通过检查偏移量 0x38(从超级块开始,或从分区开始的 0x438,或十进制的 1080)处的幻数 0xEF53 来识别超级块。幻数是小端的。所以它实际上作为 0x53EF 存储在磁盘上。

下面是它的样子xxd -a

0000000: 0000 0000 0000 0000 0000 0000 0000 0000 ................ * 0000400: 0040 5d00 0084 7401 33a0 1200 33db a600 .@]...t.3...3... 0000410: 4963 5300 0000 0000 0200 0000 0200 0000 IcS............. 0000420: 0080 0000 0080 0000 0020 0000 6637 0952 ......... ..f7.R 0000430: 6637 0952 0200 1600 53ef 0100 0100 0000 f7.R....S....... 0000440: 9938 f851 004e ed00 0000 0000 0100 0000 .8.Q.N..........

请注意,当您为 mount(或 lossup)提供偏移量时,您必须为填充开始的位置提供偏移量 - 而不是超级块。

现在,如果它不是第一个分区,或者不在两(三)个预期位置之一,您基本上可以搜索幻数 0xEF53。这就是testdisk(在评论中推荐)为您做的事情。

  • 成功!!!我不得不编写自己的脚本。`testdisk` 找不到它。谢谢大家的帮助。 (2认同)

mwf*_*ley 5

根据@derobert 的回答,我编写了一个程序 ( gist ),它将解析来自dd每个扇区的输入流并扫描每个扇区以查找看起来像 ext 分区开头的内容。

它的工作速度至少与dd从硬盘读取的速度一样快。精简版如下。

最简单的用法是sudo dd if=/dev/xxx | ext2scan,尽管您可能希望修改dd命令以改善块大小或选择要搜索的区域。

#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main() {
  unsigned char const MAGIC[2] = {0x53, 0xef};
  unsigned char const ZEROS[512] = {0};

  long long int sector = 0;

  char buf[4][512];
  int empty1, empty2;

  while (read(STDIN_FILENO, buf[sector&3], 512) > 0) {
    if (!memcmp(buf[sector&3] + 0x38, MAGIC, 2)) {
      printf("Found a possible ext2 partition at sector %lld", sector-2);

      empty1 = !memcmp(buf[(sector-2)&3], ZEROS, 512);
      empty2 = !memcmp(buf[(sector-1)&3], ZEROS, 512);

      if (empty1 && empty2) printf(" (first two sectors are empty :)\n");
    }
    sector++;
  }
}
Run Code Online (Sandbox Code Playgroud)

注意:它不仅会找到分区的开头,还会找到其中的超级块

无论哪种情况,我都建议使用dumpe2fs来分析结果。您可以将可疑超级块的开头转储到一个文件中(根据我的非正式测试,至少是前六个扇区),如果它是超级块,dumpe2fs则将告诉您(除其他外)其他超级块的相对位置.