恢复linux上删除的文件
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
续查找符号表。因此,我们可以在自己编写的库函数中实现一部分系统调用,并将这个库优先于系统库加载,
这样就能欺骗系统使用我们自己 定义的系统调用来执行原有的操作。具体到 e2undel 上来说,就是要在调
用这些系统调用删除文件时,记录下文件名和索引节点号之间的对应关系。
在编译 e2undel 源代码之后,还会生成一个库文件 libundel.so.1.0,其中包含了删除文件时所使用的一些系 统调用的钩子函数。e2undel 官方主页上下载的源码包中仅仅包括了对 unlink(2) 和 remove(3) 这两个系统 调用的钩子函数,但是从 2.6.16 版本的内核开始,引入了一系列新的系统调用,包括 faccessat(2), fchmodat(2), fchownat(2), fstatat(2), futimesat(2), linkat(2), mkdirat(2), mknodat(2), openat(2), readlinkat(2), renameat(2), symlinkat(2), unlinkat(2), mkfifoat(3) 等,尽管这些系统调用目前还没有成为 POSIX 标准的一部分,但是相信这个过程不会很久了。目前诸如 Fecora Core 8 之类的系统中自带的 rm 命 令(属于 coreutils)包已经使用这些新的系统调用进行了改写,另外本文下载部分中的补丁文件中已经提供 了对 rmdir 和 unlinkat 的钩子函数。部分源代码如下所示:
如何恢复 Linux 上删除的文件
自动恢复工具 e2undel
回想一下,在 ext2 文件系统中删除一个文件时,该文件本身的数据并没有被真正删除,实际执行的操作如
下:
1. 在块位图中将该文件所占用的数据块标识为可用状态。 2. 在索引节点位图中将该文件所占用的索引节点标识为可用状态。 3. 将该文件索引节点中的硬链接数目设置为 0。 4. 将该文件索引节点中的删除时间设置为当前时间。 5. 将父目录项中该文件对应项中的索引节点号设置为 0,并扩展前一项,使其包含该项所占用的空间。
/dev/sda2 opened for read-only access /dev/sda2 was not cleanly unmounted.
Do you want wo continue (y/n)? y 489600 inodes (489583 free) 977956 blocks of 4096 bytes (941677 free) last mounted on Fri Dec 28 16:21:50 2007
编译之后会生成一个名为 e2undel 的可执行文件,其用法如下:
清单 3. e2undel 的用法
# ./e2undel ./e2undel 0.82 usage: ./e2undel -d device -s path [-a] [-t] usage: ./e2undel -l '-d': file system where to look for deleted files '-s': directory where to save undeleted files '-a': work on all files, not only on those listed in undel log file '-t': try to determine type of deleted files w/o names, works only with '-a' '-l': just give a list of valid files in undel log file
清单 2. 编译 e2undel
# tar -zxf e2undel-0.82.tgz # patch -p0 < e2undel-0.82.patch patching file e2undel-0.82/Makefile patching file e2undel-0.82/e2undel.h patching file e2undel-0.82.orig/libundel.c # cd e2undel-0.82 # make all
而索引节点中的一些关键信息(或称为元数据,包括文件属主、访问权限、文件大小、该文件所占用的数据 块等)都并没有发生任 何变化。因此只要知道了索引节点号,就完全可以用本系列文章介绍的技术将文件完
பைடு நூலகம்整地从磁盘上恢复出来了,这正是 e2undel 之类的工具赖以生存的基础。
然而,由于所删除的文件在目录项中对应的项中的索引节点号被清空了,因此我们就无法从索引节点中获得 文件名的信息了。不过,由于文件大小、属主和删除时间信息依然能反映文件的原始信息,因此我们可以通 过这些信息来帮助判断所删除的文件是哪个。
清单 1. 确认系统中已经安装了 e2fsprogs 和 e2fsprogs-devel
# rpm -qa | grep e2fsprogs e2fsprogs-libs-1.39-7 e2fsprogs-1.39-7 e2fsprogs-devel-1.39-7
现在就可以开始编译 e2undel 了:
-------------+---------+---------+---------+---------+---------+--------
root |
0|
0|
0|
2|
0|
0
phost |
24 |
0|
0|
0|
0|
0
Select user name from table or press enter to exit:
name
-----------------------------------------------------------
13 35840 Dec 19 17:43 2007 * ASCII text
14 10485760 Dec 19 17:43 2007 * ASCII text
Select an inode listed above or press enter to go back: 13
35840 bytes written to /tmp/recover//inode-13-ASCII_text
Select an inode listed above or press enter to go back:
user name | 1 <12 h | 2 <48 h | 3 <7 d | 4 <30 d | 5 <1 y | 6 older
#
e2undel 是一个交互式的命令,命令执行过程中需要输入的内容已经使用黑体表示出来了。从输出结果中可 以看出,e2undel 一共在这个文件系统中找到了 26 个文件,其中 root 用户删除的有两个。这些文件按照删 除时间的先后顺序被划分到几类中。索引节点号 13 对应的是一个 ASCII 正文的文本文件,最终被恢复到 /tmp/recover//inode-13-ASCII_text 文件中。查看一下这个文件就会发现,正是我们在本系列前两部分中删 除的那个 35KB 的测试文件。
e2undel 实际上并没有像前面介绍的使用 e2fsck 那样的方法一样真正将已经删除的文件恢复到原来的文件系 统中,因为它并不会修改磁盘上 ext2 使用的内部数据结构(例如索引节点、块位图和索引节点位图)。相 反,它仅仅是将所删除文件的数据恢复出来并将这些数据保存到一个新文件中。因此,-s 参数指定是保存恢 复出来的文件的目录,最好是在另外一个文件系统上,否则可能会覆盖磁盘上的原有数据。如果指定了 -t 参 数,e2undel 会试图读取文件的前 1KB 数据,并试图从中确定该文件的类型,其原理与系统中的 file 命令
2|
0|
0
phost |
24 |
0|
0|
0|
0|
0
Select user name from table or press enter to exit: root
Select time interval (1 to 6) or press enter to exit: 4
inode
size deleted at
reading log file: opening log file: No such file or directory no entries for /dev/sda2 in log file searching for deleted inodes on /dev/sda2: |==================================================| 489600 inodes scanned, 26 deleted files found
非常类似,这些信息可以帮助判断正在恢复的是什么文件。
下面让我们来看一个使用 e2undel 恢复文件系统的实例。
清单 4. 使用 e2undel 恢复文件的实例
# ./e2undel -a -t -d /dev/sda2 -s /tmp/recover/ ./e2undel 0.82 Trying to recover files on /dev/sda2, saving them on /tmp/recover/
利用 libundel 库完美恢复文件
尽管 e2undel 可以非常方便地简化恢复文件的过程,但是美中不足的是,其恢复出来的文件的文件名却丢失 了,其原因是文件名是保存在父目录的目录项中的,而不是保存在索引 节点中的。本系列文章第 2 部分中给
出了一种通过遍历父目录的目录项来查找已删除文件的文件名的方法,但是由于索引节点会被重用,因此通 过这种方式恢复出来的文件名也许并不总是正确 的。另外,如果目录结构的非常复杂,就很难确定某个文件
类的命令一次删除了很多文件,这种信息就可以用来非常方便地帮助确定希望恢复的是哪些文件。在选择要
恢复的文件之后,e2undel 会从磁盘上读取该文件占用的数据块(这些数据块的信息全部保存在索引节点 中),并将其写入到一个新文件中。下面我们来看一下 e2undel 这个工具的详细用法。
首先请从 e2undel 的主页(http://e2undel.sourceforge.net/)上下载最新的源码包(截止到撰写本文为止, 最新的版本是 0.82),并将其保存到本地文件系统中。不过这个源码包在最新的 Fedora Core 8 上编译时可 能会有些问题,这是由于 ext2 文件系统内部实现中一些数据结构的变化引起来的,读者可以下载本文“下载” 部分给出的补丁来修正这个问题(请下载这个补丁文件 e2undel-0.82.patch,并将其保存到与源码包相同的 目录中)。要想编译 e2undel,系统中还必须安装 e2fsprogs 和 e2fsprogs-devel 这两个包,其中有编译 e2undel 所需要的一些头文件。Fedora Core 8 中自带的这两个包的版本号是 1.39-7:
user name | 1 <12 h | 2 <48 h | 3 <7 d | 4 <30 d | 5 <1 y | 6 older
-------------+---------+---------+---------+---------+---------+--------
root |
0|
0|
0|
的父目录究竟是哪个,因此查找正确文件名的难度就会变得很大。如果能在删除文件时记录下索引节点号 和 文件名之间的对应关系,这个问题就能完美地解决了。
这个问题在 e2undel 中得到了完美的解决。实际上,所有删除命令,例如 rm、unlink 都是通过一些底层的 系统调用(例如 unlink(2)、rmdir(2))来实现的。基于这一点,e2undel 又利用了 Linux 系统中动态链接 库加载时提供的一种便利:如果设置了环境变量 LD_PRELOAD,那么在加载动态链接库时,会优先从 $LD_PRELOAD 指向的动态链接库中查找符号表,然后才会在系统使用 ldconfig 配置的动态链接库中继
e2undel 是由 Oliver Diedrich 开发的一个用来恢复 ext2 文件系统中已删除文件的工具,它会遍历所检测的
文件系统的索引节点表,从中找出所有被标记为删除的索引节点,并按照属主和删除时间列出这些文件。另
外,e2undel 还提供了文件大小信息,并试图按照 file 命令的方式来确定文件类型。如果您使用 rm –rf * 之
这样就能欺骗系统使用我们自己 定义的系统调用来执行原有的操作。具体到 e2undel 上来说,就是要在调
用这些系统调用删除文件时,记录下文件名和索引节点号之间的对应关系。
在编译 e2undel 源代码之后,还会生成一个库文件 libundel.so.1.0,其中包含了删除文件时所使用的一些系 统调用的钩子函数。e2undel 官方主页上下载的源码包中仅仅包括了对 unlink(2) 和 remove(3) 这两个系统 调用的钩子函数,但是从 2.6.16 版本的内核开始,引入了一系列新的系统调用,包括 faccessat(2), fchmodat(2), fchownat(2), fstatat(2), futimesat(2), linkat(2), mkdirat(2), mknodat(2), openat(2), readlinkat(2), renameat(2), symlinkat(2), unlinkat(2), mkfifoat(3) 等,尽管这些系统调用目前还没有成为 POSIX 标准的一部分,但是相信这个过程不会很久了。目前诸如 Fecora Core 8 之类的系统中自带的 rm 命 令(属于 coreutils)包已经使用这些新的系统调用进行了改写,另外本文下载部分中的补丁文件中已经提供 了对 rmdir 和 unlinkat 的钩子函数。部分源代码如下所示:
如何恢复 Linux 上删除的文件
自动恢复工具 e2undel
回想一下,在 ext2 文件系统中删除一个文件时,该文件本身的数据并没有被真正删除,实际执行的操作如
下:
1. 在块位图中将该文件所占用的数据块标识为可用状态。 2. 在索引节点位图中将该文件所占用的索引节点标识为可用状态。 3. 将该文件索引节点中的硬链接数目设置为 0。 4. 将该文件索引节点中的删除时间设置为当前时间。 5. 将父目录项中该文件对应项中的索引节点号设置为 0,并扩展前一项,使其包含该项所占用的空间。
/dev/sda2 opened for read-only access /dev/sda2 was not cleanly unmounted.
Do you want wo continue (y/n)? y 489600 inodes (489583 free) 977956 blocks of 4096 bytes (941677 free) last mounted on Fri Dec 28 16:21:50 2007
编译之后会生成一个名为 e2undel 的可执行文件,其用法如下:
清单 3. e2undel 的用法
# ./e2undel ./e2undel 0.82 usage: ./e2undel -d device -s path [-a] [-t] usage: ./e2undel -l '-d': file system where to look for deleted files '-s': directory where to save undeleted files '-a': work on all files, not only on those listed in undel log file '-t': try to determine type of deleted files w/o names, works only with '-a' '-l': just give a list of valid files in undel log file
清单 2. 编译 e2undel
# tar -zxf e2undel-0.82.tgz # patch -p0 < e2undel-0.82.patch patching file e2undel-0.82/Makefile patching file e2undel-0.82/e2undel.h patching file e2undel-0.82.orig/libundel.c # cd e2undel-0.82 # make all
而索引节点中的一些关键信息(或称为元数据,包括文件属主、访问权限、文件大小、该文件所占用的数据 块等)都并没有发生任 何变化。因此只要知道了索引节点号,就完全可以用本系列文章介绍的技术将文件完
பைடு நூலகம்整地从磁盘上恢复出来了,这正是 e2undel 之类的工具赖以生存的基础。
然而,由于所删除的文件在目录项中对应的项中的索引节点号被清空了,因此我们就无法从索引节点中获得 文件名的信息了。不过,由于文件大小、属主和删除时间信息依然能反映文件的原始信息,因此我们可以通 过这些信息来帮助判断所删除的文件是哪个。
清单 1. 确认系统中已经安装了 e2fsprogs 和 e2fsprogs-devel
# rpm -qa | grep e2fsprogs e2fsprogs-libs-1.39-7 e2fsprogs-1.39-7 e2fsprogs-devel-1.39-7
现在就可以开始编译 e2undel 了:
-------------+---------+---------+---------+---------+---------+--------
root |
0|
0|
0|
2|
0|
0
phost |
24 |
0|
0|
0|
0|
0
Select user name from table or press enter to exit:
name
-----------------------------------------------------------
13 35840 Dec 19 17:43 2007 * ASCII text
14 10485760 Dec 19 17:43 2007 * ASCII text
Select an inode listed above or press enter to go back: 13
35840 bytes written to /tmp/recover//inode-13-ASCII_text
Select an inode listed above or press enter to go back:
user name | 1 <12 h | 2 <48 h | 3 <7 d | 4 <30 d | 5 <1 y | 6 older
#
e2undel 是一个交互式的命令,命令执行过程中需要输入的内容已经使用黑体表示出来了。从输出结果中可 以看出,e2undel 一共在这个文件系统中找到了 26 个文件,其中 root 用户删除的有两个。这些文件按照删 除时间的先后顺序被划分到几类中。索引节点号 13 对应的是一个 ASCII 正文的文本文件,最终被恢复到 /tmp/recover//inode-13-ASCII_text 文件中。查看一下这个文件就会发现,正是我们在本系列前两部分中删 除的那个 35KB 的测试文件。
e2undel 实际上并没有像前面介绍的使用 e2fsck 那样的方法一样真正将已经删除的文件恢复到原来的文件系 统中,因为它并不会修改磁盘上 ext2 使用的内部数据结构(例如索引节点、块位图和索引节点位图)。相 反,它仅仅是将所删除文件的数据恢复出来并将这些数据保存到一个新文件中。因此,-s 参数指定是保存恢 复出来的文件的目录,最好是在另外一个文件系统上,否则可能会覆盖磁盘上的原有数据。如果指定了 -t 参 数,e2undel 会试图读取文件的前 1KB 数据,并试图从中确定该文件的类型,其原理与系统中的 file 命令
2|
0|
0
phost |
24 |
0|
0|
0|
0|
0
Select user name from table or press enter to exit: root
Select time interval (1 to 6) or press enter to exit: 4
inode
size deleted at
reading log file: opening log file: No such file or directory no entries for /dev/sda2 in log file searching for deleted inodes on /dev/sda2: |==================================================| 489600 inodes scanned, 26 deleted files found
非常类似,这些信息可以帮助判断正在恢复的是什么文件。
下面让我们来看一个使用 e2undel 恢复文件系统的实例。
清单 4. 使用 e2undel 恢复文件的实例
# ./e2undel -a -t -d /dev/sda2 -s /tmp/recover/ ./e2undel 0.82 Trying to recover files on /dev/sda2, saving them on /tmp/recover/
利用 libundel 库完美恢复文件
尽管 e2undel 可以非常方便地简化恢复文件的过程,但是美中不足的是,其恢复出来的文件的文件名却丢失 了,其原因是文件名是保存在父目录的目录项中的,而不是保存在索引 节点中的。本系列文章第 2 部分中给
出了一种通过遍历父目录的目录项来查找已删除文件的文件名的方法,但是由于索引节点会被重用,因此通 过这种方式恢复出来的文件名也许并不总是正确 的。另外,如果目录结构的非常复杂,就很难确定某个文件
类的命令一次删除了很多文件,这种信息就可以用来非常方便地帮助确定希望恢复的是哪些文件。在选择要
恢复的文件之后,e2undel 会从磁盘上读取该文件占用的数据块(这些数据块的信息全部保存在索引节点 中),并将其写入到一个新文件中。下面我们来看一下 e2undel 这个工具的详细用法。
首先请从 e2undel 的主页(http://e2undel.sourceforge.net/)上下载最新的源码包(截止到撰写本文为止, 最新的版本是 0.82),并将其保存到本地文件系统中。不过这个源码包在最新的 Fedora Core 8 上编译时可 能会有些问题,这是由于 ext2 文件系统内部实现中一些数据结构的变化引起来的,读者可以下载本文“下载” 部分给出的补丁来修正这个问题(请下载这个补丁文件 e2undel-0.82.patch,并将其保存到与源码包相同的 目录中)。要想编译 e2undel,系统中还必须安装 e2fsprogs 和 e2fsprogs-devel 这两个包,其中有编译 e2undel 所需要的一些头文件。Fedora Core 8 中自带的这两个包的版本号是 1.39-7:
user name | 1 <12 h | 2 <48 h | 3 <7 d | 4 <30 d | 5 <1 y | 6 older
-------------+---------+---------+---------+---------+---------+--------
root |
0|
0|
0|
的父目录究竟是哪个,因此查找正确文件名的难度就会变得很大。如果能在删除文件时记录下索引节点号 和 文件名之间的对应关系,这个问题就能完美地解决了。
这个问题在 e2undel 中得到了完美的解决。实际上,所有删除命令,例如 rm、unlink 都是通过一些底层的 系统调用(例如 unlink(2)、rmdir(2))来实现的。基于这一点,e2undel 又利用了 Linux 系统中动态链接 库加载时提供的一种便利:如果设置了环境变量 LD_PRELOAD,那么在加载动态链接库时,会优先从 $LD_PRELOAD 指向的动态链接库中查找符号表,然后才会在系统使用 ldconfig 配置的动态链接库中继
e2undel 是由 Oliver Diedrich 开发的一个用来恢复 ext2 文件系统中已删除文件的工具,它会遍历所检测的
文件系统的索引节点表,从中找出所有被标记为删除的索引节点,并按照属主和删除时间列出这些文件。另
外,e2undel 还提供了文件大小信息,并试图按照 file 命令的方式来确定文件类型。如果您使用 rm –rf * 之