NTFS是Windows NT以及之后的Windows 2000、Windows XP、Windows Server 2003、Windows Server 2008、Windows Vista和Windows 7的标准文件系统。NTFS取代了文件分配表(FAT)文件系统,为Microsoft的Windows系列操作系统提供文件系统。NTFS对FAT和HPFS(高性能文件系统)作了若干改进,例如,支持元数据,并且使用了高级数据结构,以便于改善性能、可靠性和磁盘空间利用率,并提供了若干附加扩展功能,如访问控制列表(ACL)和文件系统日志。该文件系统的详细定义属于商业秘密 ,但 Microsoft 已经将其注册为 知识产权产品。
NTFS 提供长文件名、数据保护和恢复,并通过目录和文件许可实现安全性。NTFS 支持大硬盘和在多个硬盘上存储文件(称为卷)。例如,一个大公司的数据库可能大得必须跨越不同的硬盘。NTFS 提供内置安全性特征,它控制文件的隶属关系和访问。从DOS或其他操作系统上不能直接访问 NTFS 分区上的文件。如果要在DOS下读写NTFS分区文件的话可以借助第三方软件;现如今,Linux系统上已可以使用 NTFS-3G进行对 NTFS 分区的完美读写,不必担心数据丢失。
Win 2000采用了更新版本的NTFS文件系统NTFS 5.0,它的推出使得用户不但可以像Win 9X那样方便快捷地操作和管理计算机,同时也可享受到NTFS所带来的系统安全性。 NTFS 允许文件名的长度可达 256 个字符。虽然 DOS 用户不能访问 NTFS 分区,但是 NTFS 文件可以拷贝到 DOS 分区。每个 NTFS 文件包含一个可被 DOS 文件名格式认可的 DOS 可读文件名。这个文件名是 NTFS 从长文件名的开始字符中产生的。
我们来实现在VC++下面实现读取MBR。
C++内联汇编
在C++代码中插入__asm {}即可
我们亲自来分析实现NTFS文件恢复。
;******************************************************
.386
.model flat, stdcall
option casemap :none
;******************************************************
; Include 文件定义
;******************************************************
include \masm32\include\windows.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
;*******************************************************
; Equ 等值定义
;*******************************************************
ICO_MAIN equ 1000h ;图标ID
DLG_MAIN equ 1 ;对话框ID
IDC_PARTITION equ 101h ;盘符名输入框ID
IDC_FILENAME equ 102h ;文件名ID
;*******************************************************
; 数据段
;*******************************************************
.data
hFile_Disk dd 0 ;磁盘文件号
hFile dd 0 ;文件号
FileName db '\\.\' ;打开文件名为\\.\X:形式的文件则打开了X分区
PARTITION db 3 dup (0) ;请注意FileName和等待用户输入的PARTITION共
;同组成了要打开的文件名(分区)
FILENAMEA db 25 dup (0) ;等待用户输入的字符缓存
FILENAMEU db 50 dup (0) ;转换成Unicode字符串的缓存
ErrCap db '失败',00 ;错误对话框的Caption
ErrorInfo1 db '可能的原因是:',0dh
db '1.该程序不能在除NT以外的系统中执行;',0dh
db '2.您输入的盘符无效!',00h
ErrorInfo2 db '读盘错误!',00
ErrorInfo3 db '该程序只能恢复NTFS文件系统中的数据!',0dh
db '您打开的磁盘不是NTFS文件系统!',00h
ErrorInfo4 db '移动文件指针错误!',00h
Info1 db '请在当前文件夹下查看已恢复的文件!如果文件扩展名不对,请自行',0dh
db '修改扩展名,如果没有文件,则说明您输入的文件没有找到!',00h
Recoveried dd 30h ;用来存放已经恢复的文件个数0~z
_0 db 00 ;字符串结束
Readed dd 0
System_Id db 'NTFS' ;DBR中NTFS卷的标志
MFT_Flag db 'FILE' ;MFT的标志
StateFindFile dd 0 ;该数据是FindFile过程的返回值
StringLength dd 0 ;该地址用于存放用户输入的文件名的输入长度
MFTTime dd 1024
Temp db 'Text',00
EdiOffset dd 0 ;
IndicEdi dd 0 ;用来在比较字符串中存放Edi所指向的字符串的指针
FileNameOffset dd 0 ;用来存放文件名偏移
FileSize dd 0 ;用来存放常驻80H属性的文件大小
FileSize1 dq 0 ;用来存放系统分配给非常驻80H属性的大小
FileSize2 dq 0 ;用来存放非常驻80H属性的文件真实大小
Edi80 dd 0 ;用来保存非常驻80H属性的运行列表偏移
CInfo1 db 0 ;用来保存运行列表的第一个字节的低4位
CInfo2 db 0 ;用来保存运行列表的第一个字节的高4位
ResidentFlag dd 0ffh ;80H属性常驻与非常驻标志,为0表示常驻,为1表示非常驻
ByeofOneC dd 0 ;每簇字节数
RunC dd 0 ;运行相对起始簇号
RunC2 dd 0 ;运行绝对起始簇号
RunByte dd 0 ;运行字节数
RunCN dd 0 ;运行起始簇号
RunFirstAddr dq 0 ;运行起始偏移字节
;__________________________________________________________________
.data?
hInstance dd ?
DBR db 512 dup (?) ;512字节作为DBR的缓冲
MFTFirstSector dd ? ;MFT首扇区存放的缓冲
MFTFirstOffset dd 2 dup (?)
Filling db 8 dup (?) ;这个是没有用的数据,只是为了让后面的MFT在
;程序执行时起始偏移在XXXXXXX0上,方便调试
MFT db 1024*1024 dup (?);1M作为MFT的缓冲
DataBuffer db 1024*1024 dup (?);1M字节做为文件数据缓冲
FileNameLong dd ?
FileNameBuffer dw 260 dup (?)
;*******************************************************
; 代码段
;*******************************************************
.code
;*******************************************************
_ProcDlgMain proc uses ebx edi esi hWnd,wMsg,wParam,lParam
mov eax,wMsg
.if eax == WM_CLOSE ;如果消息为WM_CLOSE,当按下右上角的关闭按钮
invoke EndDialog,hWnd,NULL ;hWnd为对话框窗口句柄,结束对话框
ret
.elseif eax == WM_INITDIALOG ;初始化代码
invoke GetDlgItem,hWnd,IDOK ;取IDOK句柄
invoke EnableWindow,eax,FALSE ;IDOK显示为灰色(确定按钮)
invoke LoadIcon,hInstance,ICO_MAIN ;设置标题栏图标
invoke SendMessage,hWnd,WM_SETICON,ICON_BIG,eax
.elseif eax == WM_COMMAND
mov eax,wParam