前言

本篇将了解到 NTFS 分区结构下文件记录中常见的属性,以及属性的结构。

知识点总览

  • NTFS 文件记录的常见属性
  • 各类文件/文件夹的常用属性
  • 各项属性详解
    • 10H 属性
    • 30H 属性
    • 80H 属性
    • 90H 属性
    • A0H 属性
    • B0H 属性

NTFS 文件记录的常见属性

在 NTFS 分区下的文件或文件夹的文件记录中,经常使用的属性有:

  • 10H 属性(标准信息)
  • 30H 属性(文件名属性)
  • 80H 属性($DATA 属性)
  • 90H 属性(文件夹/根 索引属性)
  • A0H 属性(索引分配属性)
  • B0H 属性(位图属性)

各类文件/文件夹的常用属性

文件的文件记录经常使用的属性

  • 10H 属性(标准信息)
  • 30H 属性(文件名属性)
  • 80H 属性($DATA 属性)

小文件夹的常用属性

  • 10H 属性(标准信息)
  • 30H 属性(文件名属性)
  • 90H 属性(文件夹/根 索引属性)

大文件夹的常用属性

  • 10H 属性(标准信息)
  • 30H 属性(文件名属性)
  • 90H 属性(文件夹/根 索引属性)
  • A0H 属性(索引分配属性)
  • B0H 属性(位图属性)

特殊情况

有些小文件夹也有可能有 A0H 属性和 B0H 属性,这是因为这类文件夹往往是小文件夹变成大文件夹后再变为小文件夹产生的。(即用户将文件夹中的文件删除后,文件夹中的剩余文件数量非常少(甚至是空的)而形成的小文件夹)

各项属性详解

10H 属性

10H 属性的类名为 $STANDARD_INFORMATION(标准信息),是所有文件记录或文件夹都具有的常驻属性,它包含了文件或文件夹的基本信息。例如:日期、时间、有多少个目录指向文件或文件夹等。

这个属性一般位于属性头之后的第一个属性,偏移地址通常为 38H。

image-20211123094332501

30H 属性

30H 属性一般紧跟 10H 属性之后。30H 属性属于常驻无属性名属性,用于存储文件名。其大小为 68~578 字节(文件名最大为 255 个 Unicode 字符),如果一个文件或文件夹的名字超过 8 个字符时,在文件记录中就会有两个 30H 属性,一个 30H 属性描述的是短文件名,另一个描述的则是长文件名。

image-20211123105856247

80H 属性

80H 属性即 $DATA 属性,80H 属性主要用于存储文件。该属性一般情况下可分为三种结构:

  • 有属性头而无属性体
  • 常驻无属性名
  • 非常驻无属性

image-20211124160123744

有属性头无属性体

这种属性主要针对没有内容(0 字节)的文本文件的情况。

image-20211124161048806

常驻无属性名

80H 常驻无属性名分为 80H 属性头和 80H 属性体(即文件内容)两部分。文件内容的长度为 8 的倍数,当文件内容结束时并没有达到 8 的倍数时,多余的字节用 00 来填充。

字节偏移 长度/字节 含义
00H 4 属性类型(80H,对象 ID 属性)
04H 4 该属性长度(包括文件属性头头部本身)
08H 1 是否为常驻标志,此处为 00,表示常驻
09H 1 属性名的名称长度,00 表示没有属性名
0AH 2 属性名的名称偏移
0CH 2 标准(压缩、加密、稀疏等)
0EH 2 属性 ID 标识
010H 4 属性体长度(L)
014H 2 属性内容起始偏移
016H 1 索引标志
017H 1 填充
018H L 文件内容

非常驻无属性名

非常驻的属性一般以数据流(Run List)的形式表示,此处以一个 $LogFile 文件的 80H 属性进行分析,具体的数据流列表如下:

32 98 1B A6 C8 03

这个数据流的具体含义如下:

  1. 该属性共有 1 个数据流列表
  2. 这个数据流列表占 6 字节,即32 98 1B A6 C8 03,数值32表示该数据流列表的起始簇号占 3 字节,簇数占 1 字节;即该数据流列表起始簇号为 0x03C8A6(即 247974),共占 0x1B98(即 7064)个簇。

数据流(数据运行列)

80H 属性下的第一个未命名数据流也就是文件真正的数据,由 Data Run 来记录其属性体(即文件数据)的具体位置。

