百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

数据恢复(二)-linux下ext文件系统数据恢复思路深入分析

mhr18 2024-12-02 17:46 14 浏览 0 评论

在上一篇文章《数据恢复(一)-linux下ext文件系统数据删除原理浅析》中分析了ext数据删除的原理,这篇文章中会结合实例分析数据恢复的原理。

ext 含义

全称Linux extended file system, extfs,即Linux扩展文件系统,Ext2就代表第二代文件扩展系统,Ext3/Ext4以此类推,它们都是Ext2的升级版,只不过为了快速恢复文件系统,减少一致性检查的时间,增加了日志功能,所以Ext2被称为索引式文件系统,而Ext3/Ext4被称为日志式文件系统。并且Linux还支持很多文件系统,包括XFS、NFS、Fat等文件系统。

ext3/4 数据恢复思路

由于Ext3/Ext4被称为日志式文件系统,所以文件的删除会有日志记录。就意味着被删除的inode的block指针还可以从journal日志的inode副本中找到,也就有可能从磁盘中恢复出被删除的文件。

经过extundelete、ext3grep、ext4magic等几款linux下ext数据恢复软件的测试,总结出ext数据恢复的原理。

journal日志恢复

基于journal日志从inode副本中找到block指针从而确定被删除文件在磁盘上的物理位置进行恢复。

文件特征恢复

扫描整个磁盘,基于文件魔数(Magic Number)特征直接从磁盘中恢复文件。
很多类型的文件,其起始的几个字节的内容是固定的。这几个字节的内容也被称为魔数,因为根据这几个字节的内容就可以确定文件类型。

实验环境

  • 腾讯云轻量服务器1核1g
  • 操作系统 centos7、ext4文件系统

模拟ext3下文件删除后进行恢复

因为实验环境中centos7默认用的是ext4的文件系统,但是要测试ext3的文件删除,通常需要挂载一个新的硬盘并格式化为ext3。这里提供一个更简单的解决办法。

dd生成一个2G大小的空文件

[root@VM-8-8-centos newpart]# pwd
/newpart
[root@VM-8-8-centos newpart]# dd if=/dev/zero of=test.ext3 bs=1024M count=2
dd: memory exhausted by input buffer of size 1073741824 bytes (1.0 GiB)
[root@VM-8-8-centos newpart]# dd if=/dev/zero of=test.ext3 bs=128M count=16
16+0 records in
16+0 records out
2147483648 bytes (2.1 GB, 2.0 GiB) copied, 13.2437 s, 162 MB/s
[root@VM-8-8-centos newpart]# ll -h
total 2.1G
-rw-r--r-- 1 root root 2.0G Mar 11 23:28 test.ext3

可以看到第一次使用dd命令生成空文件时报错了,dd: memory exhausted by input buffer of size。申请的内存的过大,超过了内存的限制。这里要生成一个2G的文件,一次写入内存的大小为1024M即1G,而机器的内存只有1G,超出内存限制导致dd命令报错。所以可以将bs的值改小,并分为多次写入文件,对最后生成的文件大小不会有影响。

mkfs.ext3将空文件格式化为ext3文件系统

[root@VM-8-8-centos newpart]# mkfs.ext3 -I 128 test.ext3
mke2fs 1.45.6 (20-Mar-2020)
Discarding device blocks: done
Creating filesystem with 524288 4k blocks and 131072 inodes
Filesystem UUID: 8f008c7a-dc08-4efe-86ca-d0fcd6c61dab
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912
Allocating group tables: done
Writing inode tables: done
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done
[root@VM-8-8-centos newpart]# file test.ext3
test.ext3: Linux rev 1.0 ext3 filesystem data, UUID=8f008c7a-dc08-4efe-86ca-d0fcd6c61dab (large files)

这里指定生成inode-size大小为128的ext文件系统,默认为256(后面会解释)。

挂载ext3文件到系统目录

