前言:最近由于项目需要,研究了一下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属性,因为这个属性记录根目录中所有文件的文件名以及文件记录的位置。如图(再次强调,务必参考文件记录的结构理解图片内容)
根目录的文件记录
由根目录的文件记录的A0H属性的run list :0x31 01 52f909,根据run list的特殊计算方式(具体可参考文末链接)即第一个字节的3代表后三字节为簇偏移量,第一个字节的1代表共一簇。所以记录根文件中所有文件的文件名以及文件记录号的簇偏移位置为0x09f952(ntfs采用小端方式存储数据),共一簇。所以现在偏移到0x09f952簇查看具体内容。如图所示(请务必参考索引节点的数据结构阅读图片):
其中索引节点的数据结构:
- struct 索引节点{
- 索引头;
- 索引项1;
- 索引项2;
- 索引项3;
- ……
- }
由图片可以看出,根目录的索引节点有索引头和一个个索引项构成,其中这一个个索引项和根目录中的每个文件或目录一一对应,这些目录项的文件名就是根目录中文件或目录的名称。我们现在偏移到根目录下目录名为WINDOWS的索引项,如图:
WINDOWS目录的索引项
由WINDOWS索引项的MFT号,即起始的8个字节,可以计算出WINDOWS目录的文件记录号,即ox0000 0000 001c=28,所以WINDOWS目录的文件记录号为28,相对于MFT起始位置偏移28项,0x28*0x400=0x7000。和根目录一样,因为WINDOWS是个目录,所以仍然关注A0H属性,因为此属性记录WINDOWS目录中所有文件或目录的名称和MFT号(文件记录号),WINDOWS目录的文件记录如图:
WINDOWS目录的文件记录,重点关注A0H属性
如上图run list 不止一项,先取第一项0x31 0a a1a606,即WINDOWS目录中一部分文件或目录的索引项信息(包括文件或目录名以及文件或目录的MFT号)在簇偏移为ox06a6a1处,共有0x01簇。
现在偏移到435873簇(0x06a6a1),内容如图,与根目录下的索引项内容类似,可以发现我们要找到DtcInstall.log文件名已经出现。
DtcInstall.log的索引项
从DtcInstall.log索引项中我们可以发现该文件的MFT号为ox15f9,所以该文件的文件记录在MFT的偏移位置为ox15f9*0x400=0x57e400,找到该偏移位置,如图(这个图上面贴过):
该文件记录存储着DtcInstall.log的全部信息,包括文件内容,由于文件内容小,所以80H属性可以容纳全部,所以是常驻属性,否则应该是非常驻属性,而且非常驻属性的最后是run list 指向文件内容的真正簇偏移。
至此,对NTFS文件系统中某个文件的追踪过程全部结束,本文着重解释文件在NTFS文件系统的逻辑关系,对于NTFS文件系统的基础知识不做过多介绍,所以阅读本文前,可以参考文末链接了解NTFS的基础知识。另外,人非圣贤,过程中难免有错误,欢迎批评指正!
参考资料:
联系客服