一、NTFS概述

NTFS (New Technology File System),是 WindowsNT 环境的文件系统。新技术文件系统是Windows NT家族(如常见的Windows XP、Win7 、Win8、Win10)等的限制级专用的文件系统(操作系统所在的盘符的文件系统必须格式化为NTFS的文件系统,4096簇环境下)。NTFS取代了老式的FAT文件系统。

NTFS可以支持的分区(如果采用动态磁盘则称为卷)大小可以达到2TB。而Windows2000中的FAT32支持分区的大小最大为32GB。

当用户将硬盘的一个分区格式化成NTFS分区时,就建立了一个NTFS文件系统结构。NTFS文件系统与FAT文件系统一样,也是用簇为基本单位对磁盘空间和文件存储进行管理的。

NTFS采用了更小的簇,可以更有效率地管理磁盘空间。FAT32文件系统的情况下,分区大小在2GB~8GB时簇的大小为4KB;分区大小在8GB~16GB时簇的大小为8KB;分区大小在16GB~32GB时,簇的大小则达到了16KB。而NTFS文件系统,当分区的大小在2GB以下时,簇的大小都比相应的FAT32簇小; 当分区的大小在2GB以上时(2GB~2TB),簇的大小都为4KB。相比之下,NTFS可以比FAT32更有效地管理磁盘空间,最大限度地避免了磁盘空间的浪费

NTFS分区也被称为NTFS卷,卷上簇的大小,又称为卷因子,其大小是用户在创建NTFS卷时确定的。和FAT文件系统一样,卷因子的大小和文件系统的性能有着非常直接的关系。当一样簇占用的空间太小时,会出现太多的磁盘碎片,这样的空间和文件访问时间上会造成浪费;而相反的当一个簇占用的空间太大时,直接造成了磁盘空间的浪费。因此,最大限度地优化系统对文件的访问速度和最大限度地减少磁盘空间的浪费是确定簇的大小的主要因素。簇的大小一定是扇区大小的整数倍,Win7/8/10系统中通常是8(n为整数),也即簇的大小都为4KB。

NTFS文件系统使用了逻辑簇号(LCN)和虚拟簇号(VCN)对卷进行管理。其中LCN是对卷的第一个簇到最后一个簇进行编号,只要知道LCN号和簇的大小以及NTFS卷在物理磁盘中的起始扇区就可以对簇进行定位,而这些信息在NTFS卷的引导扇区中可以找到,在系统底层也是用这种方法对文件的簇进行定位的。找到簇在磁盘中的物理位置的计算公式是:
每簇扇区数*簇号+卷的隐含扇区数(卷之前的扇区总数)=簇的起始绝对扇区号

而虚拟簇号则是将特定文件的簇从头到尾进行编号,这样做的原因是方便系统对文件中的数据进行引用,VCN并不要求在物理上是连续的,要确定VCN的磁盘上的定位需先将其转换为LCN。

二、NTFS文件系统结构

NTFS最基本的原则:
(1)磁盘上任何对象包括目录都是一种文件,都使用文件记录进行管理。
(2)所有与文件相关的项目,包括数据都被认为是属性。
(3)属性分常驻(在记录中)和非常驻两种,非常驻的大文件夹使用B+树结构进行管理。
(4)簇是NTFS最小的基本单位,一个1字节的文件也要占用一簇的空间。
(5)流是NTFS最基本的存储单元,是文件属性和属性值的集合。

NTFS是以MFT(Master File Table,主文件表或主索引记录)为核心,将整个分区的系统文件和用户文件有机地组织起来的文件系统。

MFT文件和它的备份,位于NTFS分区中部,前后都是数据区,能更好地受到保护。与FAT系统先放文件分配表,后接数据区的做法不同。NTFS分区,大致布局如下图:

DBR

引导区

用户

数据

MFT

用户数据

MFT

部分记录备份

用户

数据

DBR

备份

分区所有的文件,其相关的文件信息都保存在MFT中。

a, 小于1K的小文件(目录),其整个内容都保存在MFT中。

b, 大于1K的大文件(目录),只有它的起始信息保存在MFT中。

分区高级格式化成NTFS文件系统时,首先建立了一个主文件表MFT。