[root@VM-8-8-centos newpart]# df -Th
Filesystem Type Size Used Avail Use% Mounted on
/dev/vda1 ext4 25G 8.2G 16G 35% /
/dev/vdb1 ext4 40G 180M 37G 1% /newpart
[root@VM-8-8-centos newpart]# mount -o loop test.ext3 /ext3
[root@VM-8-8-centos newpart]# df -Th
Filesystem Type Size Used Avail Use% Mounted on
/dev/vda1 ext4 25G 8.2G 16G 35% /
/dev/vdb1 ext4 40G 180M 37G 1% /newpart
/dev/loop1 ext3 2.0G 3.1M 1.9G 1% /ext3
[root@VM-8-8-centos newpart]# cd /ext3/
[root@VM-8-8-centos ext3]# mkdir test && cd test
[root@VM-8-8-centos test]# cp /etc/passwd ./
[root@VM-8-8-centos test]# ls -ilh
total 4.0K
98306 -rw-r--r-- 1 root root 1.8K Mar 11 23:59 passwd

此时已经将我们的ext3文件作为文件系统挂载到系统目录中。进入该分区中,拷贝passwd作为测试文件。
补充:mount-o loop 文件 目录,使用 loop 模式用来将一个档案当成硬盘分割挂上系统。

模拟文件删除并记录block指针

[root@VM-8-8-centos test]# debugfs /dev/loop1 -R "ls -d /test"
debugfs 1.45.6 (20-Mar-2020)
98305 (12) . 2 (12) .. 98306 (4072) passwd
[root@VM-8-8-centos test]# debugfs /dev/loop1 -R "imap <98306>"
debugfs 1.45.6 (20-Mar-2020)
Inode 98306 is part of block group 12
 located at block 393218, offset 0x0080
[root@VM-8-8-centos test]# debugfs /dev/loop1 -R "blocks <98306>"
debugfs 1.45.6 (20-Mar-2020)
16994
[root@VM-8-8-centos test]# rm -f passwd //模拟文件删除
[root@VM-8-8-centos test]# debugfs /dev/loop1 -R "ls -d /test"
debugfs 1.45.6 (20-Mar-2020) //删除后的文件inode带有尖括号显示
98305 (12) . 2 (4084) .. <98306> (4072) passwd
[root@VM-8-8-centos test]# debugfs /dev/loop1 -R "blocks <98306>"
debugfs 1.45.6 (20-Mar-2020)

//文件被删除后,原inode的block指针被填0,获取为空

这里需要强度的是虽然将ext3文件系统挂载到了系统的/ext3目录下,但是文件系统本身也有根目录(区别于系统根目录),因此这里使用ls -d /test,而非ls -d /ext3/test。

在删除文件之前特地记录了inode中block的值,也就是磁盘中该文件的真实位置。使用dd命令读取该block位置的文件。

删除文件后根据删除前的block仍能在磁盘中找到该文件。因此要想成功恢复被删除的文件,关键在于如何从journal日志中找到inode副本中的block值。
该例中文件的block为16994,只要能在日志中找到16994这个值就能恢复文件。

使用debugfs的logdump获取日志中inode副本

[root@VM-8-8-centos test]# debugfs /dev/loop1 -R "logdump -i <98306>"
debugfs 1.45.6 (20-Mar-2020)
Inode 98306 is at group 12, block 393218, offset 128
Journal starts at block 1, transaction 2
 FS block 393218 logged at sequence 47, journal block 369 (flags 0x2)
(inode block for inode 98306):
 Inode: 98306 Type: bad type Mode: 0000 Flags: 0x0
 Generation: 0 Version: 0x00000000
 User: 0 Group: 0 Size: 0
 File ACL: 0
 Links: 0 Blockcount: 0
 Fragment: Address: 0 Number: 0 Size: 0
 ctime: 0x00000000 -- Thu Jan 1 08:00:00 1970
 atime: 0x00000000 -- Thu Jan 1 08:00:00 1970
 mtime: 0x00000000 -- Thu Jan 1 08:00:00 1970
 Blocks: //该副本中为空
 FS block 393218 logged at sequence 50, journal block 397 (flags 0x2)
(inode block for inode 98306):
 Inode: 98306 Type: regular Mode: 0644 Flags: 0x0
 Generation: 4264657513 Version: 0x00000001
 User: 0 Group: 0 Size: 1825
 File ACL: 0
 Links: 1 Blockcount: 8
 Fragment: Address: 0 Number: 0 Size: 0
 ctime: 0x622b71c8 -- Fri Mar 11 23:59:04 2022
 atime: 0x622b71c8 -- Fri Mar 11 23:59:04 2022
 mtime: 0x622b71c8 -- Fri Mar 11 23:59:04 2022
 Blocks: (0+1): 16994 //被删除文件的inode副本中的block指针
 .....
