简介
NTFS(New Technology File System),是微软开发的专用文件系统,从windows NT 3.1(在1993年发布)开始成为windows NT家族的标准文件系统。
NTFS替换了FAT(文件分配表)和HPFS(高性能文件系统)并进行了一系列改进,例如增强了对元数据的支持,使用了更高级的数据结构以提升性能、可靠性和磁盘空间利用率,并附带了一些列增强功能,如访问控制列表(ACL)和文件系统日志(该功能非常强大,能够检测每个文件以及目录的变化)。
版本
微软正式发布的NTFS版本有五个:
- v1.0随着windows NT 3.1在1993年中旬发布。v1.0和v1.1和之后的所有版本不兼容,也即使用NT3.5x写入的卷无法被NT 3.1读取。
- v1.1,随windows NT 3.5域1994年秋季发布。
- v1.2,随windows NT 3.51于1995年中旬发布。支持压缩文件、命名流、基于ACL(访问控制表)的安全性等功能。
- v3.0,随windows 2000发布。支持磁盘限额、加密、稀疏文件、重解析点,更新序列(USN)日志、$Extend文件夹(及其中的文件),并改进安全描述符设计方案,允许使用同样的安全设置的多个文件共享一个安全描述符。
- v3.1随windows XP与2001年秋季发布,而后也用于Windows Vista和Windows 7。在MFT中提供冗余MFT记录数扩展项。
这里提到NTFS的版本,不同版本的NTFS在数据结构中也是有差距的,所以在考虑利用NTFS做一些东西的时候,需要考虑版本问题。其他详细介绍可以参考wikipedia。
结构
NTFS磁盘主要布局如下图所示:
对于某个NTFS卷,则布局基本上和上面是一致的,开始是$BOOT文件,紧接着是一些元文件,在接着是用户数据文件。NTFS有个重要的概念,即一切都是文件。为了了解NTFS的设计,一切重要的数据都被分配为文件。这包括其他文件系统通常隐藏起来的基本的文件系统管理数据。事实上,包含管理数据的文件可以保存在卷的任何位置,和普通文件一样。也就是说,NTFS文件系统并不像其他文件系统那样有个特定的布局。整个文件系统被认为是一个数据区,每个扇区都可以分配给一个文件。唯一不变的布局是每一个卷开始的几个扇区,包含有引导扇区和引导代码。
下面介绍各个数据结构的内容。在介绍字段含义之前,推荐两个工具Disk Editor和WinHex,这两个工具都有对应的模板可以查看磁盘具体的格式。后面我都是用Disk Editor来查看磁盘内容的。
引导扇区 $Boot
| 字节偏移 | 字段长度 | 字段含义 | 描述 |
|---|---|---|---|
| 0x00 | 3 | JMP指令 | 用于命令处理器继续执行引导扇区后的内容 |
| 0x03 | 8 | OEM标示 | 用于标记当前分区使用NTFS文件系统 |
| 0x0B | 2 | 每个扇区字节数 | 说明每个扇区的字节数 |
| 0x0D | 1 | 每簇扇区数 | 说明每个簇包含的扇区数 |
| 0x0E | 2 | 保留扇区数 | 被操作系统保留的扇区数 |
| 0x10 | 3 | 未使用 | 始终为零 |
| 0x13 | 2 | 未使用 | 始终为零 |
| 0x15 | 1 | 介质描述符 | 未知 |
| 0x16 | 2 | 未使用 | 始终为零 |
| 0x18 | 2 | 每个磁道扇区数 | 说明每个磁道扇区数 |
| 0x1A | 2 | 磁头数 | 该驱动器包含的读写磁头数 |
| 0x1C | 4 | 隐藏扇区数 | 隐藏扇区数目,参考文献中未说明隐藏扇区位置 |
| 0x20 | 4 | 未使用 | 始终为零 |
| 0x24 | 4 | 未使用 | 始终为零 |
| 0x28 | 8 | 总扇区数 | 该分区包含的总扇区数目 |
| 0x30 | 8 | $MFT簇编号 | $MFT所在的簇的编号 |
| 0x38 | 8 | $MFTMirr | $MFT镜像(备份)所在的簇的编号 |
| 0x40 | 1 | 文件记录段字节数 | 每个File Entry包含的字节数。 |
| 0x41 | 3 | 未使用 | 始终为零 |
| 0x44 | 1 | 索引缓冲簇数 | 每个索引缓冲占据的簇数 |
| 0x45 | 3 | 未使用 | 始终为零 |
| 0x48 | 8 | 卷序列数 | 用于确保内容一致性 |
| 0x50 | 4 | 检验和 | 表中所有项目中的检验和,未知算法 |
| 0x54 | 426 | 启动指令 | 用于加载操作系统其他部分的指令码,该字段未知正是引导扇区前三个字节指向的位置 |
| 0x1FE | 2 | 扇区结束标记 | 该字段用于标记一个扇区的结束 |
以上就是$Boot引导扇区的数据结构,其中有以下几个参数需要重点关注:
- 0x00,对于NTFS磁盘,该处是字符串”NTFS“
- 0x0B,每个扇区字节数,一般512字节
- 0x0D,每个簇包含的扇区数,一般为8
- 0x30,$MFT所在的簇编号
- 0x38,$MFT镜像备份的簇编号,为了防止$MFT损坏的情况
- 0x40,File Entry占用的字节数,该字段是带符号数,例如,该字段为0xF6,即以带符号补码形式,补码换算一下为-10,而计算方式是2^-(-10)=1024字节,占用两个扇区
- 0x1FE,扇区结束符 FFFF
通过0x30位置,我们可以找到$MFT结构,$MFT是描述卷上的所有文件,是介绍其本身,后续会通过其数据结构来解释其具体的作用。下面介绍$BOOT后的元文件。
主文件表(MFT)
在NTFS中,所有文件数据–文件名称、创建日期、访问权限,以及内容–都作为元数据存储在主文件表中。这种抽象的实现方式能够大大简化为文件系统添加功能的成本。
MFT结构支持最小化磁盘碎片的算法。一个目录项同时包含“文件名”和“文件ID”,后者是用于在主文件表中表示文件的记录编号。文件ID也包含“重用次数”信息,可用于检测对文件的过期引用。
元文件
NTFS是包含若干用于定义和阻止文件系统的文件。这些文件中的绝大多数结构和其他用户文件类似(只有$Volume比较特殊),但不能被文件系统客户端直接访问。这些元文件定义文件、备份文件系统的关键数据、缓存文件系统的更改、管理空闲空间的分配、满足BIOS的要求、跟踪坏扇区单元,以及存储安全信息和此按空间使用情况等等多种不同需求提供支持。
| 区段编号 | 文件名 | 作用 |
|---|---|---|
| 0 | $MFT | 描述卷上的所有文件,包括文件名、时间戳、流名称和数据流所在的簇编号列表、索引、安全标示符,以及文件属性 |
| 1 | $MFTMirr | $MFT的最开始截个关键项的副本,通常4项,作为副本保存在其他地方 |
| 2 | $LogFile | 文件系统更改的事物日志,用于保护元数据的稳定性 |
| 3 | $Volume | 卷的相关信息,如卷对象标示符、卷标、文件系统版本,以及若干卷标志。这些数据不直接在数据流中存储,而是存储于特殊的MFT属性中。如果卷对象标示符存在,则将会在一个$OJBECT_ID记录中,卷存储在$VOLUME_NAME记录中,其他数据存储在$VOLUME_INFORMATION记录中,卷序列号存储在$BOOT文件中 |
| 4 | $AttrDef | 所有NTFS项目使用到的属性的定义表,包含属性名称、属性编号和属性描述等 |
| 5 | . | 根目录。目录数据存储在两个名称均未$I30的$INDEX_ROOT和$INDEX_ALLOCATION属性中 |
| 6 | $Bitmap | 一个位图,每一位按顺序指示卷上的对应簇正在被使用(1)或空闲(0) |
| 7 | $Boot | 卷引导记录,该文件始终位于卷的第一个簇,其中包含引导代码(用于定位并启动NTLDR/BOOTMGR)、BIOS参数块(其中包含卷序列号),以及$MFT和$MFTMirr所在的簇编号 |
| 8 | $BadClus | 包含所有标记为“有坏扇区”的簇的一个文件。该文件通常被chksdk(磁盘扫描)工具使用,用于管理所有簇状态,记录坏扇区,以及标记空白簇。该文件包含两个数据流(无论卷是否有坏到):一个包含所有坏扇区编号的无名称流(如果卷没有坏扇区则该流长度为零),以及名称为$Bad的流,包含所有包含记录在第一个流中的簇 |
| 9 | $Secure | 访问控制列表数据库,NTFS将所有ACL信息几种存储于该数据库(而非每个文件独立存储鸽子的ACL)以节省磁盘占用并提高执行效率。此部分包含两个索引,分别是:“¥SII”–可能是安全ID索引,以及“SDH”–安全描述符哈希。注意大部分ACL列表通常都很长,因此这个部分知识索引,记录的是实际存储ACL数据的$SDS流的位置 |
| 10 | $UpCase | Unicode大写字母表,用于确保在Win32和DOS命名空间下大小写不敏感 |
| 11 | $Extend | 文件系统目录,用于包含若干操作系统或其他软件所需要的扩展数据,如$Quota、$ObjId、$Reparse、$UsnJrnl等 |
| 12-23 | 保留,为了以后扩展 | |
| 24 | $Extend\$Quota | 磁盘限额设置 |
| 25 | $Extend\$ObjId | 分布链接跟踪数据。包含一个索引根目录,名称为$0 |
| 26 | $Extend\$Reparse | 卷上所有重解析点数据。包含一个索引根目录,名称为$R |
| 27 | file.ext | 常规文件系统项目的起始位置 |
以上是所有元文件,其中需要重点关注的几个元文件如下所示:
- $MFT:里面包含整个磁盘中所有File Entry的信息,比如File Entry的总数(包含已经删除的File Entry)
- .:根目录,通过它以及其中的相关属性,我们可以遍历NTFS的整个目录
- $Bitmap:每一位标识File Entry是否在使用
参考
http://www.cnblogs.com/skogkatt/p/4246783.html
https://zh.wikipedia.org/zh-cn/NTFS
整理的比较辛苦,如果本文对你有用,请留下你来过的痕迹,转载请注明出处! 2016年8月4号于北京 https://soygrow.github.io