这个问题是以下问题的衍生问题:如何从磁盘提取原始 ext3 inode 数据?
我有一个文件/tmp/foo,其内容是一个简单的文本字符串“AAA”。我想找到该数据所在的磁盘块#,提取该块中的数据并确保它确实包含“AAA”。所以我做了以下事情:
stat foo
它告诉我它的索引节点号是 318903debugfs -R 'imap <318903>' /dev/vda3
它告诉我这个 inode 位于块 1277956,偏移量 0x0600dumpe2fs /dev/vda3
这表明块大小为 4096(字节),inode 大小为 256(字节)- 计算 256 字节块中 inode 相对于磁盘起始位置的偏移量(使使用 dd 提取一个 256 字节块变得更简单): (1277956 x 4096) + (1536) / 256 = 20447302
- 从磁盘中提取inode(原始数据): dd if=/dev/sda3 of=/tmp/inode.0 bs=256 count=1 skip=20447302
- 查看 ext2 inode 表的结构(ext3 inode 具有相同的结构):http://www.nongnu.org/ext2-doc/ext2.html#INODE-TABLE
- 执行一些测试以确定我是否提取了正确的 inode 块:
chgrp 1 /tmp/foo; dd if=/dev/sda3 of=/tmp/inode.1 bs=256 count=1 skip=20447302; cmp -l /tmp/inode.1 /tmp/inode.0
。 cmp 的输出如下:
13 217 362 14 225 222 25 1 0
参考inode结构,我们看到字节25对应于i_gid,因此这证实了我们确实从磁盘中提取了正确的inode块(之前的组是0,现在是1)。还可以执行类似的测试,例如更改所有权、通过添加数据更改文件大小、从磁盘重新提取 inode,这些测试继续确认我们拥有正确的 inode 块。
- 现在,根据文档,inode 表的字节 41-44 包含指向数据块的指针(文件实际内容的块号 - 文件的数据)。如果我们将 inode 与零文件进行逐字节比较,我们可以看到字节 41-44 的值:
cmp -l /tmp/inode.1 /tmp/zero.256
25 1 0 27 1 0 29 10 0 41 56 0 42 220 0 43 23 0 101 275 0 102 53 0 103 240 0 104 374 0
“cmp”给出八进制值。因此,假设字节 44 是高位字节,则八进制指针的值为 23 | 220 | 220 56. 将其转换为二进制 = 10011 | 10010000 | 00101110 或 100111001000000101110。将其转换为十进制 = 1282094
- 现在,“1282094”对于我们的数据来说是一个合理的块号吗?如果我们再次查看 dumpefs 的输出,我们会看到 inode(块 1277956)和数据(块 1282094)都落在块组 39 覆盖的范围内,因此看起来我们有一个合理的数字:
第 39 组:(块 1277952-1310719)索引节点表位于 1277954-1278464 (+2)
- 因此,我们应该能够使用 dd 从磁盘中提取数据块,检查其内容,它们应该与我们的文件内容(“AAA”)匹配。但事实并非如此。发生的情况是数据块包含其他内容,并且任何地方都没有“AAA”:
dd if=/dev/vda3 of=/tmp/data bs=4096 count=1 skip=1282094; cmp -l /tmp/data /tmp/zero.4096
1 333 0 2 335 0 3 4 0 5 14 0 7 1 0 8 2 0 9 56 0 13 221 0 14 335 0 15 4 0 17 364 0 18 17 0 19 2 0 20 2 0 21 56 0 22 56 0
这看起来不像 /tmp/foo 的内容。我想也许我偏离了一个街区,所以我也提取了周围的街区(1282093和1282095),但仍然没有找到我要找的东西。
这里发生了什么?这些额外的东西是什么?为什么没有“AAA”?
11/14。解决了。事实证明,文件系统有一些问题(孤立的 inode 等),我用 fsck 修复了这些问题,现在一切都按预期运行。我想说非常感谢 Wumpus 和 derobert(见评论),他们提供了很多宝贵的见解和建议。惊人的。