文件系统3:NTFS

NFTS总体结构如下

MFTMirr只备份前四个对象,但其位置相对不固定,通过Boot区确定其位置

Boot区#

Boot区最多占16个扇区。第1个扇区是带有“引导”代码的引导扇区(DBR),接下来的15个扇区是引导扇区的初始程序加载器。在NTFS分区的最后一个扇区留有DBR备份。第一个扇区结构如下:

偏移 意义
0-2 跳转指令
3-A 厂商名
B-C 每扇区的字节数
D 每个簇的扇区数
E-F 保留扇区
10-12 总是0
13-14 NTFS不使用
15 介质描述符
16-17 总是0
18-19 每个轨道的扇区
1A-1B 轨道数
1C-1F 隐藏的扇区,其实就是从磁盘开始到第一个分区的扇区数
20-27 NTFS不使用
28-2F 总扇区数
30-37 MFT的簇号
38-3F MFTMirr的簇号
40 int8,每个MFT占用的字节数,值为2^(-1*字段的值)
41-43 保留
44 每个索引目录(文件夹记录文件名的地方)的簇数
45-47 NTFS不使用
48-4F 卷号
50-53 校验和
54-1FD 引导代码
1FE-1FF 扇区结束标记55 AA

举例#

以磁盘0的D分区为例,分区格式为NTFS

从分区起始处的Boot区出发,数据如下,可以看到每簇扇区数为8,MFT在3簇,所以MFT在相对此分区开始的8*3扇区,此分区从2048扇区开始,所以MFT在2048+8*3=2072扇区。
可以在偏移40处知道每个MFT对象占2^(-1*-10)=1024B

主文件表 (MFT)#

MFT包含了所有文件的信息,每个文件对应一个MFT对象,其中有几个文件是初始化时就创建好的,被称为元文件

元文件种类#

文件名 在MFT记录中的顺序,即索引号 作用
$MFT 0 主文件表,包含了所有文件的信息
MFTMMirr|1|MFT前4个表项的备份
$LogFile 2 日志文件
$Volume 3 卷标和卷版本信息
$AttrDef 4 属性定义表
$Root 5 根文件夹
$Bitmap 6 位图,显示哪些簇在使用
$Boot 7 引导扇区
$BadClus 8 坏簇列表文件
$Secure 9 安全文件,用来控制文件的访问权限
$UpCase 10 大小写字符转换表,将小写字符转换为Unicode大写字符
$Extend 11 用于各种扩展
保留 12-15 保留
$Quota 24 配额管理文件,因为NTFS可以为每个用户设置其可以使用的最大空间
$ObjId 25 对象ID文件
$Reoarse 26 重解析点文件
$RmMetadata 27 记录事务元数据,即最近对文件系统的修改

MFT对象结构#

每个MFT对象由MFT记录头和多个不同的属性组成。结构图示大致如下:

MFT记录头的结构#

偏移 意义
0-3 签名,值为46 49 4C 45,即为FILE
4-5 更新序列号的偏移,在每个MFT对象所在的扇区尾,都会有2字节相同的标记值,用于保持一致性,被称为更新序列号
6-7 更新序列号的个数
8-F 日志序列号
10-11 序列号,第几个MFT对象(从1编号,备份$MFTMMirr的也为1)
12-13 硬链接数
14-15 第一个属性的偏移地址
16-17 标志,0:删除的文件,1:正常的文件,2:删除的目录,3:正常的目录
18-1B 此MFT对象的字节长度
1C-1F 此MFT对象分配的字节长度
20-27 基本文件记录中的文件索引号,只有在一个MFT对象无法完全存储一个文件时才使用,从0开始编号
28-29 下一个属性ID
2A-2B 保留
2C-2F 此MFT对象在MFT中的索引号(从0编号)
30-31 更新序列号,在每个MFT对象所在的扇区尾,都会有2字节相同的标记值,用于保持一致性,被称为更新序列号
32-33 更新数组1,如果数据在第一个扇区还没有完,但是结尾已经有更新序列号占了两个字节,就把本应该写在此处的两字节写在更新数组1处
34-35 更新数组2,与上同理,是数据在第二个扇区还没有完

举例

由BOOT区知MFT在2072扇区,所以MFT数据如下:

  • 其中红框偏移4-5处为更新序列号偏移,为30H处,所以为第二个红框处,其值为3A 00即更新序列号。在该扇区尾部即第三个红框处,也为更新序列号,要保持一致。
  • 偏移14-15处显示第一个属性偏移为38H,所以在偏移38H即红线处为第一个属性开始。
  • 2C-2F处显示为0,即索引号为0,表示该MFT对象对应的是一个元文件$MFT

属性的种类#