No magic number at block 1620: end of journal.

注意上面的 Blocks: (0+1): 16994 为block指针。

使用logdump 命令在journal日志中找到了多个indoe为98306的副本,这里只展示了两个。第一个block记录为空,在第二个副本中找到了原始block的指针,且与之前记录的文件block指针值一致,证明该方法有效,可成功恢复文件。

使用dd从磁盘中dump恢复文件

[root@VM-8-8-centos test]# dd if=/dev/loop1 bs=4096 count=1 skip=16994 2>/dev/null
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
...// 确定该block的文件就是被删除的文件内容
[root@VM-8-8-centos test]# dd if=/dev/loop1 bs=4096 count=1 skip=16994 of=passwd
1+0 records in
1+0 records out
4096 bytes (4.1 kB, 4.0 KiB) copied, 6.0939e-05 s, 67.2 MB/s
[root@VM-8-8-centos test]# ll -h
total 4 //文件恢复成功!
-rw-r--r-- 1 root root 4K Mar 12 00:50 passwd

文件恢复成功!没有使用任何数据恢复软件,仅使用linux自带的命令恢复了被删除的文件。

补充:为什么使用dd命令dump恢复的文件MD5值不一样?

[root@VM-8-8-centos test]# md5sum /etc/passwd
5e39a7f4aa25cd0de397c1685597460b /etc/passwd
[root@VM-8-8-centos test]# md5sum passwd
118c4d51a0425cf6d028076a54ba7fa9 passwd
[root@VM-8-8-centos test]# diff -Naur /etc/passwd passwd
--- /etc/passwd 2022-03-10 11:04:45.106866879 +0800
+++ passwd 2022-03-12 00:50:51.000000000 +0800
@@ -34,3 +34,4 @@
 lighthouse:x:1000:1000::/home/lighthouse:/bin/bash
 zgao:x:0:1001::/home/zgao:/bin/bash
 redis:x:991:984:Redis Database Server:/var/lib/redis:/sbin/nologin
+
\ No newline at end of file

很明显两者的md5并不相同,但用cat看到的内容却一样。因为dd命令是按照bs的大小来dump文件的,因为文件系统block-size为4096,整块一起dump包括了文件结尾填0部分,所以两者的md5值会不同。

小结

这里通过ext3演示了文件删除后的通过日志的方式恢复文件过程,由于ext4和ext3都是日志文件系统,数据恢复思路是一样的,就不再赘述了。

debugfs的logdump命令存在bug?

在大量ext3/4的数据恢复实验中发现,logdump命令并不一定成功!网上有大量误导人的文章,根本没有弄清楚原理!在此花费了大量时间验证!

结论:无论ext3、4,只有在文件系统的inode-size值为128时,logdump命令计算得到的journal日志才是正确的。而ext3默认indoe-size为128,ext4默认为256,因此通常ext3下使用logdump的结果是正确的,ext4则是错误的!

关于在ext4中如何从journal日志中正确获取indoe副本会在后续的系列文章中分析。

基于文件特征进行文件恢复

这种恢复思路最典型的实现工具就是 foremost 。

foremost是一款根据文件头,尾和内部结构来尝试从镜像文件(或者磁盘)中恢复文件的工具。foremost默认可以扫描出 jpg, gif, png, bmp, avi, exe, mpg, mp4, wav, riff, wmv 等文件。但是通过配置它的配置文件(默认为 /etc/foremost.conf),你还可以为它增加新的支持类型。

工具的使用网上有很多教程,这里只分析其实现原理。

文件类型

文件头

文件尾




JPG

FF D8 FF E0

FFD9

GIF

47 49 46 38


PSD

38 42 50 53


PNG

89 50 4E 47

AE 42 60 82

GIF

47 49 46 38

00 3B

BMP

42 4D


TIFF

49 49 2A 00


ZIP

50 4B 03 04

50 4B

MS Word/Excel (xls.or.doc)

D0 CF 11 E0


PDF

25 50 44 46 2D 31 2E


RAR

52 61 72 21


常见文件类型的文件头尾

分析png图片文件格式特征

以下图为例,一张png格式的图片。

将其放在上面创建的ext3分区中,并模拟删除。

