Board logo

标题: 如何恢复 Linux 上删除的文件-特殊文件的恢复(3) [打印本页]

作者: look_w    时间: 2018-5-22 15:02     标题: 如何恢复 Linux 上删除的文件-特殊文件的恢复(3)

现在再来查看一下这两个数据块中内容的变化:
清单16. 分析新目录项中的数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# ./read_dir_entry block.1536.deleted 4096
  offset | inode number | rec_len | name_len | file_type | name
=================================================================
     0:            2          12           1           2  .
    12:            2          12           2           2  ..
    24:           11          20          10           2  lost+found
    44:           12          24          13           1  createfile.sh
    68:           13          20          12           1  testfile.35K
    88:           14          32          12           1  testfile.10M
   108:            0          12           4           2  dir1
   120:           15          28          17           1  testfile.35K.orig
   148:           16        3948          17           1  testfile.10M.orig

# ./read_dir_entry block.88064.deleted 4096
  offset | inode number | rec_len | name_len | file_type | name
=================================================================
     0:        32577          12           1           2  .
    12:            2          12           2           2  ..
    24:        32578          24          13           1  createfile.sh
    48:        32579          16           8           2  subdir11
    64:        48865          16           8           2  subdir12
    80:        32580          20          12           1  testfile.35K
   100:        32581        3996          12           1  testfile.10M




与前面的结果进行一下对比就会发现,dir1 目录的数据块并没有发生任何变化,而根目录的数据块中 dir1 以及之前的一项则变得不同了。实际上,在删除 dir1 目录时,所执行的操作是将 dir1 项中的索引节点号清空,并将这段空间合并到前一项上(即将 dir1 项的 rec_length 加到前一项的 rec_length上)。这也就是为什么我们编写的 read_dir_entry 程序没有采用 rec_length 作为步长来遍历数据的原因。
除了数据之外,索引节点信息也发生了一些变化,现在我们来了解一下最新的索引节点信息:
清单17. 删除子目录后索引节点信息的变化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# debugfs /dev/sdb6
debugfs 1.39 (29-May-2006)
debugfs:  stat <2>
Inode: 2   Type: directory    Mode:  0755   Flags: 0x0   Generation: 0
User:     0   Group:     0   Size: 4096
File ACL: 0    Directory ACL: 0
Links: 3   Blockcount: 8
Fragment:  Address: 0    Number: 0    Size: 0
ctime: 0x474d3387 -- Wed Nov 28 17:23:19 2007
atime: 0x474d33c2 -- Wed Nov 28 17:24:18 2007
mtime: 0x474d3387 -- Wed Nov 28 17:23:19 2007
BLOCKS:
(0):1536
TOTAL: 1

debugfs:  stat <32577>
Inode: 32577   Type: directory    Mode:  0755   Flags: 0x0   Generation: 1695264350
User:     0   Group:     0   Size: 0
File ACL: 1542    Directory ACL: 0
Links: 0   Blockcount: 16
Fragment:  Address: 0    Number: 0    Size: 0
ctime: 0x474d3387 -- Wed Nov 28 17:23:19 2007
atime: 0x474d3387 -- Wed Nov 28 17:23:19 2007
mtime: 0x474d3387 -- Wed Nov 28 17:23:19 2007
dtime: 0x474d3387 -- Wed Nov 28 17:23:19 2007
BLOCKS:
(0):88064
TOTAL: 1




