NTFS文件系统有着非常优秀的特性,其安全性、可靠性都远胜于我们常用的FAT文件系统,但是微软公司出于商业目的没有公布它的规范,使得这种优秀的文件系统只能在Windows NT架构的操作系统中使用。
不过先辈们唱得好:“没有枪没有炮,敌人给我们造!”。不管微软再怎么保密,它自己总要使用NTFS文件系统。那我们就通过分析它的代码来研究NTFS文件系统的规范呐。下面就列出小弟在仔细分析之后制做的Windows 2000 build 2195版格式化的NTFS分区的引导记录的源代码,以此与各位同好共勉。
本代码在MASM 6.11下编译通过。其中与分区结构相关的数据仅适用于在下自己分的分区,各位引用时请自行代入正确的值。
.486
Title NTFS $Boot of Windows 2000 build 2195
Code SEGMENT BYTE PUBLIC USE16 'CODE'
ASSUME CS:Code,DS:Code
NTFS PROC FAR
START: JMP SHORT Loader
DB 90H
PartitionID DB 'NTFS '
BytePerSector DW 512
SectorPerCluster DB 1
SectorNumWanted DW 0
SectorWanted DD 0
SupportExtendInt13Flag DB 0
StorageMedia DB 0F8H
DB 0,0
SectorPerTrack DW 3FH
Heads DW 0FFH
HiddenSector DD 3FH
CHSMaxSectorNum DD 0
CurrentDisk DB 81H
DB 0,8,0
SectorsInPartition DD 3E81FFH
DD 0
MFTPosition DD 0C5A70H
DD 0
MFTMirrPosition DD 1FCD0AH
DD 0
ClusterPerFRS DD 2
DB 08H,0,0,0,0F6H,79H
DB 58H,5CH,0BBH,58H,5CH,0F4H
DB 0,0,0,0
Loader: CLI ; Disable interrupts
XOR AX,AX
MOV SS,AX
MOV SP,7C00H ; Initalize stack
STI ; Enable interrupts
MOV AX,7C0H
MOV DS,AX
CALL GetCHSMaxSectorNum
MOV AX,0D00H
MOV ES,AX
XOR BX,BX
MOV BYTE PTR DS:[SectorNumWanted],10H
CALL ReadSector
PUSH 0D00H
PUSH 26AH
RETF
NTFS ENDP
;-----------------------------------------------------------------------------
GetCHSMaxSectorNum PROC NEAR
MOV DL,DS:[CurrentDisk]
MOV AH,8
INT 13H
JNC Lost
MOV CX,0FFFFH
MOV DH,CL
Lost: MOVZX EAX,DH
INC AX
MOVZX EDX,CL
AND DL,3FH
MUL DX
XCHG CL,CH
SHR CH,6
INC CX
MOVZX ECX,CX
MUL ECX
MOV DS:CHSMaxSectorNum,EAX
RET
GetCHSMaxSectorNum ENDP
;-----------------------------------------------------------------------------
IsSupportExtendInt13 PROC NEAR
MOV AH,41H
MOV BX,55AAH
MOV DL,DS:CurrentDisk
INT 13H ; Is support extend int 13h
JC SHORT NotSupport ; Jump if carry Set
CMP BX,0AA55H
JNE SHORT NotSupport ; Jump if not equal
TEST CL,1
JZ SHORT NotSupport ; Jump if zero
INC BYTE PTR DS:SupportExtendInt13Flag
NotSupport: RET
IsSupportExtendInt13 ENDP
;-----------------------------------------------------------------------------
;Function : read number indicated by [WantedSecotrNum] sectors at [WantedSector] to ES:BX
ReadSector PROC NEAR
PUSHAD ; Save all regs
PUSH DS
PUSH ES
GetReadParam: MOV EAX,DS:[SectorWanted]
ADD EAX,DS:[HiddenSector]
CMP EAX,DS:[CHSMaxSectorNum]
JB NEAR PTR ReadByOldInt13
; Sector number is less than CHSMaxSectorNum , use origin int 13h
PUSH DS
; PUSH DWORD PTR 0
DB 66H,6AH,0
PUSH EAX
PUSH ES
PUSH BX
PUSH DWORD PTR 10010H
CMP BYTE PTR DS:SupportExtendInt13Flag,0
JNE NEAR PTR Supported
CALL IsSupportExtendInt13
CMP BYTE PTR DS:SupportExtendInt13Flag,0
JE NEAR PTR FatalFault
Supported: MOV AH,42H
MOV DL,DS:[CurrentDisk]
PUSH SS
POP DS
MOV SI,SP
INT 13H ; read sector
POP EAX
POP BX
POP ES
POP EAX
POP EAX
POP DS
JMP SHORT OneSectorRead
ReadByOldInt13: XOR EDX,EDX
MOVZX ECX,WORD PTR DS:[SectorPerTrack]
DIV ECX
INC DL
MOV CL,DL
MOV EDX,EAX
SHR EDX,10H
DIV WORD PTR DS:[Heads]
XCHG DL,DH
MOV DL,DS:[CurrentDisk]
MOV CH,AL
SHL AH,6
OR CL,AH ; Build read sector parameters
MOV AX,201H
INT 13H ; Read sector
OneSectorRead: JC NEAR PTR FatalFault ; Read error,shut down
MOV AX,ES
ADD AX,20H
MOV ES,AX
INC DWORD PTR DS:[SectorWanted]
DEC WORD PTR DS:[SectorNumWanted]
JNZ GetReadParam ; Fixup parameters
POP ES
POP DS
POPAD ; Restore all regs
RET
FatalFault:: MOV AL,ReadDiskErrorOffset
ReadSector ENDP
;-----------------------------------------------------------------------------
DispFatalMsg:: CALL PrintString
MOV AL,ShutDownMsgOffset
CALL PrintString ; Display shutdown message
STI ; Enable interrupts
ShutDown: JMP SHORT ShutDown ; Crash
;-----------------------------------------------------------------------------
PrintString PROC NEAR
MOV AH,1
MOV SI,AX
LoadChar: LODSB
CMP AL,0
JZ SHORT PrintStringEnd
MOV AH,0EH
MOV BX,7
INT 10H
JMP SHORT LoadChar
PrintStringEnd: RET
PrintString ENDP
;-----------------------------------------------------------------------------
ReadDiskError DB 0DH, 0AH, 'A disk read error occurred', 0
MissNTLDRError DB 0DH, 0AH, 'NTLDR is missing', 0
NTLDRCompressed DB 0DH, 0AH, 'NTLDR is compressed', 0
ShutDownMsg DB 0DH, 0AH, 'Press Ctrl+Alt+Del to restart',0DH,0AH,0
DB 13 DUP (0)
ReadDiskErrorOffset DB 83H ;OFFSET ReadDiskError
MissNTLDRErrorMsg DB 0A0H ;OFFSET MissNTLDRError
NTLDRComperssedOffset DB 0B3H ;OFFSET NTLDRCompressed
ShutDownMsgOffset DB 0C9H ;OFFSET ShutDownMsg
DB 0, 0
BootValidFlag DW 0AA55H
UnicodeNTLDR DW 5
DB "N",0,"T",0,"L",0,"D",0,"R",0
UnicodeDirectory:
DW 4
DB "S",0,"I",0,"3",0,"0",0
AttributePoint DD 0E000H
MFTPoint DD 3000H
MFTNumber DD 0
TempRootBuffer DD 0
TempDirBuffer DD 0
TempBitmapBuf DD 0
RootAttribute DD 0
DirEntryList DD 0
BitmapAttribute DD 0
TempMFT DD 0
DD 0
TempDataBuf DD 0
BitampPoint DD 0
ParamTailPoint DD 0
BytePerCluster DD 0
MFTSize DD 0
MFTSizeBySector DD 909012EBH
MFTTail DD 0
BytePerRecord DD 0
DATA_46 DD 0
SectorPerRecord DD 0
Booting: MOV AX,CS
MOV DS,AX
SHL AX,4
CLI
MOV SP,AX ; Initalize stack
STI ; Enable interrupts
CALL GetCHSMaxSectorNum
MOVZX EAX,WORD PTR [BytePerSector]
MOVZX EBX,BYTE PTR [SectorPerCluster]
MUL EBX
MOV [BytePerCluster],EAX
MOV ECX,[ClusterPerFRS]
CMP CL,0
JG NEAR PTR IsMFTSize
NEG CL
MOV EAX,1
SHL EAX,CL
JMP SHORT LOC_14
DB 90H
IsMFTSize: MOV EAX,BytePerCluster
MUL ECX
LOC_14: MOV [MFTSize],EAX
MOVZX EBX,WORD PTR [BytePerSector]
XOR EDX,EDX
DIV EBX
MOV [MFTSizeBySector],EAX ; Count sector number occurpied by MFT
CALL FindLastMFT
MOV ECX,[ParamTailPoint]
MOV [TempRootBuffer],ECX
ADD ECX,[MFTSize]
MOV [TempDirBuffer],ECX
ADD ECX,[MFTSize]
MOV [TempBitmapBuf],ECX
ADD ECX,[MFTSize]
MOV [TempMFT],ECX
ADD ECX,[MFTSize]
MOV [TempDataBuf],ECX
MOV EAX,90H
MOV ECX,[TempRootBuffer]
CALL GetAttributePos
OR EAX,EAX
JZ FatalFault
MOV [RootAttribute],EAX
MOV EAX,0A0H
MOV ECX,[TempDirBuffer]
CALL GetAttributePos
MOV [DirEnt