自学内容网 自学内容网

基于元神操作系统实现NTFS文件操作(五)

1. 背景

本文主要介绍$Root元文件的解析。先介绍元文件的构成及各个部分的结构,然后结合上一篇博文中读取到的元文件内容,对测试磁盘中目标分区的根目录进行展示。

2. $Root元文件解析

(1)$Root元文件的结构

$Root元文件由两部分构成,即文件头和属性列表,最后以4个FF结尾。$Root元文件占用2个扇区,即1KB(1024字节),但并非所有这1024字节都存放着有效内容,4个FF之后的部分就是无效的数据,可以直接忽略。上文所读取的$Root元文件结构如下图所示:

需要注意的是,每个扇区的最后两个字节都具有特殊用途,存放的都是更新序列号,与文件头部分的更新序列号相同。

对于前16个$MFT元文件,它们都拥有和$Root一样的构成。其中,文件头的长度和结构是不变的,但是属性列表是可变的,例如,0号元文件包含10H、30H、80H、B0H属性,1号元文件包含10H、30H、80H属性,2号元文件包含10H、30H、80H属性,3号元文件包含10H、30H、50H、60H、70H、80H属性,4号元文件包含10H、30H、50H、80H属性,5号元文件包含10H、30H、40H、50H、90H、A0H、B0H属性,6号元文件包含10H、30H、80H属性,7号元文件包含10H、30H、50H、80H属性,8号元文件包含10H、30H、80H属性。

(2)$Root元文件的文件头

文件头的前4个字节(即偏移0x00-0x03处的字节)为固定值,是“FILE”这4个字符的ASCII码;偏移0x04-0x05表示更新序列号的偏移;偏移0x06-0x07表示更新序列号的数目;偏移0x08-0x0F表示日志文件序列号;偏移0x10-0x11表示序列号,用于记录本文件被重复使用的次数;偏移0x12-0x13表示硬链接数;偏移0x14-0x15表示第一个属性的偏移地址;偏移0x16-0x17为标志字节,值为0时表示本文件为已删除的文件,值为1时表示本文件为正常文件,值为2时表示本文件为已删除的目录,值为3时表示本文件为正常目录;偏移0x18-0x1B表示文件的实际大小,以字节为单位;偏移0x1C-0x1F表示文件的分配大小(即在磁盘中占用的空间大小),以字节为单位;偏移0x20-0x27表示文件参考号;偏移0x28-0x29表示下一个自由ID号;偏移0x2A-0x2B表示边界值;偏移0x2C-0x2F表示本MFT的记录号;偏移0x30-0x31表示更新序列号;偏移0x32开始为更新序列数组。

其中,用于判断元文件有效性的包括:偏移0x00-0x03处固定为46 49 4C 45(即“FILE”的ASCII码),若读出的数据与此不同,说明读取的不是有效的$Root元文件;偏移0x30-0x31处为更新序列号,该元文件两个扇区的最后两个字节的值也为更新序列号,若这3处的值不相同,说明读取到的不是有效的$Root元文件。

与文件操作有关的内容包括:偏移0x14-0x15处为第一个属性的偏移地址,根据该值可以定位和解析当前元文件的第一个属性;偏移0x16-0x17处的标志字节可用于辅助操作,例如,查找文件、读文件时只需操作正常文件(即只需操作标志字节为1的文件),递归操作子目录时只需考虑正常目录(即只需考虑标志字节为3的文件),新建文件时只需考虑标记为已删除的文件(即只需考虑标志字节为0或2的文件),依此类推;偏移0x18-0x1B处为文件的实际大小,该值在读取文件内容时会用到。