[root@VM-8-8-centos test]# ll -h
total 152K
-rw-r--r-- 1 root root 143K Mar 12 01:45 logo.png
-rw-r--r-- 1 root root 4.0K Mar 12 00:50 passwd
[root@VM-8-8-centos test]# xxd logo.png
00000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452 .PNG........IHDR
00000010: 0000 1a7e 0000 059b 0806 0000 00ba cb9c ...~............
00000020: 5100 0000 0970 4859 7300 002e 2300 002e Q....pHYs...#...
...... //省略文件中间部分,只看开头和结尾
000239d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000239e0: 0030 058e 25e5 446a 69a6 1500 0000 0049 .0..%.Dji......I
000239f0: 454e 44ae 4260 82 END.B`.

模拟png图片文件被删除

对比上表的png文件头尾,头部89 50 4E 47,尾部AE 42 60 82。

[root@VM-8-8-centos test]# debugfs /dev/loop1 -R "ls -d /test"
debugfs 1.45.6 (20-Mar-2020)
98305 (12) . 2 (12) .. 98306 (56) passwd
98307 (4016) logo.png
[root@VM-8-8-centos test]# debugfs /dev/loop1 -R "blocks <98307>"
debugfs 1.45.6 (20-Mar-2020)
17302 17303 17304 17305 17306 17307 17308 17309 17310 17311 17312 17313 16794 17314 17315 17316 17317 16816 16817 16818 16819 16820 16821 16822 16823 16824 16825 16826 16827 16828 16829 16830 16831 17632 17633 17634 17635 //该图片文件包含多个连续block
[root@VM-8-8-centos test]# rm -f logo.png
[root@VM-8-8-centos test]# debugfs /dev/loop1 -R "ls -d /test"
debugfs 1.45.6 (20-Mar-2020)
98305 (12) . 2 (12) .. 98306 (4072) passwd
<98307> (4016) logo.png
[root@VM-8-8-centos test]# debugfs /dev/loop1 -R "blocks <98307>"
debugfs 1.45.6 (20-Mar-2020)
// 文件被删除后获取block指针为空

暴力搜索匹配文件特征

[root@VM-8-8-centos test]# xxd /newpart/test.ext3 | grep "8950 4e47"
04396000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452 .PNG........IHDR
[root@VM-8-8-centos test]# xxd /newpart/test.ext3 | grep "ae 4260 82"
044e39f0: 454e 44ae 4260 8200 0000 0000 0000 0000 END.B`..........

将ext3分区看做成一个大文件,进行暴力搜索匹配文件特征(头部和尾部特征)。

如果我们使用dd命令进行dump,这里需要用到16进制来计算,4096的十六进制为1000。由于文件头部肯定在任意一个block的起始位置,所以相除必为整数倍。

在线16进制计算工具

这里算出来的值和我们之前用debugfs看到的block值相等。此时只要再算出偏移位置即可从磁盘中恢复文件。

使用dd将文件从磁盘中dump出来

[root@VM-8-8-centos test]# dd if=/newpart/test.ext3 bs=4096 count=1 skip=17302 | xxd
00000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452 .PNG........IHDR
00000010: 0000 1a7e 0000 059b 0806 0000 00ba cb9c ...~............
00000020: 5100 0000 0970 4859 7300 002e 2300 002e Q....pHYs...#...
00000030: 2301 78a5 3f76 0000 0019 7445 5874 536f #.x.?v....tEXtSo
00000040: 6674 7761 7265 0041 646f 6265 2049 6d61 ftware.Adobe Ima
00000050: 6765 5265 6164 7971 c965 3c00 0239 8449 geReadyq.e<..9.I
00000060: 4441 5478 daec dd01 0100 200c 8030 b57f DATx...... ..0..

对于大文件,由于文件block不一定连续,还需要从起始block中获取到下一个block所在位置进行索引,再将文件“拼起来”即可恢复被删除的文件。

对于文件不连续的情况,会在后面的数据恢复系列文章中深入分析。

总结

本文从ext两种数据恢复的思路深入分析,未使用任何数据恢复工具的前提下,逐步展示了数据恢复的原始过程,希望大家对数据恢复有更深刻的理解。

相关推荐

【推荐】一个开源免费、AI 驱动的智能数据管理系统,支持多数据库

如果您对源码&技术感兴趣,请点赞+收藏+转发+关注,大家的支持是我分享最大的动力!!!.前言在当今数据驱动的时代,高效、智能地管理数据已成为企业和个人不可或缺的能力。为了满足这一需求,我们推出了这款开...

