美文网首页
关于NTFS-MFT

关于NTFS-MFT

作者: 嘿_lele | 来源:发表于2018-10-19 10:47 被阅读0次

    一、Ntfs文件系统在磁盘上的分布

    一个ntfs文件系统由引导扇区、MFT(包含MFT元数据)和数据区组成。
    NTFS中存储了两份MFT备份以防MFT文件损坏,两个MFT备份的具体起始位置都存储在引导扇区中。


    image.png

    二、引导扇区($Boot)

    引导扇区是从NTFS文件系统的第一个扇区开始,以55 AA结尾。我们主要关注前88字节的信息,其中重要的就是“NTFS”标识、扇区大小、每簇扇区数、MFT起始簇以及MFT备份MFTMirr位置这些信息。我们可以根据MFT起始簇信息找到MFT,或者根据MFT备份MFTMirr位置找到MFT的另外一个MFT备份。如下图所示:


    image.png
     1 typedef struct NTFS_BPB{     // 在cmd 输入 fsutil fsinfo ntfsinfo d: 查询 NTFS 信息
     2     UCHAR jmpCmd[3];
     3     UCHAR s_ntfs[8];            // "NTFS    " 标志
     4 // 0x0B
     5     UCHAR bytesPerSec[2];       //  0x0200  扇区大小,512B
     6     UCHAR SecsPerClu;           //  0x08    每簇扇区数,4KB
     7     UCHAR rsvSecs[2];           //       保留扇区
     8     UCHAR noUse01[5];           //
     9 // 0x15
    10     UCHAR driveDscrp;           //  0xF8     磁盘介质 -- 硬盘
    11     UCHAR noUse02[2];           //
    12 // 0x18
    13     UCHAR SecsPerTrack[2];      //  0x003F  每道扇区数 63
    14     UCHAR Headers[2];           //  0x00FF 磁头数
    15     UCHAR secsHide[4];          //  0x3F  隐藏扇区
    16     UCHAR noUse03[8];           //
    17 // 0x28
    18     UCHAR allSecsNum[8];        // 卷总扇区数, 高位在前, 低位在后
    19 // 0x30
    20     UCHAR MFT_startClu[8];      // MFT 起始簇
    21     UCHAR MFTMirr_startClu[8]; // MTF 备份 MFTMirr 位置
    22 //0x40
    23     UCHAR cluPerMFT[4];     // 每记录簇数 0xF6
    24     UCHAR cluPerIdx[4];     // 每索引簇数
    25 //0x48
    26     UCHAR SerialNum[8];     // 卷序列号
    27     UCHAR checkSum[8];     // 校验和
    28 }Ntfs_Bpb,*pNtfs_Bpb;
    

    三、主文件表 (Master File Table, MFT)

    MFT是什么,什么作用?
    在NTFS中,整个卷的所有文件信息(包括MFT本身、数据文件、文件夹等等)都存储在MFT。每一个文件在 MFT 中都有一个或多个 MFT 项记录文件属性信息。而且每项大小是固定的(一般为1KB),MFT保留了前16项用于特殊文件记录,称为元数据。
    可以根据MFT快速的找到文件的详细信息和具体位置等。


    image.png

    1、MFT项

    一个MFT项包括MFT头和关于文件的4条属性,以FF FF FF FF结尾。


    image.png

    (一)MFT头部

    在一个MFT项中前56字节是MFT头部信息,其中比较重要的是FILE标识、第一个属性的偏移和flags。
    flags显示了此文件是否是正常文件,或者是删除文件等。


    image.png
     1 typedef struct MFT_HEADER{
     2     UCHAR    mark[4];             // "FILE" 标志 
     3     UCHAR    UsnOffset[2];        // 更新序列号偏移     30 00
     4     UCHAR    usnSize[2];          // 更新序列数组大小+1   03 00
     5     UCHAR    LSN[8];              // 日志文件序列号(每次记录修改后改变)  58 8E 0F 34 00 00 00 00
     6 // 0x10
     7     UCHAR    SN[2];               // 序列号 随主文件表记录重用次数而增加
     8     UCHAR    linkNum[2];          // 硬连接数 (多少目录指向该文件) 01 00
     9     UCHAR    firstAttr[2];        // 第一个属性的偏移  38 00
    10     UCHAR    flags[2];            // 0已删除 1正常文件 2已删除目录 3目录正使用
    11 // 0x18
    12     UCHAR    MftUseLen[4];        // 记录有效长度    A8 01 00 00
    13     UCHAR    maxLen[4];            // 记录占用长度   00 04 00 00
    14 // 0x20
    15     UCHAR    baseRecordNum[8];     // 索引基本记录, 如果是基本记录则为0
    16     UCHAR    nextAttrId[2];        // 下一属性Id  07 00
    17     UCHAR    border[2];            //
    18     UCHAR    xpRecordNum[4];       // 用于xp, 记录号
    19 // 0x30
    20     UCHAR    USN[8];          // 更新序列号(2B) 和 更新序列数组
    21 }Mft_Header, *pMft_Header;
    

    (二)MFT项的4个属性

    每条属性都包含属性头和属性结构。每条属性的前4字节显示该属性的类型,不同类型的属性有不同的属性结构。


    image.png
    属性头
     1 //------------------  属性头通用结构 ----
     2 typedef struct NTFSAttribute //所有偏移量均为相对于属性类型 Type 的偏移量
     3 {
     4     UCHAR Type[4];           // 属性类型 0x10, 0x20, 0x30, 0x40,...,0xF0,0x100
     5     UCHAR Length[4];         // 属性的长度 
     6     UCHAR NonResidentFiag;   // 是否是非常驻属性,l 为非常驻属性,0 为常驻属性 00
     7     UCHAR NameLength;        // 属性名称长度,如果无属性名称,该值为 00
     8     UCHAR ContentOffset[2];  // 属性内容的偏移量  18 00
     9     UCHAR CompressedFiag[2]; // 该文件记录表示的文件数据是否被压缩过 00 00
    10     UCHAR Identify[2];       // 识别标志  00 00
    11 //--- 0ffset: 0x10 ---
    12 //--------  常驻属性和非常驻属性的公共部分 ----
    13     union CCommon
    14     {
    15     //---- 如果该属性为 常驻 属性时使用该结构 ----
    16         struct CResident
    17         {
    18             UCHAR StreamLength[4];        // 属性值的长度, 即属性具体内容的长度。"48 00 00 00"
    19             UCHAR StreamOffset[2];        // 属性值起始偏移量  "18 00"
    20             UCHAR IndexFiag[2];           // 属性是否被索引项所索引,索引项是一个索引(如目录)的基本组成  00 00
    21         };
    22     //------- 如果该属性为 非常驻 属性时使用该结构 ----
    23         struct CNonResident
    24         {
    25             UCHAR StartVCN[8];            // 起始的 VCN 值(虚拟簇号:在一个文件中的内部簇编号,0起)
    26             UCHAR LastVCN[8];             // 最后的 VCN 值
    27             UCHAR RunListOffset[2];       // 运行列表的偏移量
    28             UCHAR CompressEngineIndex[2]; // 压缩引擎的索引值,指压缩时使用的具体引擎。
    29             UCHAR Reserved[4];
    30             UCHAR StreamAiiocSize[8];     // 为属性值分配的空间 ,单位为B,压缩文件分配值小于实际值
    31             UCHAR StreamRealSize[8];      // 属性值实际使用的空间,单位为B
    32             UCHAR StreamCompressedSize[8]; // 属性值经过压缩后的大小, 如未压缩, 其值为实际值
    33         };
    34     };
    35 };
    

    具体属性头的大小根据是否是常驻属性来进行计算。
    是否是常驻属性根据属性头的第9个字节判断,1为非常驻,0为常驻。
    如果是非常驻属性,属性头大小为64;如果是常驻属性,属性头大小为24字节。
    常驻和非常驻的区别:
    常驻属性是直接保存再MFT中,非常驻属性保存再MFT之外的其他地方。如果文件或文件夹小于1500字节,那么它们的所有属性,包括内容都会常驻在MFT中。

    属性结构

    不同类型的属性有不同的属性结构,这里主要介绍10H属性、30H属性和80H属性。

    (1)10H属性 $STANDART_INFORMATION
    image.png
     1 struct Value0x10
     2 {
     3     UCHAR fileCreateTime[8];    // 文件创建时间 
     4     UCHAR fileChangeTime[8];    // 文件修改时间 
     5     UCHAR MFTChangeTime[8];     // MFT修改时间 
     6     UCHAR fileLatVisited[8];    // 文件最后访问时间 
     7     UCHAR tranAtrribute[4];     // 文件传统属性
     8     UCHAR otherInfo[28];        // 版本,所有者,配额,安全等等信息(详细略)
     9     UCHAR updataNum[8];         // 文件更新序列号 
    10 }; 
    

    关于文件传统属性,对照下表:


    image.png
    (2)30H属性 $FILE_NAME

    这个属性比较重要,包含了文件的详细资料和父目录的参考号等。根据父目录参考号可以知道文件之间的父子关系,从而构建文件的子父关系。
    其实在10H属性中已经描述了文件的部分信息(时间、标志等),30H属性主要关注父目录的参考号、文件名命名空间和文件名。


    image.png
     1 struct Value0x30
     2 {
     3     UCHAR parentFileNum[8];     // 父目录的文件参考号,前 6B 的文件记录号,后 2B 的文件引用计数;当文件记录号为0x05时,是根目录。
     4     UCHAR createTime[8];        // 文件创建时间
     5     UCHAR changeTime[8];        // 文件修改时间
     6     UCHAR MFTchangeTime[8];     // MFT 修改时间 
     7     UCHAR lastVisitTime[8]      // 最后一次访问时间 
     8     UCHAR AllocSize[8];         // 文件分配大小 
     9     UCHAR realSize[8];          // 实际大小 
    10     UCHAR fileFlag[4];          // 文件标志,系统 隐藏 压缩等等 
    11     UCHAR EAflags[4]            // EA扩展属性和重解析点
    12     UCHAR nameLength;           // 文件名长 
    13     UCHAR nameSpace;            // 文件命名空间:0 --- POSIX, 1 -- Win32, 2 --- DOS, 3 --- Win32 & DOS
    14     //----- Name (Unicode编码) 长度为 2 * nameLength ---- 
    15 }
    

    NTFS通过为一个文件创建多个30H属性实现POSIX (Portable Operating System Interface, 可移植操作系统接口) 式硬连接,每个30H属性都有自己的详细资料和父目录;一个硬连接删除时,就从MFT中删除这个文件名,最后一个硬连接被删除时,这个文件就算是真正被删除了。

    (3)80H属性$DATA

    LCN(logical cluster number):整个文件卷的相对位置,单位(簇)。
    VCN(virtual cluster number):文件内部的相对位置,单位(簇)。

     1 struct Value0x80
     2 {
     3     UCHAR len;          // 低4位表示运行簇大小的len,高4位表示起始簇的len
     4     UCHAR *filesize;    // 运行簇大小
     5     UCHAR *start;       // 起始簇 LCN/VCN
     6 }
    

    每个运行列表中第一个字节的低4位表示运行簇大小(filesize)的len,高4位表示起始簇(start)的len。如果一个运行列表后面的第一个字节是00,说明运行列表结束,后面的数值暂时不用管;如果不是00,则是下一个运行列表开始。

    ①非常驻-->一个运行列表
    image.png

    0x00~0x3F 是属性头;运行列表在橘黄色框中,0x40开始,可以得到运行列表 33 40 BC 00 00 00 0C。
    分析如下:
    首先0x33,低4位是3,表示紧随其后的3Byte 0xBC40作为运行簇大小(簇个数),即文件所占总大小;高4位是3,表示簇大小之后的3个Byte 0x0C0000 是起始簇,即文件起始,这里是说的是LCN。

    ②非常驻-->多个运行列表
    image.png

    分析如下:
    第一个运行列表,首先是0x31,低4位是1,表示紧接着的1Byte(03)是运行簇大小;高4位是3,表示紧接着3Byte(65 9A 00)是起始簇,这里说的是LCN;
    第二个运行列表,首先是0x11,低4位是1,表示紧接着的1Byte(01)是运行簇大小;高4位是1,表示紧接着3Byte(13)是起始簇,这里说的是VCN。
    注意,只有第一个运行列表的起始簇说的是LCN,从第二个运行列表开始每个运行列表的起始簇都说的是VCN。想要得到LCN需要按下面的公式计算:
    第n个运行列表的LCN = 第一个运行列表的起始簇(LCN) + 第二个运行列表的起始簇(VCN) +...+第n个运行列表的起始簇(VCN)

    ③常驻
    image.png

    四、常见问题

    (一)如何从NTFS文件系统中找到$MFT文件的起始和总大小

    1、从引导扇区找到“MFT起始簇”或者”MFT备份MFTMirr位置“;
    2、根据“MFT起始簇”或者”MFT备份MFTMirr位置“找到第一个MFT项(1KB),第一个MFT项就是$MFT的属性内容;
    3、在第一个MFT项中找到80H属性,根据80H属性的属性结构找到文件起始和总大小;
    4、上面3找到的就是MFT文件的起始和总大小了。

    (二)MFT文件和MFTMirr文件的区别

    MFT文件是对NTFS中全部MFT(卷上的所有文件,包括文件名、时间戳、流名和数据流所在的群集号列表、索引、安全标识符以及诸如“只读”、“压缩”、“加密”之类的文件属性)的存储,可以根据MFT文件快速的查找卷上的所有文件;而MFTMirr文件是对MFT文件中比较重要项的复制,一般是4KB。

    参考:
    https://www.cnblogs.com/mwwf-blogs/archive/2015/05/04/4467687.html
    https://en.wikipedia.org/wiki/NTFS#Master_File_Table?tdsourcetag=s_pcqq_aiomsg
    https://wenku.baidu.com/view/f204bb89e518964bce847cae.html
    备注:如果想了解其他类型的属性,详见参考文章。

    相关文章

      网友评论

          本文标题:关于NTFS-MFT

          本文链接:https://www.haomeiwen.com/subject/hzpjzftx.html