结构含义

image-20211124145935103

对应关系

image-20211125103754674

计算方式

通过数据流计算出文件的位置与大小(此处以上图的数据进行计算)

通过解析数据流,我们知道了该文件的位置大小信息为下表:

此处每簇扇区数定义为 8 (扇区/簇)

簇数(16 进制) 簇数(10 进制) 扇区数
位置(隐藏扇区数) 03 C8 A6 247974 1983792
大小 1B 98 7064 56512

有了文件的位置与大小参数,即可从 NTFS 的 DBR 处向后跳转 1983792 扇区 (隐藏扇区数),选中个 56512扇区(文件大小),即可复制选块至新文件,从底层恢复该文件。

90H 属性

90H 属性即 $INDEX_ROOT,是索引根属性,该属性是实现 NTFS 的 B+ 树索引的根节点,它总是常驻属性。

该属性没有最大最小长度性质,属性结构如下:

标准属性头

索引根

索引头

索引项

索引项

...

90H

索引根

字节偏移 字段长度(字节) 描述
标准属性头(已分析过)
0x00 4 属性类型
0x04 4 校对规则
0x08 4 每个索引缓冲区的分配大小(字节数)
0x0C 1 每个索引缓冲区的簇数
0x0D 3 无意义(填充到属性长度能被 8 整除)

索引头

字节偏移 字段长度(字节) 描述
0x00 4 第一个索引项的偏移
0x04 4 索引项的总大小
0x08 4 索引项的分配大小
0x0C 1 标志:当该字节为 00 时,表示其为小索引(适合于索引根);当该字节为 01 时,表示其为大索引(适合于索引分配)
0x0D 3 无意义(填充到属性长度能被 8 整除)

索引项

索引头后面有着不同长度的索引项的序列,由一个带有最后一个索引项标志的特殊索引项来结束。当一个目录比较小,可以全部存储在索引根属性中时,该目录就只需要这一个属性来描述。而如果目录太大不能全部存储在索引根中时,就会有两个附加的属性出现:一个是索引分配属性,描述 B +树目录的子节点;另一个是索引位图属性,描述索引块的索引分配属性使用的虚拟簇号。根目录$Root 包含它自身的一个索引项。

90H($INDEX_ROOT)

索引项描述

字节偏移 字段长度(字节) 描述
0x00 8 该文件的 MFT 参考号
0x08 2 索引项的大小(相对索引项开始的偏移)
0x0A 2 文件名属性体大小
0x0C 2 索引标志:此处为 1 表示这个索引项包含子节点;为 2 表示这是最后一个项
0x0E 2 用 0 填充,无意义
0x10 8 父目录的 MFT 文件参考号
0x18 8 文件创建时间
0x20 8 文件最后修改时间
0x28 8 文件记录最后修改时间
0x30 8 文件最后访问时间
0x38 8 文件的分配大小
0x40 8 文件的实际大小
0x48 8 文件标志
0x50 1 文件名的长度
0x51 1 文件名的命名空间
0x52 2F 文件名
2F + 0x52 P 填充到能被 8 整除(无意义)
P + 2F + 0x52 8 子节点的索引所在的 VCN(需要有子节点时才有)

A0H 属性

A0H 类型属性,即 INDEX_ALLOCATION,它是索引分配属性,也是一个索引(如目录)的基本结构,存储着组成索引的 B +树目录所有子节点的定位信息。它总是非常驻属性,没有最大最小值限制。

A0H 属性结构描述:

字节偏移 字段长度(字节) 描述
~ ~ 标准属性头(已分析过)
0x00 Data Run 列表

202111251459832.jpeg

A0H 属性的 Run List 所描述的数据流,也就是 NTFS 的 B +树结构的索引缓冲区。

B0H 属性

B0H 类型属性即 $BITMAP,也就是位图属性,该属性是由一系列的位构成的虚拟簇(VCN)使用情况表,它没有最大最小限制。该属性目前用在两个地方:索引和 $MFT 中。在索引中,每一位代表索引分配中的一个 VCN;在 $MFT 中,每一位代表一个文件记录的使用情况。

202111251500915.jpeg

下图为一个 $MFT 自带的 B0H 属性

202111251501301.jpeg

上图中 B0H 属性的 Run List 所描述的数据流,就是 $MFT 的文件记录使用情况表。