1. 程式人生 > >NTFS檔案系統結構--從零開始追蹤一個檔案的位置

NTFS檔案系統結構--從零開始追蹤一個檔案的位置

前言:最近由於專案需要,研究了一下NTFS檔案系統,NTFS檔案系統是windows使用的檔案系統,包括NT,2000,xp系列。無奈萬惡資本主義的windows將自家的東西全部藏在陰暗的角落,NTFS理所當然地也不開源,儘管沒有原始碼,還是有足夠豐富的資料將NTFS檔案系統曝光在自由的陽光下。下面通過從NTFS檔案系統的根源出發,展示如何通過一層層的解析,最終讀取到其中的某個檔案。

環境:LINUX Ubuntu16.04,待解析的檔案系統:NTFS,追蹤其中的檔案:C:\WINDOWS\DtcInstall.log(隨機找的,僅僅以此為例)

說明:本人找了一塊完整的NTFS檔案系統映象,它裡面是一個完整的Windows XP系統,是從Windows XP虛擬機器映象切下來的(因為虛擬機器映象不止包括完整的檔案系統,例如我的這塊虛擬機器映象從第0x7E000位元組以後才是完整的NTFS檔案系統),這些都不重要,重要的是現在你只要有一塊完整的NTFS檔案系統,當然必須是Window XP系統的,因為我們還有追蹤C:\WINDOWS\DtcInstall.log

這個檔案,所以其實在Windows XP中使用Disk Genius開啟你C盤分割槽就是一塊完整的NTFS檔案系統,如果以16進位制檢視應該是這樣的:

NTFS檔案系統的佈局:


BOOT存放一些檔案系統基本資訊,如一個扇區512bytes,一簇(cluster)有8個扇區,共4K,比較重要的一項是MFT的偏移簇號。

MFT是NTFS中最重要的部分,它是一個個以“FILE"開始的檔案記錄資料結構。

struct 檔案記錄{
檔案記錄頭;
屬性1;
屬性2;
屬性3;
……
}

而屬性包括屬性頭和屬性體兩部分,如下屬性的資料結構。
struct 屬性{
屬性頭;
屬性體;
}

所以,下面的檔案記錄結構舉例請參考檔案記錄結構、檔案記錄頭結構、屬性頭結構、不同屬性體結構來看!

這個資料結構就是檔案的全部資訊,檔案的各種屬性都放在這個資料結構中,在NTFS中檔案內容也屬於檔案的屬性,所以在NTFS中檔案的一切都是屬性,比如在這個資料結構中有30H屬性記錄檔名,10H屬性記錄檔案的一些元資訊如建立、訪問時間等,而80H屬性則是檔案的內容,因為一個檔案記錄資料結構僅僅4K,所以如果檔案很大,80H屬性存放的不再是檔案內容,而是存放檔案內容的簇索引號run list.對於run list 解析以後介紹,這裡知道它是檔案內容的簇偏移索引即可。舉例說明,如DctInstall.log檔案的檔案記錄如圖:


注意這個檔案內容是160位元組,80H屬效能夠包括全部內容,所以這個80H屬性是常駐屬性,如果是非常駐屬性,則檔案內容在run list表示的簇偏移中。注意常駐屬性和非常駐屬性的結構是不一樣的。

NTFS系統的其他部分比如FreeSpace等相關性不大,不做解釋,可參考其他資料。

第一步,定位根目錄:

通過BOOT塊中的資訊獲取MFT偏移量為第0x40000簇,如圖,而根目錄在MFT的第6個檔案記錄。


MFT偏移簇數0x4000


MFT0到11個固定的檔案記錄,第6個為根目錄的檔案記錄

找到根目錄的檔案記錄的偏移位置,主要關注他的A0H屬性,因為這個屬性記錄根目錄中所有檔案的檔名以及檔案記錄的位置。如圖(再次強調,務必參考檔案記錄的結構理解圖片內容)


根目錄的檔案記錄

第二步:找到根目錄的索引節點和WINDOWS目錄索引項

由根目錄的檔案記錄的A0H屬性的run list :0x31 01 52f909,根據run list的特殊計算方式(具體可參考文末連結)即第一個位元組的3代表後三位元組為簇偏移量,第一個位元組的1代表共一簇。所以記錄根檔案中所有檔案的檔名以及檔案記錄號的簇偏移位置為0x09f952(ntfs採用小端方式儲存資料),共一簇。所以現在偏移到0x09f952簇檢視具體內容。如圖所示(請務必參考索引節點的資料結構閱讀圖片):

其中索引節點的資料結構:

struct 索引節點{
索引頭;
索引項1;
索引項2;
索引項3;
……
}



由圖片可以看出,根目錄的索引節點有索引頭和一個個索引項構成,其中這一個個索引項和根目錄中的每個檔案或目錄一一對應,這些目錄項的檔名就是根目錄中檔案或目錄的名稱。我們現在偏移到根目錄下目錄名為WINDOWS的索引項,如圖:


WINDOWS目錄的索引項

第三步:定位WINDOWS目錄的檔案記錄

由WINDOWS索引項的MFT號,即起始的8個位元組,可以計算出WINDOWS目錄的檔案記錄號,即ox0000 0000 001c=28,所以WINDOWS目錄的檔案記錄號為28,相對於MFT起始位置偏移28項,0x28*0x400=0x7000。和根目錄一樣,因為WINDOWS是個目錄,所以仍然關注A0H屬性,因為此屬性記錄WINDOWS目錄中所有檔案或目錄的名稱和MFT號(檔案記錄號),WINDOWS目錄的檔案記錄如圖:


WINDOWS目錄的檔案記錄,重點關注A0H屬性

第四步:獲取WINDOWS目錄的索引節點以及WINDOWS目錄下DtcInstall.log的索引項

如上圖run list 不止一項,先取第一項0x31 0a a1a606,即WINDOWS目錄中一部分檔案或目錄的索引項資訊(包括檔案或目錄名以及檔案或目錄的MFT號)在簇偏移為ox06a6a1處,共有0x01簇。

現在偏移到435873簇(0x06a6a1),內容如圖,與根目錄下的索引項內容類似,可以發現我們要找到DtcInstall.log檔名已經出現。


DtcInstall.log的索引項

第五步:獲取DtcInstall.log檔案的MFT號,偏移到指定位置

從DtcInstall.log索引項中我們可以發現該檔案的MFT號為ox15f9,所以該檔案的檔案記錄在MFT的偏移位置為ox15f9*0x400=0x57e400,找到該偏移位置,如圖(這個圖上面貼過):

該檔案記錄儲存著DtcInstall.log的全部資訊,包括檔案內容,由於檔案內容小,所以80H屬性可以容納全部,所以是常駐屬性,否則應該是非常駐屬性,而且非常駐屬性的最後是run list 指向檔案內容的真正簇偏移。

結束

至此,對NTFS檔案系統中某個檔案的追蹤過程全部結束,本文著重解釋檔案在NTFS檔案系統的邏輯關係,對於NTFS檔案系統的基礎知識不做過多介紹,所以閱讀本文前,可以參考文末連結瞭解NTFS的基礎知識。另外,人非聖賢,過程中難免有錯誤,歡迎批評指正!

參考資料: