第3章 NTFS文件系统
由于NTFS文件系统具有许多优点,在服务器领域得到了广泛应用。自从微软公司陆续推出WINDOWS 2000和WINDOWS XP以来,NTFS文件系统在个人PC机上也得到了迅速普及。本章针对NTFS文件系统的主要特性,结合作者编写的WIN32工具程序,对使用NTFS文件系统的逻辑盘进行实际操作。通过可视化的程序界面,使用通俗的、非专业性的语言进行讲述,力求使一般读者了解NTFS文件系统的概况。
在笔者所查阅的书籍和资料当中,对NTFS文件系统介绍得最详细的、极具权威性的书籍,当属某出版社翻译出版的《Windows 2000内部揭密》一书,该书是由两位美国作者编写的。据该书在序言中的介绍,作者曾参加微软公司操作系统的研发与调试,并写了很多测试软件,其权威性是不容置疑的。
不过仔细阅读了该书以后,却感觉有一点不足。书中介绍NTFS文件系统的内容,在全书占了最大的比重,但只限于颂扬NTFS文件系统的优越性能,并没有揭示其在磁盘上的扇区存储规律。而NTFS文件系统的优越性能,凡是使用过的人一般都能观察或体会到,唯有其扇区存储规律,是文件系统的使用者不可能了解的。
根据该书作者的权威身份来推测,他们对NTFS文件系统的扇区存储规律,肯定是非常了解的。那么在书中为什么没有披露这方面的内容呢?笔者估计可能是受到某些技术保密协议的约束,这一类内容不便于公开。
到目前为止,在有关NTFS文件系统扇区存储方面,还没有发现比较系统全面的介绍资料。在互联网上找到的一些内容,也都是使用者在具体操作中的一些实践经验,而不是NTFS文件系统的设计者发表的官方资料。
NTFS文件系统的设计者为什么不公开其扇区存储规律呢?这主要是从安全方面考虑的。因为公开了这些存储规律,文件系统的许多保护机制就都能用修改硬盘物理扇区数据的方法进行修改,文件系统的安全保护功能就被削弱了。
不过,操作者如果能够了解文件系统的扇区存储规律,就能在系统维护、数据恢复、开拓应用范围等方面,学到很多不可替代的方法和技巧。
为了探索NTFS文件系统的扇区存储规律,作者编写了21个WIN32工具程序。这些工具程序能够对扇区数据进行多种形式的读写与监测,从而可以探索NTFS文件系统的扇区存储规律,进一步拓展其优越性能的应用范围。并且可以在恢复数据方面,解决很多现有软件无法解决的问题。
在本章介绍的NTFS文件系统的众多性能中,很多是与后面的《探秘篇》有关联的内容,其中大部分都能使用《工具篇》中提供的工具程序,在磁盘的扇区存储中,找到它们最底层的存储规律。
3.1 NTFS的磁盘管理功能
NTFS文件系统使用64位簇进行索引,这使它具有很强的磁盘管理功能,它对硬盘扇区的寻址能力达到160亿GB。虽然NTFS能管理如此大容量的硬盘,但它在存储文件时却非常节省空间,因为每个簇只占用很少的磁盘扇区。
凡是了解FAT16文件系统的人都知道,其对磁盘空间的浪费是非常大的。在一个2GB的逻辑驱动器上,每个簇就占用64个扇区。而文件在磁盘上是以簇为单位存储的,占用的最后一个簇即使只存储了1字节,簇中的剩余空间也不能再存储其他数据了。
FAT32文件系统与FAT16文件系统相比,在磁盘空间的浪费方面,已经有了很大的改进。而NTFS文件系统相比较FAT32文件系统,又有了一定程度的改善,它甚至可以设定每个簇只占用1个扇区。
表3-1列出了NTFS文件系统默认簇的大小。
表3-1 NTFS文件系统默认簇的大小
3.2 NTFS的Unicode编码格式
NTFS文件系统使用16位的Unicode字符编码格式,用于存储目录和文件名。在原来传统的字符编码标准中,存储目录和文件名时,有的字符使用8位,如ASCII字符;有的字符使用16位,如汉字字符。这种不统一的编码方式,使数据在不同编码的国家和地区间的转移变得较为困难。
而Unicode字符编码格式是国际字符标准,它为大多数已知字符集定义了唯一的16位值表示方法,这就增强了其在世界范围内的通用性。
本书在《工具篇》中,将要介绍一些查找扇区特征的工具程序,其中就有查找文件名的程序功能。要查找文件名时,操作者必须要了解Unicode字符编码格式的存储规律,才能对找到的扇区数据进行正确的判断。
为了让读者有一个直观的认识,现在使用“查看硬盘扇区数据.EXE”程序,将存储文件名的一个扇区数据显示在对话框中。文件名是“SymantecNorton.TXT”,这是硬盘维护软件NORTON 8.0的说明文件,是一个文本文件。该文件存储在作者使用的1号硬盘的F逻辑驱动器上,在第2章的2.2节中曾经介绍过,F逻辑驱动器使用了NTFS文件系统。
程序的运行结果如图3-1所示。
图3-1
在图3-1所示的对话框中,显示了存储“SymantecNorton.TXT”文件名的扇区数据。在主窗口的编辑框中,可以看出该扇区号是12579068,至于这个扇区号是怎么得到的,在后面的有关章节中再作介绍。
将对话框中的数据与ASCII码表中的十六进制值对照一下,可以发现从字节编号355开始,存储的是“SymantecNorton.TXT”文件名。不过每个ASCII码后面都空1字节,这是因为ASCII码是用8位表示,而NTFS文件系统统一使用16位的Unicode字符编码格式,多余的8位就空出来了。同时还能发现,存储文件名时是区分大小写的。如果文件名使用的是汉字,则每个汉字的Unicode编码要占用2字节。
在对话框的数据中,还能发现NTFS文件系统在存储文件名时的另一个规律。从字节编号235开始的24字节中,十六进制值对应的ASCII码是“SYMANT~1.TXT”。每个ASCII码后面也都空了1字节,而且全部字符都是大写。
现在将NTFS文件系统在存储文件名时的规律全面讲述一下。
(1)NTFS允许路径中的每个文件名字符长达255个,并且文件名中可以包含多个“.”字符和嵌入空格。
(2)NTFS文件系统既支持长文件名,也支持MS-DOS的8.3格式的文件名。在存储8.3格式的文件名时,ASCII字符使用大写。
(3)当在NTFS文件系统里建立一个长文件名时,系统自动生成一个MS-DOS的8.3格式文件名,生成文件名时遵循下述算法。
从长文件名中删除MS-DOS认为的不合法的字符,包括空格和Unicode字符。对文件名中的“.”字符,只保留最后一个,其他的全部删除。
将“.”前的字符串截短为6个字符,然后添加字符串“~n”。n是从1开始的编号,用来区别截断后的相同名字的不同文件。将“.”后的字符串截短为3个字符。
字符用大写字母表示。
如果生成的文件名与当前目录下已存在的文件名相同,“~n”串中的n增加1。
为了让读者更直观地看到文件名的存储格式,可以在WINDOWS 2000的“命令提示符”窗口,运行16位程序 READSF.EXE,将存储文件名的扇区数据以字符方式显示出来。程序的运行界面如图3-2所示。
图3-2
在图3-2中,可以很清楚地观察到长文件名与生成的8.3格式的文件名的存储情况。
3.3 NTFS的扇区分配
NTFS文件系统在对逻辑盘的扇区分配上,与FAT文件系统有些地方是相同的。在逻辑盘的最前面,也有63个系统隐藏的扇区,这63个扇区是不计算在逻辑簇号里面的。在这63个扇区中,最前面的第1个扇区,记录着主分区表或分区链表的数据。其余的62个扇区,系统没有使用。
在63个系统隐藏扇区之后,是分区引导记录所在的扇区,逻辑簇号就是从这个扇区开始的。
除了上面所讲的两部分以外,其余的扇区分配与FAT文件系统就完全不一样了。NTFS文件系统取消了文件分配表和文件目录登记项的设置,所有的系统数据都作为文件存储在磁盘上。就连系统启动时所用的引导文件,也与普通文件一样存储在磁盘上,这就是所谓的“磁盘上的任何事物都为文件”的存储模式。
尽管NTFS将任何事物都作为文件来对待,但对有些系统数据还是设置了固定不变的存储地址。除了将分区引导记录固定在第1个逻辑簇号以外,还在NTFS逻辑盘的磁盘中部,保存了若干个系统使用的MFT元数据文件(一般保存4个元数据文件的拷贝)。这些元数据文件称作MFT镜像,文件名是“$MFTMirr”。另外,系统还将分区引导记录的扇区数据,在逻辑盘的最后1个扇区上作了备份。
在扇区分配上的这些设置,使NTFS文件系统在处理文件和数据时,在高效和安全两个方面的性能,都比FAT文件系统优越得多。
NTFS文件系统在检索文件及读取文件数据时,速度要比FAT文件系统快。原因在于FAT文件系统在执行上述操作时,要反复读取FAT表中的簇链。而NTFS取消了FAT表,所以其检索及读取文件的速度就提高了。
NTFS文件系统由于备份了一部分系统元数据文件,所以当因为某种原因,MFT元文件的数据不能被读入时,这些拷贝可以被用来定位元数据文件。
当分区引导记录被破坏了的时候,分区就不能正常引导。这时操作者可以使用NTFS逻辑盘中的最后一个扇区数据,修复不正常的分区引导记录。
在当前普遍使用的主流文件系统中,NTFS 在效率和安全性等方面是比较优秀的。所以除了在服务器应用上占据了统治地位以外,近年来在个人PC机上也得到了广泛地应用。
3.4 NTFS的系统引导特性
操作系统在引导NTFS逻辑盘时,必须读取引导记录扇区中的有关数据。在NTFS的分区引导记录中,也有一个类似于FAT文件系统的BPB表,记录了逻辑盘的各种信息。
如果一个NTFS逻辑盘的分区引导记录被破坏,而分区表的数据仍然正常时,系统仍然能正常显示出逻辑盘的盘符,但会提示该逻辑盘没有格式化。如果这个逻辑盘中没有重要数据,可以按照系统提示进行格式化。如果盘中存储着重要数据,可以设法修复分区引导记录中被破坏的数据,则整个逻辑盘中的数据就能够正常读取了。
NTFS的分区引导记录占用了许多个扇区,而每个扇区都包含512字节,到底修复哪些字节的数据,才能使逻辑盘趋于正常呢?作者使用书中提供的工具程序,对6个NTFS逻辑盘的分区引导记录进行了对比分析,从中找出了一些对修复数据有用的规律。
这6个NTFS逻辑盘分布在4个硬盘上,它们的大小都不相同,从1GB到80GB不等。格式化时在需要设置的选项中,有一项是“分配单元大小”选项。为了使分析对比的结果具有普遍的意义,作者特意将6个NTFS逻辑盘的分配单元设置成不同的值,分别是512字节、1024字节、2048字节和4096字节。
对比分析的过程分以下两个步骤进行。
(1)在4个硬盘上分别运行工具程序“备份系统扇区数据.EXE”,得到NTFS逻辑盘的分区引导记录扇区号。然后使用工具程序“读硬盘扇区数据.EXE”,将6个NTFS逻辑盘的分区引导记录扇区数据,备份到文件中加以保存。使用每个逻辑盘的卷标给这些文件命名,生成的6个备份文件分别命名为40f、62d、62e、62f、80g和120f。文件名中的数字部分表示硬盘的容量,字符部分表示逻辑盘的盘符。
现在使用工具程序“查看扇区文件数据.EXE”,将其中的2个文件数据显示出来,使读者有一个直观的认识。
文件40f的数据显示结果如图3-3所示。
图3-3
文件80g的数据显示结果如图3-4所示。
图3-4
(2)运行“文件字节比较.EXE”程序,将6个文件中的每2个进行比较,总共比较15次。每次比较以后程序都会建立一个文件,将不相同的字节值的编号,在文件中进行列表统计。这里的字节编号是将扇区中的512字节,从1到512进行的编号,它与字节位移的概念不一样,字节位移是从00H开始的。在统计结果中,不相同字节数最多的是21个,最少的是14个。下面分别将最多的和最少的各选取一例,从中看一下引导扇区的数据存储规律。
不相同字节数最多的程序运行结果,如图3-5所示。
图3-5
由于内容较长,为方便查看,可以将程序建立的备份文件打开,文件中的内容显示如下。
G:\boot2\40f 与G:\boot2\80g 14 41 42 43 44 49 51 57 58 59 60 65 69 73 74 75 76 77 78 79 80 Ok!
不相同的字节总数是:21
不相同字节数最少的程序运行结果,如图3-6所示。
图3-6
在进行的15次比较中,其他的比较结果基本与上面显示的结果一样,只是不相同的字节数介于14与21中间。从比较中可以看出,不相同的字节都在前80字节内,这就为修复被破坏的分区引导记录,提供了依据和可行的方法。
当遇到分区引导记录不正常的情况时,可以从其他正常的NTFS逻辑盘中,将分区引导记录的数据备份到文件中。然后根据故障盘的实际情况,手工编制其中的一部分字节数据,然后写入到故障盘中,就可以使故障盘正常读取了。
特别需要注意的是,在文件40f与62f的比较中,只有14个不相同的字节值。从比较结果中可以很明显地看出,不相同的字节值属于3个字段的内容。41号到43号字节属于一个字段,这个字段记录的是逻辑盘的扇区数,整个字段占用8字节,高位的字节都是0,所以没有列出来。57号到59号字节属于第2个字段,这个字段记录的是MFT镜像文件的逻辑簇号,也是占用8字节。73号到80号扇区属于第3个字段,占用8字节,记录的是NTFS逻辑盘的序列号。
作者在实际操作中,发现NTFS逻辑盘的分区引导记录占用了7个扇区。其余6个扇区的数据被破坏时,并不会影响NTFS逻辑盘的引导,但可能发生其他的系统加载错误。有的资料中将这些扇区中的数据,称为WINDOWS NT载入程序。不过其余6个扇区的数据,在作者进行试验的所有NTFS逻辑盘中都是相同的,如果需要的话,只要将其他逻辑盘的扇区数据移植过来即可正常使用。
在实际修复NTFS逻辑盘的过程中,因为逻辑盘中的最后一个扇区备份了分区引导记录的数据,所以也可以将其移植过来,以达到修复系统数据的目的,前提是如果最后一个扇区还正常的话。
3.5 NTFS的文件表结构
在使用NTFS文件系统的逻辑盘上,不管是系统的还是用户的数据,都以文件的形式存储在磁盘上。这种存储方式,与FAT文件系统是完全不相同的,FAT文件系统只把用户的数据以文件的形式存储在磁盘上。虽然有些系统数据,NTFS 给它们设定了固定的存储地址,譬如分区引导记录、MFT镜像文件和分区引导记录的第1个扇区的备份,但这些系统数据的定位与加载,也都是以文件的形式进行的。
这种“磁盘上的任何事物都为文件”的存储方式,是NTFS文件系统具有高效与安全特性的基本保证。系统在对文件进行定位与加载时,不必象FAT文件系统那样反复地检索文件分配表,所以运行时的速度提高了。在所有的数据都为文件的前提下,NTFS文件系统设置了很多保护文件安全的措施,极大地提高了文件系统的安全性。
为了实现对文件快速定位,以及保证系统安全与数据维护的需要,NTFS使用MFT文件表结构来记录所有文件的属性。MFT文件表有两类,一类是系统文件使用的,另一类是用户文件使用的。在NTFS逻辑盘中,不管在格式化时将簇的大小设置为多少,每个文件表记录的大小都被固定在1024字节,也就是占用2个扇区。MFT本身也被作为文件来对待,它也有一个文件表记录。
系统使用的MFT文件表记录,称为元数据文件集。MFT的前16项是为元数据保留的,按文件序号标记为File0到File15,文件名的前面都以“$”开始标记。
用户文件和目录的MFT文件表记录从第25项记录开始,文件序号是File24及其后的文件。一般情况下,每个MFT记录对应着一个不同的用户文件。但有时一个文件的属性太多,在一个MFT记录里容纳不下的话,就需要一个以上的MFT记录。如果出现这种情况,则MFT的第一个记录中,就存储了其他MFT记录的地址。
作者经过对大量文件的操作与实验发现,一个文件使用一个以上MFT记录的情况较少出现。最有可能出现这种情况的原因是,一个比较大的文件,经过多次修改与存储,而且时间跨度比较长,在这期间磁盘上有大量文件被拷入或被删除。由于文件数据不连续存储的区域很多,文件属性超出了一个MFT记录的容量,必须使用新的MFT记录、存储文件的属性。
但并不是具有这种特征的文件,就一定拥有一个以上的MFT记录。当文件在修改的过程中,只要进行一次转存,则原来不连续存储的数据就会变得连续起来,文件的属性记录也就减少了。这也是NTFS文件系统的优越性能之一,因为它总是试图选择一块连续的磁盘空间,将文件数据连续存放。
在绝大多数文件的MFT记录中,如果文件名不是太长,一般只占用MFT记录中的第1个扇区,第2个扇区则空闲不用,只在记录文件引用数的字段上写有数据。
在WINDOWS 2000的调试工具中,有一个能显示NTFS逻辑盘中的MFT记录的程序,程序名为nfi.exe。这是一个字符界面的程序,可以在WINDOWS 2000的“命令提示符”窗口中运行。作者计算机中的1号硬盘是本书所有演示操作的主要对象。在命令行输入
“nfi f:”,然后回车,就能够在窗口中显示逻辑盘F的所有MFT记录。因为记录很长,所以屏幕是向上滚动的,只能看到最后一屏的内容。
如果想观察MFT记录的全部内容,可以使用DOS操作系统中的重定向命令符“>”。在命令行输入“nfi f:>f-mft.txt”,然后回车,程序会将F盘的所有MFT记录,写入文本文件f-mft.txt中加以保存。用文本编辑软件打开该文件,其内容显示如下。
NTFS File Sector Information Utility. Copyright(C)Microsoft Corporation 1999. All rights reserved. File 0 Master File Table($Mft) $STANDARD_INFORMATION(resident) $FILE_NAME(resident) $DATA(nonresident) logical sectors 32-127(0x20-0x7f) $BITMAP(nonresident) logical sectors 16-17(0x10-0x11) File 1 Master File Table Mirror($MftMirr) $STANDARD_INFORMATION(resident) $FILE_NAME(resident) $DATA(nonresident) logical sectors 2096450-2096457(0x1ffd42-0x1ffd49) File 2 Log File($LogFile) $STANDARD_INFORMATION(resident) $FILE_NAME(resident) $DATA(nonresident) logical sectors 2096458-2121545(0x1ffd4a-0x205f49) File 3 DASD($Volume) $STANDARD_INFORMATION(resident) $FILE_NAME(resident) $OBJECT_ID(resident) $SECURITY_DESCRIPTOR(resident) $VOLUME_NAME(resident) $VOLUME_INFORMATION(resident) $DATA(resident) File 4 Attribute Definition Table($AttrDef) $STANDARD_INFORMATION(resident) $FILE_NAME(resident) $SECURITY_DESCRIPTOR(resident) $DATA(nonresident) logical sectors 18-23(0x12-0x17) File 5 Root Directory $STANDARD_INFORMATION(resident) $FILE_NAME(resident) $INDEX_ROOT $I30(resident) $INDEX_ALLOCATION $I30(nonresident) logical sectors 2121618-2121625(0x205f92-0x205f99) $BITMAP $I30(resident) File 6 Volume Bitmap($BitMap) $STANDARD_INFORMATION(resident) $FILE_NAME(resident) $DATA(nonresident) logical sectors 2121626-2122137(0x205f9a-0x206199) File 7 Boot Sectors($Boot) $STANDARD_INFORMATION(resident) $FILE_NAME(resident) $SECURITY_DESCRIPTOR(resident) $DATA(nonresident) logical sectors 0-15(0x0-0xf) File 8 Bad Cluster List($BadClus) $STANDARD_INFORMATION(resident) $FILE_NAME(resident) $DATA(resident) $DATA $Bad(nonresident) File 9 Security($Secure) $STANDARD_INFORMATION(resident) $FILE_NAME(resident) $DATA $SDS(nonresident) logical sectors 2122394-2122907(0x20629a-0x20649b) logical sectors 2121546-2121547(0x205f4a-0x205f4b) logical sectors 2121616-2121617(0x205f90-0x205f91) $INDEX_ROOT $SDH(resident) $INDEX_ROOT $SII(resident) $INDEX_ALLOCATION $SDH(nonresident) logical sectors 2121606-2121613(0x205f86-0x205f8d) $INDEX_ALLOCATION $SII(nonresident) logical sectors 24-31(0x18-0x1f) $BITMAP $SDH(resident) $BITMAP $SII(resident) File 10 Upcase Table($UpCase) $STANDARD_INFORMATION(resident) $FILE_NAME(resident) $DATA(nonresident) logical sectors 2122138-2122393(0x20619a-0x206299) File 11 Extend Table($Extend) $STANDARD_INFORMATION(resident) $FILE_NAME(resident) $INDEX_ROOT $I30(resident) File 12 (unknown/unnamed) $STANDARD_INFORMATION(resident) $SECURITY_DESCRIPTOR(resident) $DATA(resident) File 13 (unknown/unnamed) $STANDARD_INFORMATION(resident) $SECURITY_DESCRIPTOR(resident) $DATA(resident) File 14 (unknown/unnamed) $STANDARD_INFORMATION(resident) $SECURITY_DESCRIPTOR(resident) $DATA(resident) File 15 (unknown/unnamed) $STANDARD_INFORMATION(resident) $SECURITY_DESCRIPTOR(resident) $DATA(resident) File 24 \$Extend\$Quota $STANDARD_INFORMATION(resident) $FILE_NAME(resident) $INDEX_ROOT $O(resident) $INDEX_ROOT $Q(resident) File 25 \$Extend\$ObjId $STANDARD_INFORMATION(resident) $FILE_NAME(resident) $INDEX_ROOT $O(resident) File 26 \$Extend\$Reparse $STANDARD_INFORMATION(resident) $FILE_NAME(resident) $INDEX_ROOT $R(resident) File 27 \RECYCLER $STANDARD_INFORMATION(resident) $FILE_NAME(resident) $INDEX_ROOT $I30(resident) File 28 \RECYCLER\S-1-5-21-1177238915-436374069-839522115-500 $STANDARD_INFORMATION(resident) $FILE_NAME(resident) $FILE_NAME(resident) $INDEX_ROOT $I30(resident) File 29 \RECYCLER\S-1-5-21-1177238915-436374069-839522115-500\desktop.ini $STANDARD_INFORMATION(resident) $FILE_NAME(resident) $DATA(resident) File 30 \RECYCLER\S-1-5-21-1177238915-436374069-839522115-500\INFO2 $STANDARD_INFORMATION(resident) $FILE_NAME(resident) $DATA(resident)
文件“f-mft.txt”中的MFT记录很长,作者节选了最前面的一部分。从上面显示的结果中可以看出,序号为File12至File15的MFT记录虽然有,但其内容是空的,系统没有使用,序号为File16至File23没有记录。这是NTFS文件系统保留的一部分存储空间,以备将来进行扩充时使用。
nfi.exe虽然能读出MFT记录,但显示的结果过于简单,看不出每个MFT记录的全貌。所以作者在实际操作中,还是喜欢使用自己编写的工具程序对MFT记录进行查找和显示。下面使用作者编写的程序,将MFT文件和MFT镜像文件的MFT记录显示出来,供读者参考。
用十六进制数据显示的MFT文件的MFT记录,如图3-7所示。
图3-7
用字符形式显示的MFT文件的MFT记录,如图3-8所示。
图3-8
用十六进制数据显示的MFTMirr文件的MFT记录,如图3-9所示。
图3-9
用字符形式显示的“MFTMirr”文件的MFT记录,如图3-10所示。
图3-10
3.6 NTFS的文件存储特性
NTFS文件系统在磁盘上写入文件数据的时候,有两种存储方式,即驻留的和非驻留。
3.6.1 NTFS的驻留属性
如果一个文件很小,文件的所有属性和属性的值,这其中包括文件的数据,就全部存放在文件的MFT记录里。当属性值直接存储在MFT记录中时,其属性被称为“驻留属性”。
现在用一个演示实例,来看一下文件数据的驻留属性。作者向逻辑盘F上拷入一个小文件,文件名为“小文件存储实验.txt”。文件很小,只有60字节,其内容如下。
欢迎使用Symantec公司的NORTON UTILITIES 8.0中文版!
根据文件名称里的字符串特征,运行“查找汉字文件名.EXE”程序,查找到文件的MFT记录,并把MFT文件表的扇区数据存储到备份文件“minmft”中保存。然后使用“查看扇区文件数据.EXE”程序,打开文件将数据显示出来,如图3-11所示。
图3-11
在图3-11所示的程序界面中,观察对话框里显示的数据,从第24行开始记录的是文件的数据内容,下面解释几个主要字段表示的意义。
(1)第24行第1字节起始,偏移0x00开始的4字节,表示属性类型。当前的值是“80H”,表示记录的是数据属性。
(2)偏移0x04开始的4字节,表示属性的长度。当前值是“58H”,换算成十进制是“88”,表示本属性占用88字节。这里面包括属性字段的全部记录,计算时要从第1字节开始。
(3)偏移0x10开始的4字节,表示属性值的长度。当前值是“3cH”,十进制为“60”,说明属性值是60字节,这就是文件数据的字节数。
(4)偏移0x14开始的2字节,是属性值在属性中的字节偏移。当前值是“18H”,说明从18H开始,记录的是属性值。查看一下18H处的字节值是“20”,这是一个空格的ASCII码值,文件数据从这里开始记录。
(5)在属性占用的字节长度之后,是4字节的属性结束标记“FF FF FF FF”。
如果使用文本编辑软件,将文件“minmft”打开,就可以观察到以文本方式存储的文件内容。也可以在WINDOWS 2000的“命令提示符”窗口中,使用DOS的内部命令“TYPE”,观察文件的内容。
在命令行输入“type minmft”,字符使用大小写都可以,然后回车,程序运行的显示界面如图3-12所示。
图3-12
NTFS文件系统的这种特性,即将小文件的数据以驻留的方式存储在MFT文件表中,可以使系统访问小文件数据的速度大大提高。因为系统只要访问磁盘一次,找到文件的MFT记录表以后,就可以立即访问文件数据。而不需要先在MFT表中查找文件数据的存储地址,然后再通过读取另外的分配单元,才能得到文件的数据。
一个小目录的属性,也能象小文件的数据属性一样,驻留在MFT记录中。
3.6.2 NTFS的非驻留属性
当一个文件或目录比较大时,其属性值在MFT记录中就容纳不下了,这时NTFS将在磁盘上为属性数据分配一个与MFT分开的存储区域,这个区域被称为run。如果属性值后来又增长了,譬如用户向文件中添加了新的内容,NTFS将为添加的数据分配另一个run。属性值的这种存储方式称为“非驻留属性”。
当一个文件的属性是非驻留时,文件系统如何定位存储属性值的run的地址呢?在MFT文件记录表里面,是使用逻辑簇号来指定磁盘上的物理地址的,这个逻辑簇号称为LCN。LCN是将NTFS逻辑盘中所有的簇,从开始到最后的逻辑编号,起点从分区引导记录所在的扇区开始。磁盘在格式化时设置的“分配单元大小”选项,确定了每个簇所含有的扇区数,NTFS将其称为“簇因子”。知道了LCN以后,用LCN乘以簇因子,就能得到在逻辑盘上扇区的偏移量。再加上逻辑盘的起始扇区号,就能得到在整个硬盘上的物理扇区地址。
NTFS除了使用LCN表示的逻辑簇号来确定物理扇区的地址,它还对存储非驻留属性值的每个簇设定了一个顺序号,这是属性值的实际簇数。从属性值的第1个簇开始编号,起始号为0,一直编到属性值的最后一簇,NTFS将这个属性值的编号称为VCN。VCN是文件系统引用文件数据时最先得到的存储信息,VCN与LCN之间有映射关系,通过VCN可以得到LCN,从而确定数据在磁盘上的存储地址。
现在用一个具体的演示实例,来看一下非驻留属性值的存储方式,并通过实际计算,得到数据在硬盘上的物理扇区地址。在后面的《探秘篇》里,对NTFS文件系统的扇区存储规律进行分析的过程中,这种计算是需要掌握的最基本内容。特别是在恢复文件数据的操作中,找到数据的存储地址是最为重要的一步,所以对于当前介绍的计算方法,读者要多下一点功夫进行实际操作与练习。
运行“查看扇区文件数据.EXE”程序,将文件“mft1”的数据显示在对话框里。mft1是一个具有非驻留属性的、名为“testfile.txt”文件的MFT记录的备份文件,程序运行后的显示界面如图3-13所示。
图3-13
在图3-13所示的界面中,对话框里第17行的第9字节开始,记录的是文件的非驻留数据属性,下面解释几个主要字段的意义。
(1)在属性记录中,偏移0x00开始的4字节,表示属性类型。当前的值是“80H”,表示记录的是数据属性。
(2)偏移0x04开始的4字节,表示属性的长度。当前值是“48H”,换算成十进制是“72”,表示本属性占用72字节。这里面包括属性字段的全部记录,计算时要从第1字节开始。
(3)偏移0x08开始的1字节,表示数据的存储方式。当前值是“01H”,是系统规定的非常驻标记。
(4)偏移0x10开始的8字节,是实际簇数VCN的起始编号。当前值是“00H”,表示非常驻数据的第1个簇从编号0开始。
(5)偏移0x18开始的8字节,是实际簇数VCN的最后编号。当前值是“1cH”,表示非常驻数据的最后1个簇的VCN编号是1cH。
(6)偏移0x20开始的2字节,是数据转移在属性中的偏移值。当前值是“40H|”,表示从属性起始处偏移40H,是数据转移的字段记录。该字段值描述的是非驻留数据在run中的存储特征。
(7)偏移0x28开始的8字节,是系统分配给非驻留数据的空间大小。当前值是“7400H”,转换成十进制是“29696”,这实际上是文件数据占用磁盘的字节数。
(8)偏移0x30开始的8字节,是非驻留数据的实际大小。当前值是“703fH”,转换成十进制是“28735”,这实际上是文件含有的字节数。
(9)偏移0x38开始的8字节,是非驻留数据的初始大小。当前值是“703fH”,该值对于分析压缩文件数据的扇区存储规律,有非常重要的意义。
(10)偏移0x40开始的1字节,是标记后面的字段记录的字节数。当前值是“31H”,这是使用类似于汇编语言中压缩BCD码的存储方式,在1字节中存入了2个数。低4位的数是“1”,表示其后的1字节构成字段,记录的是存储文件数据所使用的簇数。高4位的数是“3”,表示再往后的3字节构成一个字段,记录的是文件数据存储的起始逻辑簇号,也就是前面所说的LCN。
(11)偏移0x41开始的1字节,是存储文件数据所使用的簇数。当前值是“1dH”,十进制是“29”,说明文件数据使用了29个簇。
(12)偏移0x42开始的3字节,是存储文件数据的起始逻辑簇号。当前值是102fa6H,十进制是“1060774”,这就是逻辑簇号LCN的值。将这个值乘以簇因子,就得到在逻辑盘上的逻辑扇区号。再加上逻辑盘的起始物理扇区号,也就是分区引导记录所在的扇区号,就得到存储文件数据的物理扇区地址。
当一个硬盘的系统引导数据被严重破坏,已经无法修复时,就可以先查找文件的MFT记录。然后再根据LCN的值,计算文件数据的存储地址。地址找到以后,使用读取硬盘物理扇区的工具程序,将文件数据备份出来。
(13)在属性占用的字节长度之后,是4字节的属性结束标记“FF FF FF FF”。
3.7 NTFS的数据压缩特性
NTFS文件系统支持对文件数据进行压缩,同时也支持对目录进行压缩。NTFS的压缩比率不是很大,与众多第三方的压缩软件相比较,NTFS的压缩比率是最小的。作者选了3个文件,使用NTFS的压缩功能和WinRAR压缩软件,分别进行了压缩,压缩后文件字节数的变化结果见表3-2。
表3-2文件压缩后字节数的变化
从表3-2统计的数据中可以看出,NTFS的压缩比率远远不如WinRAR压缩软件。虽然对内容以文字为主的DOC型文件的压缩比率最大,但也比WinRAR的压缩比率差了一倍。那么在实际应用当中,选择使用NTFS的压缩功能的理由是什么呢?其原因主要有以下几方面。
(1)NTFS 支持对目录的压缩,并且可以选择对目录中的子目录与文件进行压缩,所有的压缩都是将每个文件独立进行的。它不象其他压缩软件那样,在对目录进行压缩时,将目录中的文件全部打包压缩。而要使用其中的某一个文件,必须要对压缩包实行解压。NTFS的这种透明的压缩特性,对使用者来说是比较方便的。
(2)只要对目录进行一次设置,则以后所有拷入这个目录的文件,都会自动地实现压缩功能,不需要进行其他操作。
(3)可以对压缩状态的文件进行修改,修改后的文件仍然会以压缩形式存盘。这种特性非常适合于编辑文本文件,操作者如同操作一般文件,根本感觉不出操作的是压缩文件。
NTFS的这些方便操作者的特性,弥补了它压缩比率小的不足。在文本编辑方面,得到了较为广泛的应用。
当一个文件被NTFS压缩以后,文件的MFT记录也同时被修改,很多属性中的字段值被赋予了新的内容。正确解读属性中的这些字段记录,对于恢复硬盘上的压缩文件数据有很重要的意义。
作者进行过有关的实验操作,在一个NTFS逻辑盘上,将经过NTFS压缩的文件删除,使用现有的数据恢复软件,能够成功将文件恢复。但是将逻辑盘格式化以后,要恢复同一个文件,使用同一个数据恢复软件,最后却是失败的结果。
由于现有的数据恢复软件是别人所写,作者不了解程序的运行机制,所以只能根据现象推测一下原因。造成上面这种实验结果的原因,可能是数据恢复软件在运行中,使用了文件系统记录的某些数据。当文件被删除时,原先文件系统记录的某些数据仍然存在,所以恢复文件数据成功了。而当逻辑盘被格式化以后,文件系统原来记录的数据已经全部被刷新了,所以恢复文件数据就失败了。
作者在对硬盘扇区的操作中发现,NTFS逻辑盘被格式化以后,虽然文件系统的很多记录被刷新了,但是在压缩文件的MFT记录中,数据属性里的字段记录仍然完好地保存着。这时候使用作者介绍的数据移植的方法,就能成功地将压缩文件的数据恢复出来。因为作者介绍的这种操作方法,是不需要文件系统数据记录的支持的,只要文件数据在硬盘上没有被其他数据覆盖掉,就能通过读取物理扇区数据的方法,达到恢复文件数据的目的。
本节先感性地认识一下MFT记录的变化,在后面的《探秘篇》中,还要详细地介绍压缩文件的扇区存储规律。其中包括如何解读MFT记录中的数据属性,以及如何从系统崩溃的NTFS逻辑盘上,移植并恢复压缩文件的数据。
一个没有被压缩的文件的MFT记录,如图3-14所示。
图3-14
同一个文件被压缩后的MFT记录,如图3-15所示。
图3-15
在图3-14和图3-15中,从第17行开始记录的是文件的数据属性,这也是在探索压缩文件的扇区存储规律时,必须解读的文件属性。比较一下两个图中的数据,可以发现文件压缩后的数据属性发生了很大的变化。作者为解读这一数据属性,特别编写了专用功能的工具程序,具体操作过程在《探秘篇》中再作介绍。
3.8 NTFS的EFS加密特性
NTFS文件系统在对用户文件的管理中,提供了两个重要的功能设置选项。上一节介绍了其中的一个,即对文件的压缩功能。本节介绍另一个功能,即NTFS对用户文件的加密功能。
在NTFS文件系统中,包含了一个对用户文件进行加密的子系统,即被称为EFS的文件加密系统。EFS在对文件进行加密时,如同上一节所讲的压缩操作一样,也是完全透明的。被加密的文件具有下述的特点。
(1)EFS支持对目录的加密,在选择了对目录加密以后,目录中所有的文件都会被加密。
(2)只要对目录进行一次加密设置,则以后所有拷入这个目录的文件,都会自动地实现加密功能,不需要进行其他操作。
(3)可以对加密状态的文件进行修改,修改后的文件仍然会以加密形式存盘。这种特性非常适合于编辑文本文件,操作者如同操作一般文件,根本感觉不出操作的是加密文件。
在使用EFS加密功能时,要注意以下两个问题。一是在系统引导盘的根目录下,不能使用EFS对文件进行加密。二是以操作系统WINDOWS 2000为例,在系统使用的目录WINNT下,不能使用EFS对文件进行加密。
形成上面两个问题的原因如下。EFS加密功能在系统引导期间不被使用。在系统引导过程中,系统引导盘的根目录和WINNT目录下的许多文件,都需要在系统引导过程中被加载。
EFS的加密强度是比较高的,据有关资料记载,在美国本土发行的WINDOWS操作系统版本中,EFS加密密钥是128位。在输出到美国以外的WINDOWS操作系统版本中,EFS加密密钥是56位。
被EFS加密以后的用户文件,只能使用用户帐号的EFS私有/公共密钥对来进行访问,而私有密钥是被用户帐号的密码锁定的。除此之外,没有任何方法能够访问用户的加密文件。
现在将EFS的加密机制简要地介绍一下,目的是让读者大致了解加密与解密的几个关键步骤,为后面在《探秘篇》中学习如何恢复EFS加密文件的数据,先期掌握一些基础知识。至于加密和解密本身的算法问题,不在本书讨论的范围之内。
NTFS文件系统在对文件数据进行加密时,使用的是DESX的加密算法。DESX是对称型的加密算法,因为对称型加密算法的执行速度非常快,特别适合对大量文件数据进行加/解密操作。所谓对称型加密算法,也就是说文件系统使用相同的密钥,对文件数据进行加/密与解密。所用的这个密钥,在NTFS文件系统中将其称之为FEK。
密钥FEK的数据也象文件数据一样,存储在逻辑盘的数据区中。并且在加密文件的MFT表里面,也记录了FEK的存储地址,所以FEK是任何用户都能够访问的。即使用户没有进入操作系统的权限,也可以使用读取物理扇区的方法,将FEK的数据读出来。
因此密钥FEK的数据不能以明文的形式存储在磁盘扇区中,而必须对其加密予以保护。EFS加密机制使用私用/公共密钥对,对存储在磁盘扇区中的FEK的数据进行加密,这时FEK就是安全的了。即使非法用户能够读出FEK的数据,所得到的也只是密文,是不能对用户的文件数据进行解密的。这种基于RSA公共密钥的加密算法,加密强度是很高的。其他的非法用户没有私用密钥,就不能对FEK进行解密。而没有解密的FEK,也就不能对加密文件的数据进行解密。
下面用一个EFS对文件加密的实例,来看一下文件的MFT记录中的变化。掌握MFT的这种变化,是本书对NTFS文件系统的扇区存储规律进行探秘的根本依据。所以读者一定要多观察MFT记录的存储状况,使用作者给出的工具程序,多动手进行操作演示,才能掌握这种通过读写磁盘物理扇区,解读NTFS的扇区存储规律,继而进一步实现修复系统与恢复文件的目的。
使用工具程序,将一个文件在加密前的MFT记录读出来,显示结果如图3-16所示。
图3-16
再将文件经过EFS加密以后的MFT记录读出来,显示结果如图3-17所示。
图3-17
将图3-16和图3-17比较一下,可以看出文件加密以后的MFT记录中,增加了很多新的内容。解读这些增加的内容,就能为恢复EFS加密的文件数据提供思路。把加密以后的MFT扇区数据用字符方式显示出来,结果如图3-18所示。
图3-18
在图3-18所示的界面中,可以看到在最下面的一行里,有“$EFS”的标记。在这个标记之后记录的,就是FEK密钥的数据存储地址。
这里还要说明一个问题,每个MFT记录都要占用两个扇区。如果被加密的文件的属性较多,或是文件的名称很长,则加密以后的$EFS标记就有可能存储在MFT的第二个扇区里。因此在观察文件加密前后的MFT数据的变化时,最好将两个扇区都观察一下,不要漏掉某些重要的字段记录。
3.9 小结
本书所介绍的NTFS文件系统的一些功能与特性,只是其所有性能中的一部分,还有很多其他方面的内容没有涉及,这其中有两方面的原因。
第一方面,是NTFS的某些特性与本书所讨论的主题关系不大。本书讨论的主题是探索NTFS文件系统的扇区存储规律,从而为修复系统数据或恢复文件数据提供一些技巧与方法。
而有些NTFS文件系统的特性,只是在文件系统的内核中实现的,与本书的应用关系不是很大。譬如硬链接、用户配额、支持POSIX 1003.1标准等特性,在书中没有进行分析。
第二方面,是作者对有的特性,还没有在扇区存储规律上解读成功。即使是找到了一些看似有规律的某些特征,但在不能完全解读之前,担心由于自己分析问题的片面性而误导了读者,所以也没有收录到书中。譬如NTFS的日志文件的扇区存储规律,作者虽然在这方面下了很大的功夫,耗费了很多时间,但始终不能完全揭示其在扇区中的存储规律。如果能完全解读NTFS的日志文件,结合对物理扇区的读写操作,无疑会在修复系统数据与恢复文件数据方面,增加更多强有力的技术手段。