1. 背景
本文主要介绍DBR的读取和解析,并提供了基于元神操作系统的实现代码。由于解析DBR的目的是定位到NTFS磁盘分区的元文件$Root进行文件操作,所以只解析了少量的部分,其它部分可以参考相关文档进行理解。
DBR存在于磁盘分区的第一个扇区中,每个分区都有自己的DBR。要寻找DBR,只需定位到目标分区的开始位置即可,这通过前文中MBR的分区表实现,直接使用分区表项的第9-12字节即可。
2. 方法
(1)定位DBR
在MBR的起始地址上加0x1BE(即446),得到分区表的起始地址。假设要定位的磁盘分区是N号分区(N从0开始计数,0表示第一个分区,1表示第二个分区,依此类推),则在分区表起始地址上加16*N即可得到目标分区表项的起始地址,因为每个表项16字节。最后,在目标表项的0x08偏移开始的4个字节就是分区的起始扇区号,也就是定位DBR所需要的内容。
总结一下,定位DBR的公式形如:MBR_addr+0x1BE+16*N+0x08
(2)调用元神操作系统的API读取DBR
定位到DBR后使用API_READ_DISK_SECTOR调用元神操作系统的API来读取DBR,该操作实现在read_disk_dbr函数中,然后在主函数中的读取MBR之后添加对read_disk_dbr函数的调用,代码如下所示:
use32
START:
pusha
call read_disk_mbr
mov eax, 0
call read_disk_dbr ;read dbr in partition eax
popa
iret
sector_dbr: times 512 db 0
partition_base dd 0
;input:
; eax: index of partition to operate, 0 = first partition, 1 = second partition
read_disk_dbr:
pusha
mov edi, API_PARAM
mov dword [fs:edi], API_READ_DISK_SECTOR
mov dword [fs:edi+4], 2 ;2 parameters
mov ebx, sector_buff
add ebx, 0x1BE ;ebx point to partition table
shl eax, 4 ;eax * 16
add ebx, eax ;ebx point to dest partition item
add ebx, 8 ;ebx point to start sector no. of dest partition
mov edx, [ds:ebx]
mov dword [fs:edi+8], edx ;parameter_1: sector no.
mov [ds:partition_base], edx
xor eax, eax
mov ax, ds
add eax, SEG_BASE
mov bh,byte [fs:eax+7]
mov bl,byte [fs:eax+4]
shl ebx,16
mov bx,word [fs:eax+2]
add ebx, sector_dbr
mov dword [fs:edi+12], ebx ;parameter_2: start address of buffer
call pword [fs:OS_API]
mov eax, 512
movzx ebx, word [fs:cursor_y]
movzx ecx, word [fs:cursor_x]
mov esi, [fs:edi+12]
call print_bytes_hex
add word [fs:cursor_y], 20
.end:
popa
ret
上述代码将磁盘第一个分区的DBR内容读取到sector_dbr缓冲区中,并以十六进制形式进行显示,结果如下图所示:
该图中显示的内容就是磁盘第一个分区的DBR内容。
注意:此处打印DBR内容的操作仅为讲解需要,后续操作追加之前应当注释掉read_disk_dbr函数中对于print_bytes_hex调用相关的部分,即注释掉call pword [fs:OS_API]之后的部分。
另外,函数read_disk_dbr需要提供一个输入参数“分区索引号”,根据该参数来定位到目标磁盘分区。本例代码中假设要操作的磁盘分区是第一个分区(即0号分区),该分区索引号在后续操作中可由上层应用提供,例如:读取文件“d2:\test.txt”操作,在文件名中用d2来指明要操作的文件位于磁盘的第二个分区中。
(3)解析DBR
DBR的内容共有512字节,前3个字节为跳转指令(跳转到引导代码处),之后的8个字节为文件系统的OEM标志字符串(如:“NTFS ”),再之后的若干字节记录了文件系统的重要信息,接下来的部分为引导代码,最后2个字节为标记字节(固定为55 AA)。
本文主要解析文件系统的重要信息部分,即偏移0x0B开始的若干字节。0x0B-0x0C表示每扇区的字节数;0x0D表示每簇的扇区数;0x15为介质描述符;0x18-0x19表示每磁道扇区数;0x1A-0x1B表示磁头数;0x1C-0x1F表示隐藏扇区数;0x28-0x2F表示该分区的总扇区数;0x30-0x37表示$MFT元文件的起始簇号;0x38-0x3F表示$MFT镜像文件的起始簇号;0x40为每个MFT记录所占的簇数;0x44为每索引所占的簇数;0x48-0x4F为分区的逻辑序列号;0x50-0x53为校验和。
结合上面的截图,0x0B-0x0C偏移处的值为00 02(即0x0200),表示每扇区大小为512字节;0x0D偏移处的值为08,表示每簇包含8个扇区;0x15偏移处的值为F8,表示硬盘;0x18-0x19偏移处的值为3F 00(即0x003F),表示每磁道含有63个扇区;0x1A-0x1B偏移处的值为F0 00(即0x00F0);0x1C-0x1F偏移处的值为3F 00 00 00(即0x0000003F);0x28-0x2F偏移处的值为C0 CE D4 01 00 00 00 00(即0x0000000001D4CEC0);0x30-0x37偏移处的值为00 00 0C 00 00 00 00 00(即0x00000000000C0000),表示$MFT元文件的起始簇号为0x0C0000;0x38-0x3F偏移处的值为10 00 00 00 00 00 00 00(即0x0000000000000010);0x40偏移处的值为F6;0x44偏移处的值为01;0x48-0x4F偏移处的值为89 91 30 D4 A9 30 D4 92。
其中,0x0D处的每簇扇区数、0x30-0x37处的$MFT元文件的起始簇号是后续操作中需要用到的信息,用于定位$Root元文件。
3. 总结
本文介绍了NTFS文件操作的第二步,即解析DBR。通过解析DBR可以获知分区的信息,并定位到元文件$MFT,以供后续读取$Root元文件使用。
安装元神操作系统的工具“元神操作系统安装器”可去网站www.gnxxkj.com进行下载。安装账号可去网址http://www.gnxxkj.com/app/wuziqi/register.php 进行注册。