Pure Storage推出统一数据管理云平台及新闪存阵列

PureStorage公司今日推出企业数据云(EnterpriseDataCloud),称其为组织在混合环境中存储、管理和使用数据方式的全面架构升级。该公司表示,EDC使组织能够在本地、云端和混...

对Java学习的10条建议(对java课程的建议)

不少Java的初学者一开始都是信心满满准备迎接挑战,但是经过一段时间的学习之后,多少都会碰到各种挫败,以下北风网就总结一些对于初学者非常有用的建议,希望能够给他们解决现实中的问题。Java编程的准备:...

SQLShift 重大更新:Oracle→PostgreSQL 存储过程转换功能上线!

官网:https://sqlshift.cn/6月,SQLShift迎来重大版本更新!作为国内首个支持Oracle->OceanBase存储过程智能转换的工具,SQLShift在过去一...

JDK21有没有什么稳定、简单又强势的特性?

佳未阿里云开发者2025年03月05日08:30浙江阿里妹导读这篇文章主要介绍了Java虚拟线程的发展及其在AJDK中的实现和优化。阅前声明:本文介绍的内容基于AJDK21.0.5[1]以及以上...

「松勤软件测试」网站总出现404 bug?总结8个原因,不信解决不了

在进行网站测试的时候,有没有碰到过网站崩溃,打不开,出现404错误等各种现象,如果你碰到了,那么恭喜你,你的网站出问题了,是什么原因导致网站出问题呢,根据松勤软件测试的总结如下:01数据库中的表空间不...

Java面试题及答案最全总结(2025版)

大家好,我是Java面试陪考员最近很多小伙伴在忙着找工作,给大家整理了一份非常全面的Java面试题及答案。涉及的内容非常全面,包含:Spring、MySQL、JVM、Redis、Linux、Sprin...

数据库日常运维工作内容(数据库日常运维 工作内容)

#数据库日常运维工作包括哪些内容?#数据库日常运维工作是一个涵盖多个层面的综合性任务,以下是详细的分类和内容说明:一、数据库运维核心工作监控与告警性能监控:实时监控CPU、内存、I/O、连接数、锁等待...

分布式之系统底层原理(上)(底层分布式技术)

作者:allanpan,腾讯IEG高级后台工程师导言分布式事务是分布式系统必不可少的组成部分,基本上只要实现一个分布式系统就逃不开对分布式事务的支持。本文从分布式事务这个概念切入,尝试对分布式事务...

oracle 死锁了怎么办?kill 进程 直接上干货

1、查看死锁是否存在selectusername,lockwait,status,machine,programfromv$sessionwheresidin(selectsession...

SpringBoot 各种分页查询方式详解(全网最全)

一、分页查询基础概念与原理1.1什么是分页查询分页查询是指将大量数据分割成多个小块(页)进行展示的技术,它是现代Web应用中必不可少的功能。想象一下你去图书馆找书,如果所有书都堆在一张桌子上,你很难...

《战场兄弟》全事件攻略 一般事件合同事件红装及隐藏职业攻略

《战场兄弟》全事件攻略,一般事件合同事件红装及隐藏职业攻略。《战场兄弟》事件奖励,事件条件。《战场兄弟》是OverhypeStudios制作发行的一款由xcom和桌游为灵感来源,以中世纪、低魔奇幻为...

LoadRunner(loadrunner录制不到脚本)

一、核心组件与工作流程LoadRunner性能测试工具-并发测试-正版软件下载-使用教程-价格-官方代理商的架构围绕三大核心组件构建,形成完整测试闭环:VirtualUserGenerator(...

Redis数据类型介绍(redis 数据类型)

介绍Redis支持五种数据类型:String(字符串),Hash(哈希),List(列表),Set(集合)及Zset(sortedset:有序集合)。1、字符串类型概述1.1、数据类型Redis支持...

RMAN备份监控及优化总结(rman备份原理)

今天主要介绍一下如何对RMAN备份监控及优化,这里就不讲rman备份的一些原理了,仅供参考。一、监控RMAN备份1、确定备份源与备份设备的最大速度从磁盘读的速度和磁带写的带度、备份的速度不可能超出这两...

取消回复欢迎 发表评论: