职称论文发表_见刊快,可查稿!论文快速发表网

2020-06-04 14:01【计算机论文发表范文】探索NTFS

NTFS是WindowsNT引入的新型文件系统,它具有许多新特性。本文旨在探索NTFS的底层结构,所叙述的也仅是文件在NTFS卷上的分布。NTFS中,卷中所有存放的数据均在一个叫$MFT的文件中,叫主文件表(MasterFileTable)。而$MFT则由文件记录(FileRecord)数组构成。FileRecord的大小一般是固定的,通常情况下均为1KB,这个概念相当于Linux中的inode。FileRecord在$MFT文件中物理上是连续的,且从0开始编号。$MFT仅供FileSystem本身组织、架构文件系统使用,这在NTFS中称为元数据(Metadata)。以下列出Windows2000Release出的NTFS的元数据文件(我将要给出的示例代码的部分输出结果)。
FileRecord(inode)FileName
--------------------------
0$MFT
1$MFTMirr
2$LogFile
3$Volume
4$AttrDef
5.
6$Bitmap
7$Boot
8$BadClus
9$Secure
10$UpCase
11$Extend

Windows2000中不能使用dir命令(甚至加上/ah参数)像普通文件一样列出这些元数据文件。实际上FileSystemDriver(ntfs.sys)维护了一个系统变量NtfsProtectSystemFiles用于隐藏这些元数据。默认情况下,这个变量被设为TRUE,所以使用dir/ah将得不到任何文件。知道这个行为后使用i386kd修改NtfsProtectSystemFiles后即可以列出元数据文件:

kd>xntfs!NtfsProtect*
fe213498Ntfs!NtfsProtectSystemFiles
fe21349cNtfs!NtfsProtectSystemAttributes
kd>ddntfs!NtfsProtectSystemFilesl2
fe2134980000000100000001
kd>edntfs!NtfsProtectSystemFiles0
kd>ddntfs!NtfsProtectSystemFilesl2
fe2134980000000000000001
kd>

D:>ver

MicrosoftWindows2000[Version5.00.2195]

D:>dir/ah$*
驱动器D中的卷是W2KNTFS
卷的序列号是E831-9D04

D:的目录

2000-04-2719:3136,000$AttrDef
2000-04-2719:310$BadClus
2000-04-2719:3167,336$Bitmap
2000-04-2719:318,192$Boot
2000-04-2719:31<DIR>$Extend
2000-04-2719:3113,139,968$LogFile
2000-04-2719:3127,575,296$MFT
2000-04-2719:314,096$MFTMirr
2000-04-2719:31131,072$UpCase
2000-04-2719:310$Volume
9个文件40,961,960字节
1个目录51,863,552可用字节

需要指出的是ntfs.sys将元数据文件以一种特殊的方式打开,所以在打开NtfsProtectSystemFiles后,如果使用ReadFile等产生IRP_MJ_READ等IRP包时将会导致PageFault(详见GaryNebbett的《WindowsNT/2000NativeAPIReference》)。

以上的讨论均是基于$MFT文件而讨论的,即基于$MFT中的FileRecord(inode)讨论的。为更好的继续以下的讨论,这儿我列出FileRecordHeader的结构:

typedefstruct{
ULONGType;
USHORTUsaOffset;
USHORTUsaCount;
USNUsn;
}NTFS_RECORD_HEADER,*PNTFS_RECORD_HEADER;

typedefstruct{
NTFS_RECORD_HEADERNtfs;
USHORTSequenceNumber;
USHORTLinkCount;
USHORTAttributesOffset;
USHORTFlags;//0x0001=InUse,0x0002=Directory
ULONGBytesInUse;
ULONGBytesAllocated;
ULONGLONGBaseFileRecord;
USHORTNextAttributeNumber;
}FILE_RECORD_HEADER,*PFILE_RECORD_HEADER;

下面我将讨论如何定位$MFT。稍微有点操作系统知识的人都会知道引导扇区(BootSector),其物理位置为卷中的第一个扇区。以下由dskprobe.exe(Windows2000ResourceKit中的一个小工具)分析的第一个扇区(当然也可以使用WinHex等其他应用程序):

File:d:Sector00.bin
Size:0x00000200(512)

Address|00010203-04050607:08090A0B-0C0D0E0F|0123456789ABCDEF
---------|-------------------------:-------------------------|-----------------
00000000|EB52904E-54465320:20202000-02080000|?R?NTFS.....
00000010|00000000-00F80000:3F00F000-3F000000|.....?..?.e.?...
00000020|00000000-80008000:90C04100-00000000|....?.?.惱A.....
00000030|04000000-00000000:091C0400-00000000|................
00000040|F6000000-01000000:049D31E8-BB31E894|?.......?杌1钄
..
..
..
000001F0|00000000-00000000:83A0B3C9-000055AA|........儬成..U?



这512字节为如下的格式:(摘自GaryNebbett书中,本文许多代码均来自或参考此书。)

#pragmapack(push,1)

typedefstruct{
UCHARJump[3];
UCHARFormat[8];
USHORTBytesPerSector;
UCHARSectorsPerCluster;
USHORTBootSectors;
UCHARMbz1;
USHORTMbz2;
USHORTReserved1;
UCHARMediaType;
USHORTMbz3;
USHORTSectorsPerTrack;
USHORTNumberOfHeads;
ULONGPartitionOffset;
ULONGReserved2[2];
ULONGLONGTotalSectors;
ULONGLONGMftStartLcn;
ULONGLONGMft2StartLcn;
ULONGClustersPerFileRecord;
ULONGClustersPerIndexBlock;
ULONGLONGVolumeSerialNumber;
UCHARCode[0x1AE];
USHORTBootSignature;
}BOOT_BLOCK,*PBOOT_BLOCK;

#pragmapack(pop)

各个字段的详细意义从字段名中即可大致清楚。在linux-ntfs的GNU工程(http://sf.net/projects/linux-ntfs)中也有详细的文档,限于篇幅我不将其列出。可以使用如下代码读出卷中的第一个扇区:


hVolume=CreateFile(drive,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,0,
OPEN_EXISTING,0,0);

ReadFile(hVolume,&bootb,sizeof(bootb),&n,0);

bootb是一个BOOT_BLOCK结构,在我的卷中如下格式(请对应Sector00.bin分析):

DumpBootBlockatbelow:
BytesPerSector:200
SectorsPerCluster:8
BootSectors:0
SectorsPerTrack:3F
NumberOfHeads:F0
PartitionOffset:3F
TotalSectors:41C090
MftStartLcn:4
Mft2StartLcn:41C09
ClustersPerFileRecord:F6
ClustersPerIndexBlock:1
VolumeSerialNumber:E8319D04
BootSignature:AA55


以上的MftStartLcn其实是$MFT在卷中的簇(Cluster)号。簇是NTFS的基本单位,最小单位。一个只有1Byte的文件也要占用一簇的空间。NTFS使用LCN(LogicalClusterNumber)来代表NTFS卷中的物理位置,其简单的从0到卷中的总簇数减一进行编号。对于一个特定的文件NTFS则使用VCN(VirtualClusterNumber)来映射LCN实现文件的组织。从MftStartLcn的值4可以知道$MFT的LCN为4与SectorsPerCluster、BytesPerSector的大小即可定位$MFT的位置。得到$MFT的位置后,如果遍历$MFT中所有的FileRecord即可以得到卷中所有的文件列表(前面已经提到FileRecord只是简单的从0开始编号)。也就是说到目前为止已经可以对文件组织有最简单的认识,但如何得到文件的信息呢,如文件名等等。NTFS中所有文件包括普通的用户文件、元数据文件均用同样的方式组织数据、属性等。我将nfi.exe(来自WindowsNT/2000OEMSupportTools)的输出结果列出,作为我叙述的开始:

D:>copyconfile
testforntfs^Z
已复制1个文件。

D:>nfid:file
NTFSFileSectorInformationUtility.
Copyright(C)MicrosoftCorporation1999.Allrightsreserved.

[1][2]下一页


论文快速发表网 www.lwksfb.cn 诚实守信,有始有终,是您职称评定的不二之选!

13121212186 13121212186 微信扫一扫,添加好友 →