NTFS 上恢复已删除文件,归结为两个时钟和一条简单规则。时钟:MFT 记录槽位被复用要多久,数据簇被覆盖要多久。规则:只要这两个时钟之中任一个对你还有用,就别向这块卷写入。
下面这套就是当有人把一块 NTFS 卷递给我并说"他们删了 X,能救回来吗"时,我真正会跑的恢复流程。不管 X 是一个文件、一棵目录树,还是 SDelete 处理过的某个目录里的全部内容,我都从同一套工具箱里挑。
为什么删除并不是擦除
Windows 从 NTFS 卷上删除一个文件时:
- 记录头偏移 0x16 处 flags 字段中的
IN_USE(bit 0)被清掉。 - 承载数据的簇在
$Bitmap中被标记为空闲。 - 父目录的
$INDEX_ROOT条目被移除。
不会发生的:没有任何东西覆盖记录或簇。它们被标记为下次分配时可用。在别的东西认领它们之前,文件是可恢复的。逐字段细节见 删除后还剩什么。
MFT 槽位恢复时钟和数据簇恢复时钟是独立的。你可能遇到记录已经被复用(槽位现在是另一个文件)但数据簇仍保留旧字节的情况;也可能遇到已删除记录完好、但簇被分配给新文件的情况。两种情形需要不同的恢复策略。
第 1 步:停止向该卷写入
每次写入都可能让被删除记录的槽位或其数据簇被复用。如果该文件重要:
- 停掉触碰过它的应用。如果是数据库,关引擎。如果是文档,关编辑器。
- 如果文件在系统盘上、且系统仍在运行,那么操作系统本身一直在写(分页、prefetch、注册表、事件日志)。请关机或从外部介质启动。一台在线系统在按秒泄露可恢复空间。
- 对外部盘,立即卸载。Windows 上是弹出,Linux 上是
umount。
这是大家在以为恢复"很容易"时容易跳过的一步。我见过的失败恢复案例中,有一半就是栽在这一步。
第 2 步:对磁盘做镜像
在副本上工作,永远不在原盘上。标准方案:
- FTK Imager:免费、GUI,输出
.dd或.E01镜像,读取过程中对源做哈希。 - Linux 上的
dd:dd if=/dev/sdX of=disk.img bs=4M conv=noerror,sync status=progress。健康盘上很快。 ddrescue:更慢,但对故障盘上的读错误容忍度高。当盘本身是问题(咔嗒声、读取缓慢、SMART 警告)时它就是正确选择。
采集完毕立刻对镜像做哈希(SHA-256)。后续所有步骤都针对镜像,绝不针对原盘。
第 3 步:选择正确的恢复路径
路径取决于还有什么是完好的。
MFT 重放 适用于被删除文件的记录仍在表里时。用能列出已删除记录的工具解析 $MFT。文件名、时间戳、父目录,以及(对小文件)数据,可直接从记录里恢复。对非常驻文件,runlist 仍指向原始簇;只要它们尚未被覆盖,icat 或同类工具可提取数据。
支持文件系统的恢复工具 适合当你想要从某卷或镜像里以 GUI 驱动做有选择的还原时:
- R-Studio:商业软件,是 NTFS 上分析师的首选。能处理复杂的损坏、能从被格式化的卷恢复,并理解 EFS 与 BitLocker(需有密钥)。
- TestDisk + PhotoRec:免费、成熟,适合处理分区损坏。PhotoRec 是按签名 carve 而非感知文件系统,所以会失去文件名。
- Recuva:消费级。在简单卷上做单文件单盘恢复尚可。我不会拿它做调查。
签名 carving 适用于 MFT 没了或记录被复用时。scalpel、foremost、PhotoRec 扫描原始镜像,寻找已知文件签名(JPEG FF D8 FF、PNG 89 50 4E 47、ZIP 50 4B 03 04、PDF 25 50 44 46),并把找到的拼起来。被 carve 出来的文件会失去文件名与时间戳;那些信息住在 MFT 里。字节本身能回来,但要看碎片化情况。
对碎片化文件,签名 carving 很吃力。carver 会把看起来对的连续簇拼起来,但若文件本就散落各处,就拼不回来。NTFS 感知的 MFT 重放能正确处理碎片化,因为 runlist 明确地描述了每一个片段。
第 4 步:当 MFT 恢复是唯一出路
小文件($DATA 不到约 700 字节)完整存在于 MFT 记录里。即使 $Bitmap 已被覆盖几十次,常驻字节也仍然待在记录里,直到槽位被复用。见 resident data。
对小文本文件、小 JSON 配置、PowerShell 脚本、注册表导出、小证书或 .lnk 文件,浏览器解析器 往往是最快的路径:把抽取出来的 $MFT 拖进去,过滤已删除项,找出有常驻 $DATA 的记录,把字节复制回来。这在别的方法都不奏效时仍然管用,因为数据从未离开过 MFT。
真正无法恢复的情形
被覆盖的簇。 现代 HDD 与 SSD 都没有现实的路径去恢复已被覆盖一次的数据。老取证文献里那种关于"残留磁化"的幻想恢复,对本世纪生产的盘并不适用。密度太高、磁头定位太精确。
被 TRIM 回收的 SSD 块。 一旦 SSD 控制器对一个块做了 TRIM,底层闪存就会在垃圾回收时被清零。数据会很快消失。在现代 Windows 上,删除到 TRIM 完成之间的窗口至多以秒计。
没有密钥的加密卷。 用 BitLocker、VeraCrypt 或 LUKS 加密的 NTFS 卷,无密钥就无法恢复。明文从一开始就没碰过磁盘。
被合格擦写器擦除过的文件。 sdelete -p 3 -z -s -q C:\target\* 会把文件簇覆盖三次、把空闲空间清零并递归。数据簇的恢复无望;MFT 记录可能仍含元数据与常驻数据,但实质性的文件内容没了。
常驻数据:物理学站在你这边的情况
常驻数据这种情况不断让初级分析师感到惊讶。低于阈值的文件就内联在 MFT 记录里。记录会一直留到槽位被复用。数据区域无关;即使 $Bitmap 被覆盖了一千次,常驻字节依然在那里。
我曾从一块在删除后又被使用两周、且大部分已被覆盖的硬盘上,恢复出一份 400 字节的 .config 文件。MFT 中超过 230,000 号的那一槽位没被复用。整份文件就在那里,常驻在记录中。五分钟工夫。
正因如此,对小文件我总会先尝试以 MFT 为先的恢复路径,再去碰数据区。
常见问题
NTFS 上的已删除文件能保持多久可恢复?
直到 MFT 槽位被复用且数据簇被覆盖为止。在繁忙系统上以小时计。在空闲系统上可能有数月。没有固定计时器;这由卷的分配压力驱动。
清空回收站会让恢复更难吗?
不会。回收站 是每个卷上的一个隐藏目录($Recycle.Bin)。清空它就在 NTFS 意义上删除了里面的文件;同样的恢复手法依旧适用。清空之前,文件其实只是 \$Recycle.Bin\<SID>\ 下名为 $R<ID> 的普通 NTFS 文件;伴生的 $I<ID> 记录原始路径。
用 del /F 或 Shift+Delete 删的文件能恢复吗?
可以。这两种方式只是跳过了回收站,但删除方式是一样的(IN_USE 被清、簇被释放)。MFT 记录仍在那里直到被复用。
能从被格式化的 NTFS 盘恢复文件吗?
快速格式化只重写引导扇区与一份全新的 $MFT。多数旧数据簇仍然完好,许多旧的 MFT 记录(NTFS 复用相同的起始偏移)可通过对原始卷做 FILE 头签名 carving 来恢复。完全格式化会把卷清零;这些数据真的没了。
删除前被重命名的文件呢?
删除之后的 MFT 记录显示的是最终名(重命名之后的)。USN journal 保留 RENAME_OLD_NAME / RENAME_NEW_NAME 这一对,因此你可以从那里恢复原始名字。
延伸阅读
- Brian Carrier,File System Forensic Analysis。讨论 NTFS 删除语义与恢复的章节。
- Sleuth Kit 的
fls -d与icat -r文档。已删除文件枚举与数据恢复的规范命令行工作流。 - PhotoRec 文档。当 MFT 不再是正确工具时,签名 carving 的参考资料。