属性类型(16进制) 描述
10 记录标准信息
20 属性列表:当一个文件需要多个文件记录时,用来描述文件的属性列表
30 文件名属性
40 对象ID
50 安全描述
60 卷名
70 卷信息
80 文件数据内容
90 索引(可以看做是文件夹)根属性
A0 索引分配树节点,当90属性存储不下使用
B0 MFT文件和索引的位图
C0 重解析点
D0 扩充属性信息
E0 扩充属性
F0 早期NTFS才有的属性
100 EFS加密属性

属性结构#

每个属性可以分为两个部分:属性头和属性体

因为一个MFT对象空间有限,如果要MFT对象要记录的属性超过空间大小,剩下的部分就要在MFT之外的区域存储,存储采用簇流运行的方式。因此对以上属性又可以分为常驻属性,即优先保存在MFT区域中,和非常驻属性,即优先放到MFT区域外。

簇流是存放数据的区域
簇流运行是记录簇流具体在文件系统哪个位置的代码
簇流运行第一个字节的低四位表示:该字节后几个字节为一组,这一组表示簇流的大小
簇流运行第一个字节的高四位表示:该字节后几个字节为一组,这一组表示簇流的起始簇号(相对于当前簇流),如果起始簇号为负,表示下个簇流在这个簇流前面

常驻属性的结构如下:

偏移(相对于每个属性内) 意义
0-3 属性类型
4-7 属性的总字节数
8 0:常驻属性,1:非常驻属性
9 属性名的长度
A-B 相对于属性头的属性名的偏移
C-D 0001:压缩,4000:加密,8000:稀疏
E-F 属性ID
10-13 属性体的字节数
14-15 属性体相对属性的偏移,因为在属性头后可能有属性名
16 索引标志
17 保留
18- 属性体

非常驻属性结构如下:

偏移(相对于每个属性内) 意义
0-3 属性类型
4-7 属性的总字节数
8 0:常驻属性,1:非常驻属性
9 属性名的长度
A-B 相对于属性头的属性名的偏移
C-D 0001:压缩,4000:加密,8000:稀疏
E-F 属性ID
10-17 文件数据起始虚拟簇号,一定为00
18-1F 文件数据结束虚拟簇号
20-21 簇流运行的偏移地址
22-23 压缩的大小,2的幂次,为0表示没有压缩
24-27 保留
28-2F 属性体占用的字节数
30-37 属性体实际占用的字节数
38-3F 属性体的初始大小
40- 簇流运行信息

属性体

不同属性类型的属性体的结构不同

10属性的属性体

偏移(相对于每个属性体内) 意义
0-7 文件创建时间
8-F 最后修改时间
10-17 MFT修改时间
18-1F 最后访问时间
20-23 文件属性,1:只读,2:隐藏,4:系统,20H:存档,40H:设备,80H:常规,100H:临时,200H:稀疏文件,400H:重解析点,800H:压缩,1000H:脱机,2000H:未编入索引,4000H:加密
24-27 最高版本号
28-2B 版本号
2C-2F 分类ID
30-33 所有者ID
34-37 安全ID
38-3F 磁盘配额
40-47 更新序列号

接着上面例子的红划线处看,首先是属性头(绿线表示)。

偏移0-3(相对于属性内),即图中38-3B处值为10,表示属性类型为记录标准信息的属性
4-7处属性总字节数,刚好为红框框处
8处是0,表示为常驻属性
9处是0,表示没有属性名
A-B是24,表示相对于属性头的属性名的偏移,但是属性名又为0,说明属性头占24B,在属性头后直接为属性体。所以在14-15处可以看到属性体相对属性头的偏移也为24

接着是属性体
偏移20-23处(相对于每个属性体内),即图中偏移70-73处,值为6,表示是系统隐藏文件

30属性的属性体

偏移(相对于每个属性体内) 意义
0-3 父目录的参考号,即MFT对象序列号
4-5 保留
6-7 父目录的更新序列号
8-F 文件创建时间
10-17 文件修改时间
18-1F MFT的修改时间
20-27 文件最后修改时间
28-2F 文件分配大小
30-37 文件实际大小
38-3B 文件属性,1:只读,2:隐藏,4:系统,20H:存档,40H:设备,80H:常规,100H:临时,200H:稀疏文件,400H:重解析点,800H:压缩,1000H:脱机,2000H:未编入索引,4000H:加密
3C-3F 重解析点
40 文件名的长度
41 文件名的命名方式,00:文件名大小写敏感,字符\和空字符不能用,01:字符*/:<>\不能用,最后一个字符不能是.或空格,02:只能是大写字符,长度1-8,.是连接符,最后0-3个字符为扩展名,03:采用01或者02的命名方式
42- unicode编码的文件名

还是接着上面的例子看,10属性下一个是30属性,其属性头是划红线处,30属性也为常驻属性。
然后看属性体
偏移0-3处,即绿色划线处表示父目录的MFT对象索引号为5,而在前面知道索引号为5的元文件为根文件夹
蓝线处为文件分配大小和文件实际大小
偏移38-3B处,即图中阴影E8-EB处为6,表示是系统隐藏文件
偏移40处,即图中阴影F0处为4,表示文件名为4字符长,之后的偏移41处,表示文件命名方式
之后就是unicode编码的文件名了,一个字符由两字节表示,为字符$MFT

80属性的属性体

如果是常驻属性,则属性体为数据内容
如果为非常驻属性,则属性体为簇流运行

继续接着看,30属性后为80属性
偏移8处为1,表示为非常驻属性。
红线处为文件数据起始虚拟簇号(一般为0)和文件数据的结束虚拟簇号(值为20415,起始就是占多少簇)
偏移20-21处,即绿色划线处为簇流的偏移地址,为64,即蓝色划线处为簇流运行
其第一个字节的低四位为2,表示后面两个字节为一组,即C0 4F,表示簇流大小,为几个簇,值为20416(与上面的结束虚拟簇号相对应),扇区为2072+20416*8=165400
其第一个字节的高四位为1,表示再后面一个字节为一组,即03,表示簇流起始簇号,算出扇区正好为2072,也就是这个文件的数据就从这里开始(因为就是$MFT文件)

90属性的属性体

索引根节点

偏移(相对于索引根节点内) 意义
0-3 属性类型
4-7 校对规则
8-B 每个索引缓冲区的字节数
C 每个索引缓冲区的簇数
D-F 保留

索引头

偏移(相对于索引头内) 意义
0-3 第一个索引项的偏移,相对于属性体的偏移
4-7 索引项的字节数
8-B 索引项的分配字节数
C 0:根索引,1:索引分配
D-F 保留

索引项

偏移(相对于索引头内) 意义
0-3 文件的MFT对象序列号
4-5 保留
6-7 更新序列号
8-9 本索引项字节数
A-B 文件名属性体字节数(索引项从10到结尾字节数)
C-D 0:没有子节点,1:有子节点,2:最后一个索引项
E-F 保留
10-13 父目录的MFT序列号
14-15 保留
16-17 父目录的更新序列号
18-1F 文件创建时间
20-27 文件最后修改时间
28-2F MFT最后修改时间
30-37 最后访问时间
38-3F 文件分配大小
40-47 文件实际大小
48-4F 文件属性,1:只读,2:隐藏,4:系统,20H:存档,40H:设备,80H:常规,100H:临时,200H:稀疏文件,400H:重解析点,800H:压缩,1000H:脱机,2000H:未编入索引,4000H:加密
50 文件名长度
51 文件名的命名方式
52- 文件名

接着上面的例子,跳转到根目录对应的MFT对象区域,找到90属性,如图中阴影部分,分析可知其为常驻属性,属性头红色划线标记,属性名绿色划线标记,剩下为属性体

之后,蓝色括号部分为索引根节点,红框处为每个索引缓冲区的字节数,为4096,蓝色划线处为每个索引缓冲区簇数,为1

红色括号处为索引头,偏移4-7,即图中偏移为84-87处值为00 00 00 28,所以该索引项大小为28H(从索引头开始算,到阴影部分结尾)
偏移C处表示该索引项是索引分配,所以应该找后面紧接着的A0属性的属性体

A0属性的属性体

当文件夹中内容很少时,用90属性存,否则使用A0属性,属性使用簇流。
在其索引缓冲区包含一个索引头和多个索引项,索引项与90属性索引项相同

索引头结构

偏移 意义
0-3 标志,为INDX
4-5 更新序列号偏移
6-7 更新序列号与更新数组单位大小
8-9 日志文件序列号
10-17 本索引缓冲区的第几个簇(从0开始,有时候一个簇存放不下)
18-1B 索引项的偏移(相对于18位置)
1C-1F 索引项的大小
20-23 索引项的分配大小
24 0:叶节点,1:还有子节点
25-27 保留
28-29 更新序列号
2A 更新序列号数组

继续接着上面的例子看,数据如下图阴影处所示,红线处为簇流运行,其余部分为非常驻属性体。分析其簇流运行,起始簇号为00 E6 8B 即59019,大小为一个簇,可以找到其索引缓冲区

索引缓冲区如下
红框处为索引头,剩下的为各个索引项,只看第一个索引项,即阴影处
偏移0-3处为04,表示为元文件$AttrDef的MFT对象的索引项
8-9表示本索引项的字节数
10-13表示父目录的MFT序列号,为5,也就是根目录

参考#

https://www.bilibili.com/video/BV1ia411F7av?p=1
https://www.ntfs.com/ntfs_basics.htm
https://blog.csdn.net/enjoy5512/category_6144112.html
基于NTFS文件系统的文件恢复程序的设计与实现 于天佐

posted @   启林O_o  阅读(1224)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)
点击右上角即可分享
微信分享提示
CONTENTS