前言:
在正常工作中经常会有数据恢复或者取证分析的场景,数据是否能被恢复,主要还是看数据是否被覆盖,正常情况下文件虽然被删除,只是修对应的标志位,文件本身数据并不会被破坏,所以我们就可以通过对硬盘的读取来恢复:
常见的硬盘格式有如下
1. FAT32 (File Allocation Table 32)
- 特点: 兼容性强,几乎所有操作系统都支持。
- 文件大小限制: 最大文件大小为 4 GB。
- 分区大小限制: 最大分区大小为 8 TB。
2. NTFS (New Technology File System)
- 特点: 主要用于 Windows 系统,支持文件权限、加密和压缩。
- 文件大小限制: 理论上最大为 16 TB。
- 分区大小限制: 最大分区大小为 256 TB。
3. exFAT (Extended File Allocation Table)
- 特点: 适用于闪存和移动设备,兼容性比 FAT32 更强,但不支持文件权限。
- 文件大小限制: 最大文件大小为 16 EB(Exabytes)。
- 分区大小限制: 最大分区大小为 128 PB(Petabytes)。
4. HFS+ (Hierarchical File System Plus)
- 特点: 苹果系统常用格式,支持文件权限和元数据。
- 文件大小限制: 最大文件大小为 8 EB。
- 分区大小限制: 最大分区大小为 8 EB。
5. APFS (Apple File System)
- 特点: 苹果最新的文件系统,优化了 SSD 的性能,支持加密和快照。
- 文件大小限制: 理论上最大为 8 EB。
- 分区大小限制: 最大分区大小为 8 EB。
6. EXT4 (Fourth Extended File System)
- 特点: Linux 系统常用格式,支持日志功能,性能优越。
- 文件大小限制: 最大文件大小为 16 TB。
- 分区大小限制: 最大分区大小为 1 EB。
7. Btrfs (B-tree File System)
- 特点: 现代 Linux 文件系统,支持快照、压缩和动态分配。
- 文件大小限制: 最大文件大小为 16 EB。
- 分区大小限制: 最大分区大小为 16 EB。
8. XFS
- 特点: 高性能的文件系统,特别适合处理大文件和高并发。
- 文件大小限制: 最大文件大小为 8 EB。
- 分区大小限制: 最大分区大小为 8 EB。
FAT32 格式:
常见的格式为FAT32,下面我们先了解下具体的FAT32硬盘存储格式,首先我们可以使用工具winhex对硬盘进行分析
https://www.x-ways.net/winhex/index-m.html
硬盘格式分析的比较枯燥,其中大部分都是网上找到的内容,初级恢复不用精通了解即可,但是涉及到数据分散存储就需要了解具体的存储链,才能恢复,主要就是算偏移:
0x00 0x20: 每扇区字节数,512(0X02 00)。
0x08: 最小单元(簇)为0x08(8)扇区,8*512=4K
0x46 0xCC 0xEC 0x00:文件系统总的扇区数:15518790 15518790*512=7.39G
0x02 0x00 0x00 0x00: 根目录所在第一个簇的簇号,通常情况下,根目录簇号为2
0x46 0x41 0x54 0x33 0x32 0x20 0x20 0x20:文件系统格式 FAT32
FSInfo信息分区 2号分区
【4】0x1E8~0x1EB: 4个字节,文件系统的空簇数,964466(0x00 0E B7 72)。
【5】0x1EC~0x1EF: 4个字节,下一可用簇号(0x 00 00 00 15)。
【7】0x1FE~0x1FF: 2个字节,“55 AA”标志。 结束
文件系统分配磁盘空间按簇来分配。因此,文件占有磁盘空间时,基本单位不是字节而是簇,即使某个文件只有一个字节,操作系统也会给它分配一个最小单元:即一个簇。对于大文件,需要分配多个簇。同一个文件的数据并不一定完整地存放在磁盘中一个连续地区域内,而往往会分若干段,像链子一样存放。这种存储方式称为文件的链式存储。为了实现文件的链式存储,文件系统必须准确地记录哪些簇已经被文件占用,还必须为每个已经占用的簇指明存储后继的下一个簇的簇号,对于文件的最后一簇,则要指明本簇无后继簇。这些都是由FAT表来保存的,FAT 表对应表项中记录着它所代表的簇的有关信息:诸如是空,是不是坏簇,是否是已经是某个文件的尾簇等。
【6号表项】:0x07 表项值为7,即指向下一个表项, 2号簇为根目录,对应的开始扇区为32768, 6号簇。开始的扇区为 32768 + 8 * (6-2)= 32800, 即为build.log的开始扇区。
【7号表项】:0x08 表项值为8,即指向下一个表项。
【8号表项】: 0x0FFFFFFF, 结束簇, 从6号簇build.log开始,到8号簇,文件结束。
数据区
数据提取
我们需要了解具体的硬盘格式,我们还需要知道磁盘是如何存储的,如果一个文件的大小是预先判定的固定大小,且后续不会增加,一盘会分配一个连续的空间给该文件存储,这种情况下我们就可以对磁盘内容遍历来恢复数据,但是如果文件内容会随着时间增加而越来越大,如果一个连续的空间无法存储完成这些数据,就会有一个存储链来记录下一个存储区块,所以正常情况下,我们首先需要进行初步数据提取,将需要提取的文件格式进行整理,然后将磁盘中的所有此类文件进行提取,这样可以获得一个非常完整的列表,然后找到自己需要处理的文件,查看是否能成功运行,如果不能运行,就要去看是否是因为存储块不是连续存储,需要根据存储链进行提取合并数据。
初步数据提取首先我们可以对数据进行备份,防止因为恢复数据导致的数据修改,并且可以分段存储,比较方便:
分段存储完毕后,可以去查找自己需要恢复文件的文件格式,我这里恢复视频格式为例子,我找到了大部分的视频格式的前缀:
- MP4 (MPEG-4 Part 14):
- 十六进制: 00 00 00 20 66 74 79 70 69 73 6F 6D
- 字符串: ftypisom
- AVI (Audio Video Interleave)
- 十六进制: 52 49 46 46 XX XX XX XX 41 56 49 20
- 字符串: RIFF...AVI
- MKV (Matroska)
- 十六进制: 1A 45 DF A3
- 字符串: Matroska
- WMV (Windows Media Video)
- 十六进制: 30 26 B2 75 B5 A2 00 00
- 字符串: .wmv
- FLV (Flash Video)
- 十六进制: 46 4C 56 01
- 字符串: FLV
- MOV (QuickTime)
- 十六进制: 00 00 00 20 66 74 79 70 71 74 20 20
- 字符串: ftypqt
- WebM
- 十六进制: 1A 45 DF A3
- 字符串: Matroska (与 MKV 相同)
- 3GP (3rd Generation Partnership Project)
- 十六进制: 00 00 00 20 66 74 79 70 33 67 70 35
- 字符串: ftyp3gp5
- MPEG (MPEG Video)
- 十六进制: 00 00 01 BA
- 字符串: MPEG
- OGG (Ogg)
- 十六进制: 4F 67 67 53
- 字符串: OggS
第一种方案,我可以使用工具进行提取,这里使用 FFmpeg 等工具可以有效识别和提取大型文件中的视频流
https://ffmpeg.org/download.html
命令
ffmpeg -i yourfile.ext
如果您识别了视频流(例如,流编号为 0),可以使用以下命令提取视频:
ffmpeg -i yourfile.ext -map 0:0 -c copy output_video.mp4
或者可以使用ffmpeg进行批量提取:
import subprocess
import redef get_video_stream_count(input_file):# 获取视频流的数量command = ['ffmpeg', '-i', input_file]result = subprocess.run(command, stderr=subprocess.PIPE, text=True)# 使用正则表达式查找视频流数量match = re.findall(r'Stream #(\d+:\d+)', result.stderr)return len(match)def extract_video(input_file, output_file_prefix):stream_count = get_video_stream_count(input_file)for stream_index in range(stream_count):output_file = f"{output_file_prefix}_stream{stream_index}.mp4"command = ['ffmpeg', '-i', input_file, '-map', f'0:{stream_index}', '-c', 'copy', output_file]print(f"Extracting stream {stream_index} to {output_file}...")subprocess.run(command)# 示例用法
input_file = 'yourfile.ext' # 输入文件
output_file_prefix = 'output_video' # 输出文件前缀extract_video(input_file, output_file_prefix)
或者可以自行编写代码对指定格式文件通过前缀进行提取,需要注意的就是文件大小,还需要根据对应的文件协议,获取到对应的文件大小,并进行截取,不过是否截取问题也不大,并不会影响文件正常的使用,只是大小会有区别。
这样全盘扫描的方式来定向恢复,我们可以恢复出磁盘中的所有该文件格式的数据,下面就是需要找到自己需要的文件,查看其文件是否提取完整,如果不完整,就需要去查看存储链,根据存储链地址获取数据进行拼接即可