问题分析
在NTFS文件系统中,每一个文件或目录都拥有一个MFT记录,MFT记录中记录了文件或目录的基本信息,对于普通文件来说,一般拥有文件序号,文件名,创建时间,文件大小,文件属性,文件数据地址索引等基本文件信息,而一个目录除了拥有基本文件信息,还拥有其目录下的文件索引项信息,文件与其父目录之间通过该文件的MFT记录中的父目录信息和目录中的索引项来建立隶属关系,这两种信息唯一地确定了文件与父目录之间的对应关系,由此可知,要在一个指定目录下生成一个文件,除了要创建目标文件本身的MFT记录,还需在其父目录的MFT记录或者其索引分配中建立目标文件的索引。在NTFS系统中,文件索引是一个比较复杂的内容,文件的索引采用了树型结构,这给NTFS系统带来了查找文件速度快的优点,但却给当索引结点增加或减少时,如何维护树的平衡带来了难题。在NTFS系统中,小目录的索引直接存放在目录本身MFT记录的90H属性中,而大目录的索引则需另外开辟新的索引分配区来存放相关的索引。原程序中只考虑了小目录的情况,即将文件的索引直接存放在90H属性中,并不考虑大目录的索引情况。除此之外,NTFS系统对于每一个文件操作都会写入日志文件中,以便一致性检查,但由于这方面的内容尚未研究清楚,本程序中也未涉及这方面的内容。
流程图
程序实现的基本步骤
首先使用十六进制编辑工具(如Hexshop)读取目标文件的二进制内容,将其复制出来粘贴在一个文本文档中,再使用一个小工具changesrc.exe将其转化为汇编代码中的字符串形式,将这些字符串内嵌在汇编代码中,如图1.1到图1.5所示
(1)如要将一个exe文件survior.exe的内容复制,首先用Hex Workshop打开这个文件,这里只取出部分图作为示范
图1.1
(2)将其全选,复制,粘贴到文件文档中
图1.2
(3)使用小工具changesrc.exe,将其进行转换
图1.3
(4)转换后的结果,如图1.4所示,由于那个小工具有点小问题,注意要把最后的“,0”去掉
图1.4
图1.5
(5)将这些代码拷贝进汇编代码中
通过BPB参数(磁盘的第63个扇区的内容)获得几个重要的元文件信息,分别为$MFT,$Bitmap文件的MFT记录所在的扇区地址,可以通过程序实现得到这些信息,这样更为灵活一些,通用性更强一些,也可通过WinHex来直接得到这些信息,然后将这些信息固定在汇编代码中,这样的通用性会稍差,对于不同的机器可能无法适用同一个程序。
使用WinHex来得到这几个文件的扇区地址的方法:
用WinHex打开一个NTFS格式的分区,如C盘,可以看到我们所需要的那几个文件的起始地址,在“1st sector”这一列中已经标出,但是这个地址并不是我们最终需要的地址,因为这个地址只是一个相对地址,C盘的开始扇区并不是从0开始的,而是从63扇区(对于一些C盘前面有隐藏分区的电脑来说,可能不是63,可用WinHex进行查看)开始,所以要得到文件的绝对扇区地址还要再加上63
图2.1
如$Bitmap文件的起始地址,图中标出是4325932,其绝对地址应该是4325932+63=4325995,
可用WinHex确定C盘的绝对起始扇区地址是63,如图2.2所示
图2.2
如果要使用程序实现得到这几个文件的扇区地址,步骤如下:
(1)首先确定NTFS分区每个簇所占扇区数,在分区第一个扇区(这里是指相对地址,即绝对地址为63)中0x0D处,一个字节。
(2)确定$MFT的首簇地址:在分区第一个扇区中0x30处,8个字节,如图2.3所示
图2.3
如红线框中所示,地址为04H,这里是簇号,要转换成扇区,一个簇有8个扇区,即扇区地址为4*8=32,还要再加上63来得到绝对扇区地址,即32+63=95,这个才是$MFT文件的绝对扇区地址,$MFT:Bitmap的地址在$MFT中的B0h属性中有表示
图2.4
跳过40h(这里是十六进制数)的属性头,如红框中表示,第一个字节的低位部分是代表前面一个字节表示连续的簇的个数,高位部分则表示前面第二个字节代表起始地址,如图中所示的“02”,后面还可以看到“31 01 59 73 26”,这些表示$MFT:Bitmap的分布非常零散,有碎片,由前面的“02”我们可以知道$MFT:Bitmap的起始地址就是2*8+63=79
(3)计算$Bitmap的扇区地址,将前两步结果相乘得$MFT首扇区,加上12(因为$MFT为第0个文件,$Bitmap为第六个文件,每个MFT记录一般占2个扇区)。
(4)读取$Bitmap位置处两个扇区。
(5)从这两个扇区0x30处开始找80属性:读8个字节,前四个为属性,如果小于80继续,后四个为此属性所占字节,一直到找到80属性。(30属性是文件名,正好确定此文件是