结合下图中读取到的$Root元文件的文件头内容,偏移0x00-0x03处为固定值“FILE”;偏移0x04-0x05处为30 00(即0x0030),表示更新序列号在偏移0x0030处,定位到0x0030处可发现其值为66 04,同样的每个扇区的最后两个字节也为66 04,说明读取的元文件是有效的;偏移0x06-0x07处的值为03 00(即0x0003),表示有3个更新序列号,分别位于文件头和每个扇区的结尾;偏移0x14-0x15处为38 00(即0x0038),表示偏移0x38处开始第一个属性,即开始10H属性;偏移0x16-0x17处为03 00(即0x0003),表示当前文件为正常目录(即分区的根目录);偏移0x18-0x1B处为98 02 00 00(即0x00000298),表示当前文件的实际大小为0x298字节,即664字节;偏移0x1C-0x1F处为00 04 00 00(即0x00000400),表示当前文件分配的大小为0x400字节,即1024字节(1KB),对比实际大小可见,分配的大小大于或等于实际大小,而多出来的空间是浪费掉的磁盘空间,此处需要注意的是:对于正常的文件,分配的大小是以簇为单位的,假设每簇扇区数为8,则分配的大小是以8*512=4KB为单位的,即最小分配4KB,即便实际大小只有1个字节,也要分配4KB的磁盘空间;而$Root元文件中的此处分配值为1KB,是因为存放的是元文件(即$Root文件),该元文件固定占2个扇区,不是以簇为单位的。

(3)$Root元文件的属性

$Root元文件的属性列表中包含7个属性,分别为10H、30H、40H、50H、90H、A0H、B0H属性。10H属性包含文件的创建、修改、最近访问时间及兼容DOS的文件属性;30H属性存放文件名或目录名;40H属性为对象标识符;50H属性存放安全相关信息;90H属性存放B+树的根节点,可用于实现索引,如目录等;A0H属性用于存放B+树的所有子节点;B0H属性存放位映射,每一位表示一个簇的使用状态,值为1时表示对应的簇已经使用,值为0时表示对应的簇空闲(即尚未使用)。其中,30H属性、90H属性、A0H属性在文件遍历、文件搜索等相关操作中比较常用,B0H则在文件删除等磁盘空间相关的操作中会用到。

每个属性都由一个属性头和属性体构成。每个属性从开始位置起的若干字节为属性头,属性头分为常驻属性头和非常驻属性头。属性头的偏移0x00-0x03表示属性类型,即10、30、40、50、90、A0、B0等值;偏移0x04-0x07表示属性的长度;偏移0x08处为常驻标志,值为00时表示当前属性为常驻属性,值为01时表示当前属性为非常驻属性;偏移0x09处为属性名的长度;偏移0x0A-0x0B表示属性名开始的偏移;偏移0x0C-0x0D处为文件压缩标志;偏移0x0E-0x0F表示属性ID。

根据偏移0x08处的值,属性分为常驻属性和非常驻属性。对于常驻属性的属性头,偏移0x10-0x13表示属性数据的长度;偏移0x14-0x15表示属性体开始的位置;偏移0x16处为索引标志;偏移0x18开始为属性体。

对于非常驻属性的属性头,偏移0x10-0x17表示起始虚拟簇号;偏移0x18-0x1F表示结束虚拟簇号;偏移0x20-0x21表示Data RUN的偏移地址;偏移0x22-0x23处为压缩单位;偏移0x28-0x2F表示属性分配的大小;偏移0x30-0x37表示属性的实际大小;偏移0x38-0x3F表示属性的初始大小;偏移0x40开始为Data RUN信息。

每种属性的属性体都具有不同的结构,$Root元文件属性的解析涉及到的内容较多,限于篇幅,将在下一篇博文中进行介绍。

3. 总结

本文介绍了$Root元文件的结构及文件头的结构,并结合读取到的数据进行了解析,最后介绍了属性及属性头的结构,下文将结合读取的内容对$Root元文件的属性进行解析。

安装元神操作系统的工具“元神操作系统安装器”可去网站www.gnxxkj.com进行下载。安装账号可去网址http://www.gnxxkj.com/app/wuziqi/register.php 进行注册。 


原文地址:https://blog.csdn.net/wangdechang119/article/details/142695877

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!