在MFT文件中,会预先建立16个重要的文件(MFT记录的ID编号固定为0-15)和8个保留文件(MFT记录的ID编号固定为16-23),这24个文件是被称为元文件(Metafiles)或元数据(metadata)的系统文件(具体内容见后面),NTFS文件系统将这些数据都当做文件进行管理,这些文件用户是不能访问的,它们的文件名的第一个字符都是“$”,表示该文件是隐藏的。

而用户的文件在MFT中的ID编号从24后开始排,用户每添加一个文件,ID号加1。当某文件被删除时,与之对应的MFT记录将被空出来,如果此时再添加文件,系统会优先填充ID小的空位。MFT尽量保持其物理上的连续性,可将磁盘碎片降至最低。

序号

元文件

功能

0

$MFT

主文件表本身

1

$MFTMirr

主文件表的部分镜像

2

$LogFile

日志文件

3

$Volume

卷文件

4

$AttrDef

属性定义列表

5

$Root

根目录

6

$Bitmap

位图文件

7

$Boot

引导文件

8

$BadClus

坏簇文件

9

$Secure

安全文件

10

$UpCase

大写文件

11

$Extend metadata directory

扩展元数据目录

12

$Extend\$Reparse

重解析点文件

13

$Extend\$UsnJrnl

变更日志文件

14

$Extend\$Quota

配额管理文件

15

$Extend\$ObjId

对象ID文件

16-23

保留

23+

用户文件和目录

$MFT中前16个文件记录总是元文件的记录,并且这16个文件记录的顺序是固定的,下面对这16个记录简单做一个介绍:

第1个记录就是$MFT自身的记录,也就是说$MFT首先对自己进行管理。

第2个记录是$MFTMirr的记录,也就是$MFT前4个文件记录的镜像。

第3个记录是日志文件($LogFile)的记录,该文件是NTFS为实现可恢复性和安全性而设计的。当系统运行时,NTFS就会在日志文件中记录所有影响NTFS卷结构的操作,包括文件的创建和改变目录结构的命令,从而可在系统失败时能够恢复NTFS卷。

第4个记录是卷文件($Volume)的记录,它包含卷名、NTFS的版本和一个标明该磁盘是否损坏的标志位,NTFS文件系统以此决定是否需要调用Chkdsk程序来进行修复。

第5个记录是属性定义表($AttrDe,attribute definition table)的记录,其中存放着卷所支持的所有文件属性,并指出它们是否可以被索引和恢复等。

第6个记录是根目录($ROOT)的记录,其中保存着该卷根目录下的所有文件和目录的索引。在访问一个文件后,NTFS就保留该文件的MFT引用,第二次就能够直接访问该文件。

第7个记录是位图文件($Bitmap)的记录,NTFS卷的簇使用情况都保存在这个位图文件中,其中每一位(bit)代表卷中的一簇,标识该簇的空间还是已分配。由于该文件可以很容易被扩大,所以,NTFS的卷可以很方便地动态扩大,而FAT格式的文件系统由于涉及FAT表的变化,所以不能随意对分区大小进行调整。

第8个记录是引导文件($Boot)的记录,该文件中存放着操作系统的引导程序代码。该文件必须位于特定的磁盘位置才能够正确地引导系统,一般都是位于卷的最前面。

第9个记录是坏簇文件($BadClus)的记录,它记录着该卷中所有损坏的簇号,防止系统对其进行分配使用。

第10个记录是安全文件($Secure)的记录,它存储着整个卷的安全描述符数据库。NTFS文件和目录都有各自的安全描述符,为节省空间,NTFS将文件和目录的相同描述符存放在此公共文件中。

第11个记录为大写文件($UpCase,upper case file)的记录,该文件包含一个大小写字符转换表。

第12~15记录解释见上表,

MFT文件在创建时非常小(大约16KB),其大小是随着磁盘文件的增加而增加。MFT文件默认占用该分区12%(1/8)的空间(MFT区域)。当用户文件空间不足时,系统会把MFT空间分配给用户文件。当有剩余空间时,这些空间又会被重新划分给MFT。

MFT的每一编号对应一个MFT的文件记录(File Record,FR),又称文件记录段 (FRS)。一个MFT文件记录的大小一般为1KB(两扇区)。每一个或多个文件记录对应本分区一个文件。第一个MFT文件记录就是MFT本身。

文件记录由记录头和属性列表组成(见下图):

文件记录头

文件属性列表

属性1

属性头

属性体

属性2

属性头

属性体

属性3

属性头

属性体

结束标志FF FF FF FF

MFT文件记录头:为前部为一个包含几十个字节的具有固定的大小和结构的部分,是每一个MFT记录都有的。起始字节是46 49 4C 45,相应的ASCII码是FILE。

属性列表(list):为MFT记录的主体,长度可变,起始偏移为0x30(相对于记录首字节的偏移),用于存放文件各种属性(大小、位置、时间等)。常见的是标准属性(0x10)、文件名属性(0x30)、数据流属性(0x80)和位图属性(0xB0)等,一个文件记录至少包含0x10和0x30属性。

每一属性又都有属性头(header)和属性体(body)的结构。MFT的结束标志为FF FF FF FF(严格说是上面属性的结束,下一个属性开始)。

$MFT文件首扇(0x0~0x1FF),即MFT自身的记录,属性有0x10 0x30 0x80 0xB0,

以小编电脑的硬盘为例如下:MFT记录表就长下面的这个样子.

MFT记录对照表如下:

◇属性分常驻属性和非常驻属性:

(1)小文件和目录将全部(内容或索引信息)存储在MFT基本的文件记录里,其属性就称为常驻属性(residentattribute)。标准信息、文件名和索引根等属性总是常驻属性。NTFS对常驻属性的访问时间短。

(2)大文件(目录)如果属性值超过1KB时,在基本的文件记录中就用一个指针指向MFT基本文件记录之外的一个外部簇,以此形成B-Tree(B+树)结构。值存储在运行中而不是在MFT文件记录中的属性称为非常驻属性(nonresidentattribute)。

属性头(Header)对照表:

常驻属性的属性头分析表:

非常驻属性的属性头分析表:

0xC-0xD flags:

属性体(Body)对照表:

Data Run:

非常驻属性(nonresidentattribute)的文件(目录)属性值超过1KB,在基本的文件记录中就用一个指针指向MFT基本文件记录之外的一个外部簇,这些外部簇通常称为一个运行(run或Data Run)或一个盘区(extent),它们可用来存储属性(如索引项)或属性值(如文件数据)

Data run的格式如下:

我们再举几个Data run解析的例子:

Data Run Example 1 - Normal, Unfragmented File(正常没有分割的数据)

Data runs:

  • 21 18 34 56 00

  • 21 18 34 56 - 00 (regrouped)

Run 1:

  • Header = 0x21 - 1 byte length, 2 byte offset

  • Length = 0x18 (1 byte)

  • Offset = 0x5634 (2 bytes)

Run 2:

  • Header = 0x00 - the end

Summary:

  • 0x18 Clusters @ LCN 0x5634

所以, Data1是一个没有分割的数据,大小是0x18个簇,逻辑簇号(LCN)是0x5634,


Data Run Example 2 - Normal, Fragmented File(分割的数据)

Data runs:

  • 31 38 73 25 34 32 14 01 E5 11 02 31 42 AA 00 03 00

  • 31 38 73 25 34 - 32 14 01 E5 11 02 - 31 42 AA 00 03 - 00 (regrouped)

Run 1:

  • Header = 0x31 - 1 byte length, 3 byte offset

  • Length = 0x38

  • Offset = 0x342573

Run 2:

  • Header = 0x32 - 2 byte length, 3 byte offset

  • Length = 0x114

  • Offset = 0x363758 (0x211E5 + Run1 0x342573)

Run 3:

  • Header = 0x31 - 1 byte length, 3 byte offset

  • Length = 0x42

  • Offset = 0x393802 (0x300AA + Run2 0x363758)

Run 4:

  • Header = 0x00 - the end

Summary:

  • 0x38 Clusters @ LCN 0x342573

  • 0x114 Clusters @ LCN 0x363758

  • 0x42 Clusters @ LCN 0x393802

所以,Data2是一个分割的数据,大小为0x38+ 0x114+ 0x42 = 0x18E簇,逻辑簇号(LCN)是 0x342573, 0x363758,0x393802.


Data Run Example 3 - Normal, Scrambled File(加密文件)

Data runs:

  • 11 30 60 21 10 00 01 11 20 E0 00

  • 11 30 60 - 21 10 00 01 - 11 20 E0 - 00 (regrouped)

Run 1:

  • Header = 0x11 - 1 byte length, 1 byte offset

  • Length = 0x30

  • Offset = 0x60

Run 2:

  • Header = 0x21 - 1 byte length, 2 byte offset

  • Length = 0x10

  • Offset = 0x160 (0x100 + Run1 0x60)

Run 3:

  • Header = 0x11 - 1 byte length, 1 byte offset

  • Length = 0x20

  • Offset = 0x140 (0xE0= -0x20, + Run2 0x160)

Run 4:

  • Header = 0x00 - the end

Summary:

  • 0x30 Clusters @ LCN 0x60

  • 0x10 Clusters @ LCN 0x160

  • 0x20 Clusters @ LCN 0x140

所以,Data3是一个分割的数据,大小为0x30+ 0x10+ 0x20 = 0x80簇,逻辑簇号(LCN)是 0x60, 0x160,0x140. 其中第三个Data Run具有一个负的offset, 将Data Run3要放在Data Run2之前.


此外,Data run layout必须考虑数据压缩, 如果一个file的VCN是一个compressed fileattribute, 那么将VCN以16 cluster为压缩单元组成一个group, VCN0 ~VCN15组成第一个压缩单元, VCN16~VCN31组成第二个, 以此类推, 对于每一个压缩单元,

(1) 如果一个压缩单元全是0, 那么称之为Sparse unit, 将不占物理存储单元, 只是有一个no offset的field(F=0)和一个长度为16放入runlist当中,

(2) 如果并非全部压缩单元都是0, 那么假设N个不是全0, 剩下的16-N是全0单元, 那么只有N物理存储, 剩下的16-N将会是一个no offset的field(F=0),

(3) 如果unit不是compressed, 那么16个cluster都将都占物理存储, 一个长度为16的单元将放入runlist,

Data Run Example 4 - Sparse, Unfragmented File

Data runs:

  • 11 30 20 01 60 11 10 50 00

  • 11 30 20 - 01 60 - 11 10 30 - 00 (regrouped)

Run 1:

  • Header = 0x11 - 1 byte length, 1 byte offset

  • Length = 0x30

  • Offset = 0x20

Run 2:

  • Header = 0x01 - 1 byte length, 0 byte offset (sparse)

  • Length = 0x60

  • Offset = N/A

Run 3:

  • Header = 0x11 - 1 byte length, 1 byte offset

  • Length = 0x10

  • Offset = 0x30

Run 4:

  • Header = 0x00 - the end

Summary:

  • 0x30 Clusters @ LCN 0x20

  • 0x60 Clusters (sparse)

  • 0x10 Clusters @ LCN 0x50

所以,Data4是一个压缩单元全是0的Sparse文件,大小为0xA0簇, 逻辑簇号为0x20, 0x50.


Data Run Example 5 - Compressed, Unfragmented File(压缩文件)

Data runs:

  • 11 08 40 01 08 11 10 08 11 0C 10 01 04 00

  • 11 08 40 - 01 08 - 11 10 08 - 11 0C 10 - 01 04 - 00 (regrouped)

Run 1:

  • Header = 0x11 - 1 byte length, 1 byte offset

  • Length = 0x08

  • Offset = 0x40

Run 2:

  • Header = 0x01 - 1 byte length, 0 byte offset (sparse)

  • Length = 0x08

  • Offset = N/A

Run 3:

  • Header = 0x11 - 1 byte length, 1 byte offset

  • Length = 0x10

  • Offset = 0x48 (0x8 + 0x40)

Run 4:

  • Header = 0x11 - 1 byte length, 1 byte offset

  • Length = 0x0C

  • Offset = 0x58 (0x10 + 0x48)

Run 5:

  • Header = 0x01 - 1 byte length, 0 byte offset (sparse)

  • Length = 0x04

  • Offset = N/A

Run 6:

  • Header = 0x00 - the end

Summary:

  • 0x08 Clusters @ LCN 0x40

  • 0x08 Clusters (sparse)

  • 0x10 Clusters @ LCN 0x48

  • 0x0C Clusters @ LCN 0x58

  • 0x04 Clusters (sparse)

所以,Data5是一个压缩不连续的文件,文件大小为0x30簇, 逻辑簇号 0x40, 0x48,0x58.

三、NTFS文件系统引导原理

说,电脑启动分几步:

(1) 按下计算机power键以后,开始执行主板bios程序。

(2) 进行完一系列检测和配置以后, 开始按bios中设定的系统引导顺序引导系统。

(3)假定现在是硬盘,Bios执行完自己的程序后把执行权交给硬盘。

(4) 交给硬盘后执行存储硬盘上的系统程序。

NTFS文件系统的引导扇区是$Boot的第一个扇区,它的结构与FAT文件系统的DBR类似,所以习惯上也称该扇区为DBR扇区。

因为文件以引导扇区开始,所以它必须在0物理簇起始(这是NTFS唯一不能移动的簇)。这样就迫使文件的数据属性是非常驻的。从而引导扇区的拷贝可以定位于卷上的任何位置。

$Boot元文件由分区的第一个扇区(DBR)和后面的15个扇区(NTLDR区域)组成,其中DBR由“跳转指令”、“OEM代号”、“BPB(BIOS参数记录块,记录了分区尺寸、$MFT文件位置等)”、“引导程序”和“结束标志”组成,这里和FAT32文件系统的DBR一样。下图是一个NTFS文件系统完整的DBR。

$Boot文件首扇结构(NTFS分区启动扇区。注意:它虽以55AA结束,但它不是分区表):

Offset 大小 描述
0x0000 3 跳到引导载入器程序
0x0003 8 系统标识符:"NTFS    "
0x000B 2 每个扇区的字节数
0x000D 1 每个簇的扇区数
0x000E 7 未用
0x0015 1 媒体描述符(a)
0x0016 2 未用
0x0018 2 每个磁道的扇区数
0x001A 2 磁头数
0x001C 8 未用
0x0024 4 一般是 80 00 80 00 (b)
0x0028 8 卷的扇区数
0x0030 8 LCN of VCN 0 of the $MFT
0x0038 8 LCN of VCN 0 of the $MFTMirr
0x0040 4 每个MFT记录的簇(c)
0x0044 4 每个索引记录的簇(c)
0x0048 8 卷的系列号
~ ~ ~
0x0200 Windows NT 载入器

针对小编手里的硬盘,Winhex解析如下:

如何定位$MFT文件?

根据上表可知,$MFT文件第一簇簇号,在$boot首扇偏移0x30处标明(占用8个字节)。

以上面硬盘DBR扇区图为例,它的第1簇簇号为00 00 0C 00 00 00 00 00,其十六进制数表示为0xC0000H(十六进制数为“低位在前,高位在后”),即第786432簇。NTFS分区的簇大小一般为4K,簇因子(是每簇所包含扇区的数目)为8786432簇×8=6291456扇, $MFT文件首个记录位于本分区第6291456扇区。

利用Winhex的跳转功能Go to Sector, 跳转到6291456扇, 我们就看到了$MFT文件的首个记录。

四、NTFS数据恢复

◇删除的恢复:

当在NTFS卷中删除一个文件时,系统至少在三个地方做了改变:

(1)该文件的MFT记录被删除或被改动。

(2)其父文件夹的90H属性或者A0H属性;

(3)在位图($Bitmap)文件中把该文件所占用的簇对应的位置置0,这样好给其他文件腾出空间。

我们从删除原理着手,分几步将数据进行恢复:

第一步:首先要找到MFT。MFT的第一个文件记录称为基本文件记录(大文件还可能有多个记录),当中存储有其他扩展文件记录的一些信息。

第二步:通过文件记录的INDEX_ROOT索引根、INDEX_ALLOCATION索引分配以及位图Bitmap对被删文件加以确认和定位。找到该文件在数据区中的存储位置。   

第三步:恢复该文件。进行数据恢复时,我们仅仅是将其相关信息复制到了内存,并将相关信息做了修改。为了修复数据而做的修改,其实并没有写回到原文件属性上。这就有效的避免了被访文件的再次破坏。

◇DBR(OBR)或EBR的备份和恢复:

NTFS在其分区最后的扇区上,备份了DBR(OBR)或EBR。

只需将备份扇区的内容复制到分区引导扇区DBR(OBR)或EBR位置,就可使该分区恢复正常。注意:若DBR扇区损坏,可将DBR改在其它柱面。

分区表的分区大小包括此扇,而DBR描述的分区大小不包括此扇。DBR描述文件系统大小时,总是比分区表描述的扇区数小1个扇区。

五、实例:分析NTFS文件系统得到特定文件的内容

找某一个文件的内容,如要读取文件J:\dir\dir2\NTFStest.txt,具体步骤如下:
(1)读取分区表/分区链表信息,找到磁盘J的起始扇区。
(2)读取J盘的第一个扇区(分区的BOOTSETOR)取得分区的每簇大小,MFT表起始簇号等信息。
(3)读取MFT表的第五个记录(根目录)找到目录索引所在簇号。
(4)读取根目录索引,查找dir目录所在的MFT记录号
(5)读取dir目录的MFT记录,找到目录索引所在簇号。
(6)读取dir目录的索引,查找dir2目录所在MFT记录号
(7)读取dir2目录的MFT记录,找到目录索引所在簇号。
(8)读取dir2目录的索引,查找NTFStest.txt 所在MFT记录号
(9)读取NTFStest.txt文件的MFT记录,找到它的DATA属性。
(10)根据DATA属性中指定的文件数据存放位置读取出NTFStest.txt文件的数据。

下面我们具体执行一下:

(1)读取分区表/分区链表信息,找到磁盘J的起始扇区。

因为小编用J盘是一个独立的硬盘,所以J盘的起始扇区为0.

(2)读取J盘的第一个扇区(分区的BOOTSETOR)取得分区的每簇大小,MFT表起始簇号等信息。

绿色部分offset 0xD=0x8, 簇因子(是每簇所包含扇区的数目)为8;

蓝色部分offset 0x30~0x37= 00 00 0C 00 00 00 00 00 = 0xC0000H = 786432,$MFT文件记录起始簇号为第786432簇。

(3)读取MFT表的序号为5的记录(根目录)找到目录索引所在簇号。

由第二步的簇因子以及$MFT记录起始簇号得到,

$MFT文件首个记录位于786432簇×8=6291456扇。

利用Winhex的跳转功能Go to Sector, 跳转到6291456扇, 我们就看到了$MFT文件的首个记录。

(4)读取根目录索引,查找dir目录所在的MFT记录号

MFT 是由一条条 MFT 项(记录)所组成的,而且每项大小是固定的(一般为1KB=0x400),MFT保留了前16项用于特殊文件记录,称为元数据,

元数据在磁盘上是物理连续的,编号为0~15;

我们从上图可以看到$MFT文件的首个记录偏移为0x0C0000000, 那么:

根目录记录(序号5)偏移= 0x0C0000000 + 5*0x400 = 0x0C0001400,

IndexAlloc_header对照表如下:

offset 0x8=0x01, 代表$MFT记录为非常驻属性,

offset 0x9=0x04,Name长度为4,

offset 0x20=0x48, 代表data runs距离属性ID A0的距离为0x48,

所以,data runs所在位置是0x0C00015C8+0x48= 0x0C0001610,

即,data runs= 11 01 2C

  • Header = 0x11 - 1 byte length, 1 byte offset

  • Length = 0x01

  • Offset = 0x2C

所以,偏移簇数0x2C,长度是0x1簇,

跳转到偏移簇数0x2C会看到根目录下的索引项,其中可看到$AttrDef,$BadClus,$Bitmap,$Boot等系统文件的索引项。

找到dir的索引项,如下图,粉色部分是本索引项的名称dir。前8字节是文件的MFT索引记录号(只用到前4个字节,0x23)

