发新话题
打印

[转载]NTFS分区的引导记录源码

[转载]NTFS分区的引导记录源码

题 目: NTFS分区的引导记录源码
类 型: 原创
作 者: 易水
来 源: 易水的编程网
引用:
  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 [DirEntryList],EAX
          MOV EAX,0B0H
          MOV ECX,[TempBitmapBuf]
          CALL GetAttributePos
          MOV [BitmapAttribute],EAX
          MOV EAX,[RootAttribute]
          OR EAX,EAX
          JZ FatalFault ;           Check if root is exist
          CMP BYTE PTR           [EAX+8],0               ; Nonresident, error record!
          JNE FatalFault
          LEA EDX,DWORD           PTR [EAX+10H]
          ADD AX,WORD           PTR [EDX+4]
          MOVZX ECX,BYTE           PTR [EAX+0CH]
          MOV [DATA_46],ECX
          MOV ECX,DWORD           PTR [EAX+8]
          MOV [BytePerRecord],ECX
          MOV EAX,[BytePerRecord]
          MOVZX ECX,WORD           PTR [BytePerSector]
          XOR EDX,EDX
          DIV ECX
          MOV [SectorPerRecord],EAX
          MOV EAX,[TempDataBuf]
          ADD EAX,[BytePerRecord]
          MOV [BitampPoint],EAX
          CMP [DirEntryList],0
          JE NEAR PTR           LookForNTLDR
          CMP [BitmapAttribute],0
          JE FatalFault
          MOV EBX,[BitmapAttribute]
          PUSH DS
          POP ES
          MOV EDI,[BitampPoint]
          CALL GetAttributeData
         
          LookForNTLDR: MOVZX               ECX,WORD           PTR [UnicodeNTLDR]
          MOV EAX,OFFSET           [UnicodeNTLDR+2]
          CALL SearchFileInRoot ;           Look for NTLDR in root
          OR EAX,EAX
          JZ MissNTLDR ; Can't           find NTLDR
          MOV EAX,[EAX]
          PUSH DS
          POP ES
          MOV EDI,[TempMFT]
          CALL LoadMFTNode
          MOV EAX,[TempMFT]
          MOV EBX,80H
          MOV ECX,0
          MOV EDX,0
          CALL SearchAttribute
          OR EAX,EAX
          JNZ NEAR PTR           LoadNTLDR
          MOV ECX,80H
          MOV EAX,[TempMFT]
          CALL SearchAttributeEx
          OR EAX,EAX
          JZ MissNTLDR ; Can't           find NTLDR
          PUSH DS
          POP ES
          MOV EDI,[TempMFT]
          CALL LoadMFTNode
          MOV EAX,[TempMFT]
          MOV EBX,80H
          MOV ECX,0
          MOV EDX,0
          CALL SearchAttribute
          OR EAX,EAX
          JZ MissNTLDR ; Can't           Find NTLDR
         
          LoadNTLDR: MOVZX               EBX,WORD           PTR [EAX+0CH]
          AND EBX,0FFH
          JNZ CompressedNTLDR
          MOV EBX,EAX
          PUSH 2000H
          POP ES
          SUB EDI,EDI
          CALL GetAttributeData ;           Load NTLDR
          MOV DL,CurrentDisk
          MOV AX,3E8H
          MOV ES,AX
          LEA SI,CS:[0BH]
          SUB AX,AX
          PUSH 2000H
          PUSH AX
          RETF ; Jump to NTLDR           to run
          ;------------------------------------------------------          ; Function : read some clusters indicated by  EDX at the cluster indicated           ;by EAX to buffer indicated by ES:EDI
          ; ArgIn : EAX cluster offset, EDX cluster number,ES:EDI point           ;to buffer to store data
          ReadCluster PROC NEAR
          PUSH ES
          PUSH DS
          PUSHAD
          MOV EBX,EDX
          MOVZX ECX,BYTE           PTR [SectorPerCluster]
          MUL ECX
          MOV [SectorWanted],EAX
          MOV EAX,EBX
          MUL ECX
          MOV WORD PTR           DS:[SectorNumWanted],AX
          MOV BX,DI
          AND BX,0FH
          MOV AX,ES
          SHR EDI,4
          ADD AX,DI
          PUSH AX
          POP ES ;           Calculate buffer address
          CALL ReadSector
          POPAD
          NOP
          POP DS
          POP ES
          RET
          ReadCluster ENDP
          ;--------------------------------------------------          ; Look for a attribute item at buffer indicated           by DS:EAX
          ; Name of attribute indicated by ES:EDI size           is indicated by ECX
          SearchAttribute PROC NEAR
          ADD AX,WORD           PTR [EAX+14H]
         
          Searching: CMP               DWORD PTR [EAX],0FFFFFFFFH      ; Is chain tail?
          JE NEAR PTR           RecordIsNotExist ; Yes return
          CMP [EAX],EBX
          JNE NEAR PTR           ToNextAttribute
          OR ECX,ECX
          JNZ NEAR PTR           HaveName
          CMP BYTE PTR           [EAX+9],0               ; Have name?
          JNE NEAR PTR           ToNextAttribute
          RET
         
          HaveName: CMP               CL,BYTE           PTR [EAX+9]
          JNE NEAR PTR           ToNextAttribute ; Jump if not equal
          MOV ESI,EAX
          ADD SI,WORD           PTR [EAX+0AH]
          CALL LowerCase2UpperCase
          PUSH ECX
          PUSH DS
          POP ES
          MOV EDI,EDX
          REPZ CMPSW ; names           of them is equal ?
          POP ECX
          JNZ NEAR PTR           ToNextAttribute
          RET
         
          ToNextAttribute:
          CMP DWORD           PTR [EAX+4],0
          JE NEAR PTR           RecordIsNotExist
          ADD EAX,DWORD           PTR [EAX+4]
          JMP SHORT           Searching
         
          RecordIsNotExist:
          SUB EAX,EAX
          RET
          SearchAttribute ENDP
          ;----------------------------------------------------          ; Function : Look for a file in directory named    as buffer indicated by EBX
          ; ArgOut : EAX The file record
          SearchFile PROC NEAR
          MOV ESI,EBX
          CALL LowerCase2UpperCase
          ADD EAX,[EAX]
         
          SearchingFile: TEST               WORD PTR [EAX+0CH],2
          JNZ NEAR PTR           FileNotFound
          LEA EDX,DWORD           PTR [EAX+10H]
          CMP CL,BYTE           PTR [EDX+40H]
          JNE NEAR PTR           SearchNextFile
          LEA ESI,DWORD           PTR [EDX+42H]
          CALL LowerCase2UpperCase
          PUSH ECX
          PUSH DS
          POP ES
          MOV EDI,EBX
          REPZ CMPSW
          POP ECX
          JNZ NEAR PTR           SearchNextFile
          RET
         
          SearchNextFile: CMP               WORD PTR [EAX+8],0
          JE NEAR PTR           FileNotFound
          ADD AX,WORD           PTR [EAX+8]
          JMP SHORT           SearchingFile
         
          FileNotFound: XOR               EAX,EAX
          RET
          SearchFile ENDP
          ;-------------------------------------------------          ; Function : Copy attribute data to buffer indicated  by ES:EDI
          ; ArgIn : EBX point to attribute item, ES:EDI    buffer to store attribute data
          ; ArgOut :
          GetAttributeData PROC NEAR
          CMP BYTE PTR           [EBX+8],0
          JNE NEAR PTR           DataForRun
         
          PUSH ES
          PUSH DS
          PUSHAD ; Save all           regs
          LEA EDX,DWORD           PTR [EBX+10H]
          MOV ECX,[EDX]               ; Get resident data length
          MOV ESI,EBX
          ADD SI,WORD           PTR [EDX+4]               ; Get resident data offset
          REP MOVSB ; Copying
          POPAD ; Restore           all regs
          NOP
          POP DS
          POP ES
          RET
         
          DataForRun: LEA               EDX,DWORD           PTR [EBX+10H]
          MOV ECX,DWORD           PTR [EDX+8]               ; Get the last VCN Segment
          INC ECX
          SUB EAX,EAX
          CALL ReadRunDataByClusterOffset ;           Read data in runs
          RET
          GetAttributeData ENDP
          ;--------------------------------------------------          ; Function : Read noresident data in attribute  item
          ; ArgIn : EAX cluster offset in file
          ; ArgIn : EBX point to noresident attribute   item,ES:EDI buffer to store noresident data
          ; ArgOut : None
          ReadRunDataByClusterOffset PROC NEAR
          PUSH ES
          PUSH DS
          PUSHAD ; Save all           regs
          CMP BYTE PTR           [EBX+8],1
          JE NEAR PTR           IsDataForRun
          JMP FatalFault ;           Invalid description
         
          IsDataForRun: CMP               ECX,0
          JNE NEAR PTR           ReadingRunningData
          POPAD ; Read complete
          NOP
          POP DS
          POP ES
          RET
         
          ReadingRunningData:
          PUSH EBX
          PUSH EAX
          PUSH ECX
          PUSH EDI
          PUSH ES
          CALL GetStreamPos
          MOV EDX,ECX
          POP ES
          POP EDI
          POP ECX
          CMP ECX,EDX
          JGE NEAR PTR           ReadRunClusters
          MOV EDX,ECX
         
          ReadRunClusters:
          CALL ReadCluster
          SUB ECX,EDX
          MOV EBX,EDX
          MOV EAX,EDX
          MOVZX EDX,BYTE           PTR [SectorPerCluster]
          MUL EDX
          MOVZX EDX,WORD           PTR [BytePerSector]
          MUL EDX
          ADD EDI,EAX               ; Fixup Buffer point
          POP EAX
          ADD EAX,EBX               ; Fixup cluster
          POP EBX
          JMP SHORT           IsDataForRun
          ReadRunDataByClusterOffset ENDP
          ;-------------------------------------------------          ; Function : Read some data to ES:EDI
          ; ArgIn : EBX point to a run data, ES:EDI point  to the buffer, EAX file offset sector index
          ; AgrIn : ECX sector count
          ReadRunDataBySectorOffset PROC NEAR
          PUSH ES
          PUSH DS
          PUSHAD ; Save all           regs
          CMP BYTE PTR           [EBX+8],1
          JE NEAR PTR           PrepairReadData
          JMP FatalFault
         
          PrepairReadData:
          CMP ECX,0
          JNE NEAR PTR           ReadingRunningData
          POPAD ; Restore           all regs
          NOP
          POP DS
          POP ES
          RET
         
          ReadingRunningData:
          PUSH EBX
          PUSH EAX
          PUSH ECX
          PUSH EDI
          PUSH ES
          PUSH ECX
          XOR EDX,EDX
          MOVZX ECX,BYTE           PTR [SectorPerCluster]
          DIV ECX               ; Calculate cluster number
          PUSH EDX
          CALL GetStreamPos
          MOVZX EBX,BYTE           PTR [SectorPerCluster]
          MUL EBX
          POP EDX
          ADD EAX,EDX
          PUSH EAX
          MOVZX EAX,BYTE           PTR [SectorPerCluster]
          MUL ECX               
          ; Calculate the sector offset and sector number           of the data wanted read
          MOV EDX,EAX
          POP EAX
          POP ECX
          POP ES
          POP EDI
          POP ECX
          CMP ECX,EDX
          JGE NEAR PTR           ReadRunningClusters
          MOV EDX,ECX               ; Fixup the sector number will be read
         
          ReadRunningClusters:
          MOV [SectorWanted],EAX
          MOV WORD PTR           DS:[SectorNumWanted],DX
          PUSH ES
          PUSH DS
          PUSHAD
          MOV BX,DI
          AND BX,0FH
          MOV AX,ES
          SHR EDI,4
          ADD AX,DI
          PUSH AX
          POP ES
          CALL ReadSector
          POPAD
          NOP
          POP DS
          POP ES
          SUB ECX,EDX
          MOV EBX,EDX
          MOV EAX,EDX
          MOVZX EDX,WORD           PTR [BytePerSector]
          MUL EDX
          ADD EDI,EAX               ; Fixup buffer point
          POP EAX
          ADD EAX,EBX
          POP EBX
          JMP PrepairReadData
          ReadRunDataBySectorOffset ENDP
          ;----------------------------------------------          ; Function : Fixup record
          ; ArgIn : ES:EDI point to the record
          ; ArgOut : None
          FixupRecord PROC NEAR
          PUSH ES
          PUSH DS
          PUSHAD ; Save all           regs
         
          MOVZX EBX,WORD           PTR ES:[EDI+4]
          MOVZX ECX,WORD           PTR ES:[EDI+6]
          OR ECX,ECX
          JZ FatalFault
          ADD EBX,EDI
          ADD EBX,2
          ADD EDI,1FEH
          DEC ECX
         
          FixupingRecord: OR               ECX,ECX
          JZ NEAR PTR           FixupRecordComplete
          MOV AX,ES:[EBX]
          MOV ES:[EDI],AX
          ADD EBX,2
          ADD EDI,200H
          DEC ECX
          JMP SHORT           FixupingRecord
         
          FixupRecordComplete:
          POPAD ; Restore           all regs
          NOP
          POP DS
          POP ES
          RET
          FixupRecord ENDP
          ;--------------------------------------------------          ; Function : Get MFT record number occupide           by MFT description
          ; ArgIn : None
          ; ArgOut : None
          FindLastMFT PROC NEAR
          PUSH ES
          PUSH DS
          PUSHAD ; Save all           regs
          MOV EAX,1
          MOV [MFTNumber],EAX
          MOV EAX,[MFTPoint]
          ADD EAX,[MFTSize]
          MOV [MFTTail],EAX
          ADD EAX,[MFTSize]
          MOV [ParamTailPoint],EAX
          MOV EAX,[MFTPosition]
          MOVZX EBX,BYTE           PTR [SectorPerCluster]
          MUL EBX               
          MOV EBX,[ParamTailPoint]
          MOV [BX],EAX
          MOV [SectorWanted],EAX
          ;-------------------------------------------------
          ADD BX,4
          MOV EAX,[MFTSizeBySector]
          MOV [BX],EAX
          MOV WORD PTR           DS:[SectorNumWanted],AX
          ADD BX,4
          MOV [ParamTailPoint],EBX
          MOV EBX,[MFTPoint]
          PUSH DS
          POP ES
          CALL ReadSector ;           Read MFT
          MOV EDI,EBX
          CALL FixupRecord ;           Fixup
          MOV EAX,[MFTPoint]
          MOV EBX,20H
          MOV ECX,0
          MOV EDX,0
          CALL SearchAttribute ;           Look for attribute list
          OR EAX,EAX               ; Find ?
          JZ NoAttributeList ;           Can't find attribute list
          MOV EBX,EAX
          PUSH DS
          POP ES
          MOV EDI,[AttributePoint]
          CALL GetAttributeData ;           Read attribute list
          MOV EBX,[AttributePoint]
         
          SearchingAttribute:
          CMP DWORD           PTR [BX],80H
          JZ FoundData ; Look           for a data record in attribute list
          ADD BX,[BX+4]
          JMP SHORT           SearchingAttribute
         
          GetExtMFTPos: PUSH               EBX
          MOV EAX,[BX+10H]
          MUL [MFTSizeBySector]
          PUSH EAX
          XOR EDX,EDX
          MOVZX EBX,BYTE           PTR [SectorPerCluster]
          DIV EBX               ; Get cluster number of record
          PUSH EDX
          CALL GetMFTDataPos
          OR EAX,EAX
          JZ FatalFault
          MOV ECX,[MFTSizeBySector]
          MOVZX EBX,BYTE           PTR [SectorPerCluster]
          MUL EBX
          POP EDX
          ADD EAX,EDX
          ;-------------------------------------------------
          MOV EBX,[ParamTailPoint]
          MOV [BX],EAX
          ADD BX,4
          MOVZX EAX,BYTE           PTR [SectorPerCluster]
          SUB EAX,EDX
          CMP EAX,ECX
          JBE NEAR PTR           SaveMFTUnitSize
          MOV EAX,ECX
         
          SaveMFTUnitSize:
          MOV [BX],EAX
         
          FixupMFTParam: SUB               ECX,EAX
          POP EDX
          JZ NEAR PTR           NextUnit
          ADD EAX,EDX
          PUSH EAX
          XOR EDX,EDX
          MOVZX EBX,BYTE           PTR [SectorPerCluster]
          DIV EBX
          PUSH ECX
          CALL GetMFTDataPos
          POP ECX
          OR EAX,EAX
          JZ FatalFault
          MOVZX EBX,BYTE           PTR [SectorPerCluster]
          MUL EBX
          MOV EBX,[ParamTailPoint]
          MOV EDX,[BX]
          ADD BX,4
          ADD EDX,[BX]
          CMP EDX,EAX
          JNE NEAR PTR           GetReadParam8
          MOVZX EAX,BYTE           PTR [SectorPerCluster]
          CMP EAX,ECX
          JBE NEAR PTR           SaveFixupSize
          MOV EAX,ECX
         
          SaveFixupSize: ADD               [BX],EAX
          JMP SHORT           FixupMFTParam
         
          ;-------------------------------------------------
          GetReadParam8: ADD               BX,4
          MOV [ParamTailPoint],EBX
          MOV [BX],EAX
          ADD BX,4
          MOVZX EAX,BYTE           PTR [SectorPerCluster]
          CMP EAX,ECX
          JBE NEAR PTR           GetReadParam9
          MOV EAX,ECX
         
          GetReadParam9: MOV               [BX],EAX
          JMP SHORT           FixupMFTParam
         
          NextUnit: ADD               BX,4
          INC [MFTNumber]
          MOV [ParamTailPoint],EBX
          POP EBX
         
          FoundData: ADD               BX,[BX+4]
          CMP DWORD           PTR [BX],80H
          JZ GetExtMFTPos
         
          NoAttributeList:
          POPAD ; Restore           all regs
          NOP
          POP DS
          POP ES
          RET
          FindLastMFT ENDP
          ;-----------------------------------------------------          ; Function : Calculate next cluster offset in  MFT and cluster number in the stream
          ; ArgIn : EAX cluster index
          ; ArgOut : EAX cluster offset, ECX cluster number           in the stream
          GetMFTDataPos PROC NEAR
          MOV EDX,EAX
          MOV ECX,[MFTNumber]
          MOV ESI,DWORD           PTR [MFTTail]
          ADD ESI,[MFTSize]
         
          GetMFTData: PUSH               EDX
          PUSH ECX
          PUSH EDX
          MOV EBX,DWORD           PTR [MFTTail]
          MOV EDI,[MFTSizeBySector]
         
          LoadingData: MOV               EAX,[SI]
          MOV [SectorWanted],EAX
          ADD SI,4
          MOV EAX,[SI]
          MOV WORD PTR           DS:[SectorNumWanted],AX
          ADD SI,4
          PUSH DS
          POP ES
          CALL ReadSector ;           Read a cluster of MFT
          SUB EDI,EAX
          JZ NEAR PTR           ReadComplete
         
          MUL WORD PTR           [BytePerSector]
          ADD BX,AX               ; Fixup parameter
          JMP SHORT           LoadingData
         
          ReadComplete: MOV               EDI,DWORD           PTR [MFTTail]
          PUSH DS
          POP ES
          CALL FixupRecord
          MOV EAX,DWORD           PTR [MFTTail]
          MOV EBX,80H
          MOV ECX,0
          MOV EDX,ECX
          CALL SearchAttribute ;           Look for a data attribute
          OR EAX,EAX
          JZ FatalFault
          MOV EBX,EAX
          POP EAX
          PUSH ESI
          CALL GetStreamPos
          POP ESI
          OR EAX,EAX
          JZ NEAR PTR           NoStreamData
         
          POP EBX
          POP EBX
          RET
         
          NoStreamData: POP               ECX
          POP EDX
          LOOP GetMFTData
         
          XOR EAX,EAX
          RET
          GetMFTDataPos ENDP
          ;----------------------------------------------------          ; Function : Read some records of MFT
          ; ArgIn : EAX sector offset, ECX = count,ES:EDI
          ReadMFTNode PROC NEAR
          PUSH ES
          PUSH DS
          PUSHAD ; Save all           regs
         
          PrepairReadParam:
          PUSH EAX
          PUSH ECX
          XOR EDX,EDX
          MOVZX EBX,BYTE           PTR [SectorPerCluster]
          DIV EBX
          PUSH EDX
          PUSH EDI
          CALL GetMFTDataPos ;           Calculate next MFT cluster parameter
          POP EDI
          OR EAX,EAX
          JZ FatalFault
          MOVZX EBX,BYTE           PTR [SectorPerCluster]
          MUL EBX
          POP EDX
          ADD EAX,EDX
          MOV [SectorWanted],EAX
          POP ECX
          MOVZX EBX,BYTE           PTR [SectorPerCluster]
          CMP ECX,EBX
          JLE NEAR PTR           ReachToLastCluster
         
          MOV WORD PTR           DS:[SectorNumWanted],BX
          SUB ECX,EBX
          POP EAX
          ADD EAX,EBX
          PUSH EAX
          PUSH ECX
          JMP SHORT           CalculateBuffer
          DB 90H
         
          ReachToLastCluster:
          POP EAX
          ADD EAX,ECX
          PUSH EAX
          MOV WORD PTR           DS:[SectorNumWanted],CX
          MOV ECX,0
          PUSH ECX
         
          CalculateBuffer:
          PUSH ES
          PUSH EDI
          MOV BX,DI
          AND BX,0FH
          MOV AX,ES
          SHR EDI,4
          ADD AX,DI
          PUSH AX
          POP ES
          CALL ReadSector
          POP EDI
          POP ES
          ADD EDI,[BytePerCluster]               ; Fixup buffer address
          POP ECX
          POP EAX
          CMP ECX,0
          JG PrepairReadParam ;           Reading...
         
          POPAD ; Restore           all regs
          NOP
          POP DS
          POP ES
          RET
          ReadMFTNode ENDP
          ;-------------------------------------------------          ; Function : Load some units of MFT and fixup
          ; ArgIn : EAX MFT record number, ES:EDI buffer  to store data
          LoadMFTNode PROC NEAR
          PUSH ES
          PUSH DS
          PUSHAD ; Save all           regs
          MUL [MFTSizeBySector]
          MOV ECX,[MFTSizeBySector]
          CALL ReadMFTNode
          CALL FixupRecord
          POPAD ; Restore           all regs
          NOP
          POP DS
          POP ES
          RET
          LoadMFTNode ENDP
          ;-----------------------------------------------          ; Function : Read Extend directory entrys list
          ; ArgIn : EAX record index
          ReadExtDirNode PROC NEAR
          PUSH ES
          PUSH DS
          PUSHAD
          MUL [SectorPerRecord]
          MOV EBX,[DirEntryList]               ; Resident data point (?)
          MOV ECX,[SectorPerRecord]
          PUSH DS
          POP ES
          MOV EDI,[TempDataBuf]
          CALL ReadRunDataBySectorOffset
          CALL FixupRecord
          POPAD ; Restore           all regs
          NOP
          POP DS
          POP ES
          RET
          ReadExtDirNode ENDP
          ;------------------------------------------------          ; Function : Check if a bit in directory bitamp   is used
          ; ArgIn : EAX the index in bitmap
          FindUsedUnit PROC NEAR
          PUSH EAX
          PUSH EBX
          PUSH ECX
          MOV EBX,[BitampPoint]
          MOV ECX,EAX
          SHR EAX,3
          AND ECX,7
          ADD EBX,EAX
          MOV EAX,1
          SHL EAX,CL               ; Search in a bit data
          TEST AL,[EBX]
          JZ NEAR PTR           FreedomUnit
          CLC
          JMP SHORT           UsedUnit
          DB 90H
         
          FreedomUnit: STC
         
          UsedUnit: POP               ECX
          POP EBX
          POP EAX
          RET
          FindUsedUnit ENDP
          ;--------------------------------------------------          ; Function : return offset and size of a stream  data in running data
          ; ArgIn : EBX point to the running data,EAX  the offset of unit in file
          ; ArgOut : EAX the cluster offset of the wanted  unit
          ; ArgOut : ECX the last unit number from the  offset
          GetStreamPos PROC NEAR
          CMP BYTE PTR           [EBX+8],1
          JE NEAR PTR           IsRunningData
          SUB EAX,EAX
          RET
         
          IsRunningData: LEA               ESI,DWORD           PTR [EBX+10H]
          MOV EDX,DWORD           PTR [ESI+8]
          CMP EAX,EDX
          JA NEAR PTR           OutOfVCNSegment
          MOV EDX,[ESI]
          CMP EAX,EDX
          JAE NEAR PTR           StartHandle
         
          OutOfVCNSegment: ;           Out of range of VCN
          SUB EAX,EAX
          RET
         
          StartHandle: ADD      BX,WORD   PTR [ESI+10H]      ; EBX point to data offset
          SUB ESI,ESI
         
          ReadStreamInChain:
          CMP BYTE PTR           [EBX],0
          JE NEAR PTR           ReachEndOfData
          CALL GetStreamOffset
          ADD ESI,ECX
          CALL GetStreamSize
          ADD ECX,EDX
          CMP EAX,ECX
          JL NEAR PTR           StreamFound
          MOV EDX,ECX
          PUSH EAX
          MOVZX ECX,BYTE           PTR [EBX]
          MOV EAX,ECX
          AND EAX,0FH
          SHR ECX,4
          ADD EBX,ECX
          ADD EBX,EAX
          INC EBX               ; Fixup index point
          POP EAX
          JMP SHORT           ReadStreamInChain
         
          StreamFound: SUB               ECX,EAX
          SUB EAX,EDX
          ADD EAX,ESI
          RET
         
          ReachEndOfData: SUB               EAX,EAX
          RET
          GetStreamPos ENDP
          ;---------------------------------------------------          ; Function : Get noresident data record size
          ; ArgIn : EBX Point to a noresident record index
          ; ArgOut : ECX Current record size
          GetStreamSize PROC NEAR
          SUB ECX,ECX
          MOV CL,[EBX]
          AND CL,0FH
          CMP ECX,0
          JNE NEAR PTR           NeedBind ; There is data
          SUB ECX,ECX
          RET
         
          NeedBind: PUSH               EBX
          PUSH EDX
          ADD EBX,ECX
          MOVSX EDX,BYTE           PTR [EBX]               ; Get data size
          DEC ECX
          DEC EBX
         
          CombineDataSize:
          CMP ECX,0
          JE NEAR PTR           BindComplete
          SHL EDX,8
          MOV DL,[EBX]
          DEC EBX
          DEC ECX
          JMP SHORT           CombineDataSize
         
          BindComplete: MOV               ECX,EDX
          POP EDX
          POP EBX
          RET
          GetStreamSize ENDP
          ;--------------------------------------------          ; Function : Get noresident data record offset
          ; ArgIn : EBX Point to a noresident record index
          ; ArgOut : ECX Current record offset
          GetStreamOffset PROC NEAR
          PUSH EBX
          PUSH EDX
          SUB EDX,EDX
          MOV DL,[EBX]
          AND EDX,0FH
          SUB ECX,ECX
          MOV CL,[EBX]
          SHR CL,4
          CMP ECX,0
          JNE NEAR PTR           OffsetValid
          SUB ECX,ECX
          POP EDX
          POP EBX
          RET
         
          OffsetValid: ADD               EBX,EDX
          ADD EBX,ECX               ; EBX point the offset of record
          MOVSX EDX,BYTE           PTR [EBX]
          DEC ECX
          DEC EBX
         
          CombineDataOffset:
          CMP ECX,0
          JE NEAR PTR           HandleComplete
          SHL EDX,8
          MOV DL,[EBX]
          DEC EBX
          DEC ECX
          JMP SHORT           CombineDataOffset
         
          HandleComplete: MOV               ECX,EDX
          POP EDX
          POP EBX
          RET
          GetStreamOffset ENDP
          ;------------------------------------------------          LowerCase2UpperCase PROC NEAR
          OR ECX,ECX
          JNZ NEAR PTR           StringValid
          RET
         
          StringValid: PUSH               ECX
          PUSH ESI
         
          CheckChar: CMP               WORD PTR [ESI],61H
          JL NEAR PTR           NextChar
          CMP WORD PTR           [ESI],7AH
          JG NEAR PTR           NextChar
          SUB WORD PTR           [ESI],20H
         
          NextChar: ADD               ESI,2
          LOOP CheckChar
         
          POP ESI
          POP ECX
          RET
          LowerCase2UpperCase ENDP
          ;--------------------------------------------------          ; Function : Read root and look for a file in   it
          ; ArgIn : EAX point to the file name, ECX file    name size(Unicode)
          ; ArgOut : point to file record
          SearchFileInRoot PROC NEAR
          PUSH EAX
          PUSH ECX
          MOV EDX,EAX
          MOV EAX,[RootAttribute]
          LEA EBX,DWORD           PTR [EAX+10H]
          ADD AX,WORD           PTR [EBX+4]
          LEA EAX,DWORD           PTR [EAX+10H]
          MOV EBX,EDX
          CALL SearchFile
          OR EAX,EAX
          JZ NEAR PTR           NeedSearch
         
          POP ECX
          POP ECX
          RET
         
          NeedSearch: MOV               EAX,[DirEntryList]
          OR EAX,EAX
          JNZ NEAR PTR           OneSectorRead8
         
          POP ECX
          POP ECX
          XOR EAX,EAX
          RET
         
          OneSectorRead8: MOV               EDX,[DirEntryList]
          LEA EDX,DWORD           PTR [EDX+10H]
          MOV EAX,DWORD           PTR [EDX+8]
          INC EAX
          MOV EBX,[BytePerCluster]
          MUL EBX
          XOR EDX,EDX
          DIV [BytePerRecord]
          PUSH EAX
         
          TestPreviousUnit:
          POP EAX
          OR EAX,EAX
          JZ NEAR PTR           UnitNotFound
          DEC EAX
          PUSH EAX
          CALL FindUsedUnit
          JC TestPreviousUnit
         
          CALL ReadExtDirNode
          POP EDX
          POP ECX
          POP EBX
          PUSH EBX
          PUSH ECX
          PUSH EDX
          MOV EAX,[TempDataBuf]
          LEA EAX,DWORD           PTR [EAX+18H]
          CALL SearchFile
          OR EAX,EAX
          JZ TestPreviousUnit
         
          POP ECX
          POP ECX
          POP ECX
          RET
         
          UnitNotFound: POP               ECX
          POP ECX
          XOR EAX,EAX
          RET
          SearchFileInRoot ENDP
          ;-----------------------------------------------          ; Function :
          ; ArgIn : EBX attribute of "$I30" record, ECX
          ; ArgOut :
          GetAttributePos PROC NEAR
          PUSH ECX
          PUSH EAX
          MOV EAX,5
          PUSH DS
          POP ES
          MOV EDI,ECX
          CALL LoadMFTNode ;           Read the 5th MFT record
          MOV EAX,ECX
          POP EBX
          PUSH EBX
          MOVZX ECX,WORD           PTR [UnicodeDirectory]
          MOV EDX,OFFSET           [UnicodeDirectory+2]
          CALL SearchAttribute
          POP EBX
          POP ECX
          OR EAX,EAX
          JNZ NEAR PTR           FindRecord
          MOV EAX,ECX
          MOV ECX,EBX
          PUSH EAX
          PUSH EBX
          CALL SearchAttributeEx ;           Check if the attribute item exist in attribute list
          POP EBX
          POP EDI
          OR EAX,EAX
          JZ NEAR PTR           FindRecord
          PUSH DS
          POP ES
          CALL LoadMFTNode
          MOV EAX,EDI
          MOVZX ECX,WORD           PTR [UnicodeDirectory]
          MOV EDX,OFFSET           [UnicodeDirectory+2]
          CALL SearchAttribute
         
          FindRecord: RET
          GetAttributePos ENDP
          ;-----------------------------------------------          ; Function : Look for attribute item in attribute           list
          ; ArgIn : ECX the attribute of wanted item
          ; ArgOut : EAX point to the wanted attribute           item
          SearchAttributeEx PROC NEAR
          PUSH ECX
          MOV EBX,20H
          MOV ECX,0
          MOV EDX,0
          CALL SearchAttribute
          OR EAX,EAX
          JZ NEAR PTR           SearchFailure
          MOV EBX,EAX
          PUSH DS
          POP ES
          MOV EDI,[AttributePoint]
          CALL GetAttributeData
          PUSH DS
          POP ES
          MOV EBX,[AttributePoint]
          POP ECX
         
          _Searching: CMP               ES:[BX],ECX
          JE NEAR PTR           FoundTheRecord
          CMP DWORD           PTR ES:[BX],0FFFFFFFFH
          JE NEAR PTR           SearchComplete
          CMP WORD PTR           ES:[BX+4],0
          JE NEAR PTR           SearchComplete
          MOVZX EAX,WORD           PTR ES:[BX+4]
          ADD BX,AX
          MOV AX,BX
          AND AX,8000H
          JZ _Searching
         
          MOV AX,ES
          ADD AX,800H
          MOV ES,AX
          AND BX,7FFFH
          JMP SHORT           _Searching ; Fixup segment
         
          FoundTheRecord: MOV               EAX,ES:[BX+10H]
          RET
         
          SearchFailure: POP               ECX
         
          SearchComplete: XOR               EAX,EAX               ; Zero register
          RET
          SearchAttributeEx ENDP
          ;---------------------------------------------------          MissNTLDR: MOV               AL,MissNTLDRErrorMsg
          JMP DispFatalMsg
         
          CompressedNTLDR:
          MOV AL,NTLDRComperssedOffset
          JMP DispFatalMsg
          DB 4908 DUP           (0)
          Code ENDS
          END START

TOP

这是主引导代码吧?
先把mbr 和dbr搞明白再说

TOP

发新话题