与删除之前的结果进行一下比较就会发现,主要区别包括:
通过了解数据块和索引节点的相应变化可以为恢复目录提供一个清晰的思路,其具体步骤如下:
实际上,步骤3并不是必须的,因为如果这个目录中包含文件或子目录,使用 debugfs 的 lsdel 命令(遍历索引节点表)也可以找到所删除的索引节点记录,采用本文中介绍的方法也可以将其逐一恢复出来。
debugfs 的 mi 命令可以用来直接修改索引节点的信息,下面我们就使用这个命令来修改 dir1 这个目录对应的索引节点的信息:
清单18. 使用 debugfs 的 mi 命令直接修改索引节点信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# debugfs -w /dev/sdb6
debugfs 1.39 (29-May-2006)
debugfs:  lsdel
Inode  Owner  Mode    Size    Blocks   Time deleted
32577      0  40755      0    1/   1 Wed Nov 28 17:23:19 2007
32578      0 100755   1406    1/   1 Wed Nov 28 17:23:19 2007
32579      0  40755      0    1/   1 Wed Nov 28 17:23:19 2007
32580      0 100644  35840    9/   9 Wed Nov 28 17:23:19 2007
32581      0 100644 10485760 2564/2564 Wed Nov 28 17:23:19 2007
48865      0  40755      0    1/   1 Wed Nov 28 17:23:19 2007
6 deleted inodes found.
debugfs:  mi <32577>
                          Mode    [040755]
                       User ID    [0]
                      Group ID    [0]
                          Size    [0] 4096
                 Creation time    [1196241799]
             Modification time    [1196241799]
                   Access time    [1196241799]
                 Deletion time    [1196241799] 0
                    Link count    [0] 4
                   Block count    [16]
                    File flags    [0x0]
                    Generation    [0x650bae5e]
                      File acl    [1542]
                 Directory acl    [0]
              Fragment address    [0]
               Fragment number    [0]
                 Fragment size    [0]
               Direct Block #0    [88064]
               Direct Block #1    [0]
               Direct Block #2    [0]
               Direct Block #3    [0]
               Direct Block #4    [0]
               Direct Block #5    [0]
               Direct Block #6    [0]
               Direct Block #7    [0]
               Direct Block #8    [0]
               Direct Block #9    [0]
              Direct Block #10    [0]
              Direct Block #11    [0]
                Indirect Block    [0]
         Double Indirect Block    [0]
         Triple Indirect Block    [0]
debugfs:  link <32577> dir1
debugfs:  q




注意要使用 mi 命令直接修改索引节点的信息,在执行 debugfs 命令时必须加上 –w 选项,表示以可写方式打开该设备文件。在上面这个例子中,lsdel 命令找到 6 个已经删除的文件,其中 32577 就是 dir1 目录原来对应的索引节点。接下来使用 mi 命令修改这个索引节点的内容,将 Size 设置为 4096(Block count * 512),Deletion Time 设置为 0,Links count 设置为 4。最后又执行了一个 link 命令,为这个索引节点起名为 dir1(这样并不会修改父目录的 Links count 值)。
退出 debugfs 并重新挂载这个设备,就会发现 dir1 目录已经被找回来了,不过尽管该目录下面的目录结构都是正确的,但是这些文件和子目录的数据都是错误的:
清单19. 验证恢复结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# mount /dev/sdb6 /tmp/test
# ls -li /tmp/test
total 20632
   12 -rwxr-xr-x 1 root root     1406 Nov 28 16:53 createfile.sh
32577 drwxr-xr-x 4 root root     4096 Nov 28 17:23 dir1
   11 drwx------ 2 root root    16384 Nov 28 16:52 lost+found
   14 -rw-r--r-- 1 root root 10485760 Nov 28 16:54 testfile.10M
   16 -rw-r--r-- 1 root root 10485760 Nov 28 16:57 testfile.10M.orig
   13 -rw-r--r-- 1 root root    35840 Nov 28 16:53 testfile.35K
   15 -rw-r--r-- 1 root root    35840 Nov 28 16:56 testfile.35K.orig

# ls -li /tmp/test/dir1
total 0
??--------- ? ? ? ?            ? /tmp/test/dir1/createfile.sh
??--------- ? ? ? ?            ? /tmp/test/dir1/subdir11
??--------- ? ? ? ?            ? /tmp/test/dir1/subdir12
??--------- ? ? ? ?            ? /tmp/test/dir1/testfile.10M
??--------- ? ? ? ?            ? /tmp/test/dir1/testfile.35K




其原因是 dir1 中所包含的另外两个子目录和三个文件都还没有恢复。可以想像,恢复一个删除的目录会是件非常复杂而繁琐的事情。幸运的是,e2fsck 这个工具可以很好地理解 ext2 文件系统的实现,它可以用来对文件系统进行检查,并自动修复诸如链接数不对等问题。现在请按照上面的方法使用 mi 命令将其他 5 个找到的索引节点 Deletion Time 设置为 0,并将 Link count 设置为 1。然后使用下面的命令,强制 e2fsck 对整个文件系统进行检查:
清单20. 使用 e2fsck 强制对文件系统进行一致性检查
1
# e2fsck -f -y /dev/sdb6 > e2fsck.out 2>&1




e2fsck 的结果保存在 e2fsck.out 文件中。查看这个文件就会发现,e2fsck要执行 4 个步骤的检查:
现在重新挂载这个文件系统,会发现所有的文件已经全部恢复出来了。




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0