Offset Size Description
~ ~ Standard Index Header
0x00 8 MFT Reference of the file
0x08 2 Size of this index entry
0x0A 2 Offset to the filename
0x0C 2 Index Flags
0x0E 2 Padding (align to 8 bytes)
0x10 8 MFT File Reference of the parent
0x18 8 File creation time
0x20 8 Last modification time
0x28 8 Last modification time for FILE record
0x30 8 Last access time
0x38 8 Allocated size of file
0x40 8 Real size of file
0x48 8 File Flags
0x50 1 Length of filename (F)
0x51 1 Filename namespace
0x52 2F Filename
2F+0x52 P Padding (align to 8 bytes)
P+2F+0x52 8 VCN of index buffer with sub-node

(5)读取dir目录的MFT记录,找到目录索引所在簇号。

由上面的图可以得到dir MFT记录号为0x23=35,

之前我们有得到$MFT文件的首个记录偏移为0x0C0000000, 那么:

dir MFT记录(序号35)偏移= 0x0C0000000 + 35*0x400 = 0x0C0008C00,

(6)读取dir目录的索引,查找dir2目录所在MFT记录号

我们跳转到offset 0x0C0008C00,

offset 0xC008D00=0x0, 说明为常驻属性,

从粉色框中得到dir2的MFT记录项的记录号是0x24=36,

(7)读取dir2目录的MFT记录,找到目录索引所在簇号。

第(5)步有得到dir MFT记录(序号35)偏移= 0x0C0000000 + 35*0x400 = 0x0C0008C00, 那么,

dir2 MFT记录(序号36)偏移= 0x0C0008C00 + 0x400 = 0x0C0009000,

(8)读取dir2目录的索引,查找NTFStest.txt 所在MFT记录号

我们跳转到offset 0x0C0009000,

offset 0xC009108=0x0, 说明为常驻属性,

从粉色框中得到dir2的MFT记录项的记录号是0x26=38,

(9)读取NTFStest.txt文件的MFT记录,找到它的DATA属性。

第(7)步有得到dir2 MFT记录(序号36)偏移= 0x0C0008C00 + 0x400 = 0x0C0009000, 那么,

NTFSTest.txt MFT记录(序号38)偏移= 0x0C0009000 + (38-36)*0x400 = 0x0C0009800,

offset 0xC0098A0=0x0, 说明为常驻属性,

从0x30文件名属性可以看到NTFStest.txt的文件名, 0x80数据属性中可以得到文件内容.

(10)根据DATA属性中指定的文件数据存放位置读取出NTFStest.txt文件的数据。

从0X80数据属性中可以知道此属性是常驻属性,直接看到test.txt的文件内容,“This is a NTFS test file!”.

此时,前面的找文件的任务就大功告成啦~~~~

另外,我们延伸一下,如果我继续向NFTStest.txt 写入数据,DATA属性中的数据会增加,如下图粉色区域。

但是当文件内容继续增加超过1K时,0x80数据属性从常驻属性改为非常驻属性,文件内容不会直接存储在此属性中,而是其他簇中,根据Data run可以定位到。

0x80数据属性;0x01说明是非常驻属性;

Data runs = 11 01 25 00;

Run1:

  • Header = 0x11 - 1 byte length, 1 byte offset

  • Length = 0x01

  • Offset = 0x25

Run 2:

  • Header = 0x00 - the end

所以,偏移簇数0x25,长度是0x1簇,

打开簇号0x25,可以看到NTFStest.txt的文件内容:

硬盘文件系统系列专题之二 NTFS相关推荐

  1. 文件系统系列专题之 Btrfs

    一.Btrfs概述 Btrfs(B-tree 文件系统,通常念成 Butter FS,Better FS或B-tree FS),一种支持写入时复制(COW)的文件系统,运行在 Linux 操作系统上. ...

  2. Microsoft .Net Remoting系列专题之二:Marshal、Disconnect与生命周期以及跟踪服务

    Microsoft .Net Remoting系列专题之二 一.远程对象的激活 在Remoting中有三种激活方式,一般的实现是通过RemotingServices类的静态方法来完成.工作过程事实上是 ...

  3. Microsoft .Net Remoting系列专题之二

    Microsoft .Net Remoting系列专题之二 一.远程对象的激活 在Remoting中有三种激活方式,一般的实现是通过RemotingServices类的静态方法来完成.工作过程事实上是 ...

  4. NVMe系列专题之二:队列(Queue)管理

    转载链接:https://mp.weixin.qq.com/s?__biz=MzIwNTUxNDgwNg==&mid=2247484355&idx=1&sn=04f0617bf ...

  5. [C# 网络编程系列]专题十二:实现一个简单的FTP服务器

    引言: 休息一个国庆节后好久没有更新文章了,主要是刚开始休息完心态还没有调整过来的, 现在差不多进入状态了, 所以继续和大家分享下网络编程的知识,在本专题中将和大家分享如何自己实现一个简单的FTP服务 ...

  6. [C#基础知识系列]专题十二:迭代器

    引言: 在C# 1.0中我们经常使用foreach来遍历一个集合中的元素,然而一个类型要能够使用foreach关键字来对其进行遍历必须实现IEnumerable或IEnumerable<T> ...

  7. TensorFlow系列专题(二):机器学习基础

    欢迎大家关注我们的网站和系列教程:http://www.tensorflownews.com/ ,学习更多的机器学习.深度学习的知识! 目录: 数据预处理 归一化 标准化 离散化 二值化 哑编码 特征 ...

  8. PCIe系列专题之二:2.5 Flow Control缓存架构及信用积分

    一.故事前传 之前我们讲了对PCIe的一些基础概念作了一个宏观的介绍,了解了PCIe是一种封装分层协议(packet-based layered protocol),主要包括事务层(Transacti ...

  9. PCIe系列专题之二:2.8 事务排序机制

    一.故事前传 之前我们讲了对PCIe的一些基础概念作了一个宏观的介绍,了解了PCIe是一种封装分层协议(packet-based layered protocol),主要包括事务层(Transacti ...

  10. PCIe系列专题之二:2.3 TLP结构解析

    一.故事前传 之前我们讲了对PCIe的一些基础概念作了一个宏观的介绍,了解了PCIe是一种封装分层协议(packet-based layered protocol),主要包括事务层(Transacti ...

最新文章

  1. 1048 Find Coins(散列解法)
  2. C#语言中的可访问性约束
  3. 各种页面刷新代码大全,asp/javascript刷新页面代码
  4. python 如何将字符串列表合并后转换成字符串? ''.join(List(str))函数
  5. 1.关于python
  6. hp服务器raid一直显示同步,HP Netserver NetRAID 一致性检查常见问题解答(FAQ)
  7. 解决xib自定义tableFooterView一个神奇的bug
  8. 解决vue视图不渲染
  9. 牛客小白月赛13 解题报告
  10. Repository 仓储,你的归宿究竟在哪?(三)-SELECT 某某某。。。
  11. SIR模型的应用(2) - Influence maximization in social networks based on TOPSIS(3)
  12. matlab对函数时间抽样,信号与系统实验报告4 matlab时间抽样
  13. 二阶魔方还原 C++ BFS
  14. 麦子学院视频教程笔记
  15. c++中数字与字符,字符与其ASCII转换
  16. CTB6.0标注体系
  17. 职业发展,选择大都市还是回老家?
  18. PE结构-空白区手动添加任意代码(附实例代码)
  19. GIS小白教程:如何利用高程DEM数据构建三维地图模型(基于ArcScene)
  20. 多米诺骨牌问题Push Dominoes

热门文章

  1. linux安装CUPS详细教程,ubuntu安装打印机CUPS
  2. crypto405-grasshopper(网鼎杯2022)
  3. packet captuer tool: snoop
  4. NodeJS--NVM出现exit status 1解决方法
  5. H3C S5820V2_5830V2交换机IRF2堆叠后升级方法
  6. 百度2023校招 内推码IVV4AS
  7. 移动光猫路由改桥接降低延时初尝试
  8. 美团构建实时数仓的痛点是什么?如何解决?
  9. python 金融发欺诈_python金融反欺诈-项目实战
  10. Pandas数据分析(十年期国债收益率 与 十年期国债期货价格的相关性)