書名: NTFS文件系統扇區存儲探秘作者名: 宋群生 宋亞瓊編著本章字數: 976字更新時間: 2018-12-27 08:01:45
第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的日志文件,結合對物理扇區的讀寫操作,無疑會在修復系統數據與恢復文件數據方面,增加更多強有力的技術手段。