本文主要是介绍使用winhex查看FAT16格式结构,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
winhex介绍
winhex可以直接查看磁盘二进制信息, 可以比较直观地查看到各种文件系统格式的区别.
winhex使用
- 查看硬盘要管理员权限, 即启动的时候要用邮件管理员权限启动
- 点击
Tools->Open Disk
查看硬盘
- 磁盘浏览界面字体如果太小, 可以在
Option->General->Font(右下角)
调整
View->Show->Data Interpreter
打开光标数值实时查看悬浮窗
- 在悬浮窗上右键点Option, 可以调整展示的内容以及切换符号/无符号显示
- 默认为Little Endian, 可以改为Big Endian
- 磁盘浏览界面
- 每行16个byte
- 在Offset这一列上左键点击可以切换十进制和十六进制显示, 非常有用
- 点击具体地址, 在底栏会显示当前sector, 偏移量(地址), 值(无符号byte),
- 选择区域, 在底栏会显示block区间, 大小(非常有用)
- 在右侧ANSI ASCII这一列抬头上点击左键, 可以切换为UTF-8等编码显示
- 二进制区
Navigation->Position Manager
, 可以分不同颜色添加自定义区域, 很直观, 非常有用
Navigation->Go To Offset
可以从当前位置快速定位到指定偏移量位置, 非常有用
- 双击磁盘, 会打开内容浏览界面, 显示的是磁盘内部文件, 包含已删除文件
FAT16的基本结构
FAT16文件系统的基本结构依次为: DBR扇区, FAT表1, FAT表2, 根目录, 数据区.
MBR区(主引导扇区)
MBR(Main Boot Record), 按其字面上的理解即为主引导记录区, 位于整个硬盘的0磁道0柱面1扇区. 在总共512字节的主引导扇区中, MBR只占用了其中的446个字节(偏移0 - 偏移1BDH), 另外的64个字节(偏移1BEH - 偏移1FDH)交给了DPT(Disk Partition Table硬盘分区表), 最后两个字节55 AA
(偏移1FEH - 偏移1FFH)是分区的结束标志. 这个整体构成了硬盘的主引导扇区.
主引导记录中包含了硬盘的一系列参数和一段引导程序。其中的硬盘引导程序的主要作用是检查分区表是否正确并且在系统硬件完成自检以后引导具有激活标志的分区上的操作系统, 并将控制权交给启动程序.
MBR是由分区程序(如fdisk)所产生的, 它不依赖任何操作系统, 而且硬盘引导程序也是可以改变的, 从而实现多系统共存.
DBR扇区
DBR(Dos Boot Record)是操作系统引导记录区, 它通常位于硬盘的0磁道1柱面1扇区, 是操作系统可以直接访问的第一个扇区, 它包括一个引导程序和一个被称为BPB(Bios Parameter Block)的本分区参数记录表. 引导程序的主要任务是当MBR将系统控制权交给它时,判断本分区跟目录前两个文件是不是操作系统的引导文件(以DOS为例, 即是 IO.SYS 和 MSDOS.SYS), 如果确定存在, 就把其读入内存, 并把控制权 交给该文件. BPB参数块记录着本分区的起始扇区, 结束扇区, 文件存储格式, 硬盘介质描述符, 根目录大小, FAT个数, 分配单元的大小等重要参数.
下面是从一个2G的TF卡上得到的DBR扇区实际数据
EB3C90
4D53444F53352E30
0002
40
0800
02
0002
0000
F8 <- nc
EC00
3F00FF0087000000 <- nc
79CF
3A00000029A8E6B3004E4F204E414D4520202020 <-nc
4641543136202020
首先说明一下数据格式, 这些是Little Endian格式的数据, 在单个byte时可以直读, 但是在多个byte时, 高位是在右侧的, 例如 '00 02'代表的其实是'02 00'即512, '00 FF'代表的是'FF 00'即65280. 下面是具体每一段的数值说明:
- 偏移地址00H, 长度3, 内容: EB 3C 90 跳转指令.
- 偏移地址03H, 长度8, 内容: 4D 53 44 4F 53 35 2E 30 为厂商标志和os 版本号, 这里是MSDOS5.0.
- 偏移地址0BH,长度2, 内容: 00 02, 即512. 表示每个扇区有512个字节. 这个值也可能是1024, 2048, 4096.
- 偏移地址0DH, 长度1, 内容: 40. 表示的意思是每个簇有64个扇区, 即32KByte. 这个值不能为0, 而且必须是2的整数次方, 比如1、2、4、8、16、32、64、128. 但是这个值不能使每个簇超过32KB字节.
- 偏移地址0EH, 长度2, 内容: 08 00. 转换一下, 就是00 08, 意思是保留区域中的保留扇区数为8个. 那么就可以知道下面的FAT1区的开始的地址就是 0x08 * 0x200(每个扇区的字节数)= 0x1000.
- 偏移地址10H, 长度1, 内容: 02. 表示此卷中的FAT结构的份数为2, 另外一个是备份的.
- 偏移地址11H, 长度2, 内容: 00 02. 转换一下, 就是0200H, 表示根目录项数(Root Entries) 能够保存在该分区的根目录文件夹中的32个字节长的文件和文件夹名称项的总数. 在一个典型的硬盘上该值为512.
- 偏移量地址13H, 长度2, 内容: 00 00. 表示小扇区数(Small Sector). 该分区上的扇区数, 表示为16位(<65536). 对大于65536个扇区的分区来说, 本字段的值为0, 而使用大扇区数来取代它.
- 偏移地址16H, 长度2, 内容: EC 00. 转换一下为00 EC = 60,664, 表示每个FAT占用的扇区数. 那么每个扇区占用的字节数就是0x00EC*0x200 = 0x1D800. 根据启动区、FAT1、FAT2、根目录、数据区的次序, 可以依次计算出它们的地址了(教程中给出的偏移地址为24H, 但是根据实际的FAT1/FAT2地址的推算, 应该是16H地址).
- 偏移量地址20H, 长度2, 内容: 79CF, 即CF79 = 53,113. 表示大扇区数(Large Sector). 如果小扇区数字段的值为0, 本字段就包含该 FAT16 分区中的总扇区数. 如果小扇区数字段的值不为0, 那么本字段的值为0.
- 偏移量地址36H, 长度为8, 内容: 46 41 54 31 36 20 20 20, 对于ASCII码为"FAT16", 表示文件系统类型(File System Type) 根据该磁盘格式, 该字段的值可以为FAT, FAT12 或 FAT16.
FAT1, FAT2
簇的链表. 在根据目录项获取文件的首簇号后, 在FAT 找到对应的簇, 可以找到下一个簇, 一直到文件结束. 对于FAT16, 每个簇用16Bit来表示, 而对于FAT32, 使用32Bit来表示. 这是两者之间的重要区别.
根据上面的分析得知, FAT1和FAT2的起始位置在 0x1000, 长度为 0x1D800, 分区开始位置在10E00, 所以
- BDR: 0x10E00, 长度0x1000
- FAT1: 0x11E00, 长度0x1D800
- FAT2: 0x2F600, 长度0x1D800
- 根目录: 0x4CE00
DIR区, 根目录区
根目录的作用就是有文件或者目录的首簇号, 以及文件的长度(目录的长度是0). FAT16中, 根目录的所占空间可以根据BPB中的参数 - Maximum Root Directory Entries(0x11, 2bytes).
FAT16短文件目录项, 每32个字节表示一个文件(文件夹也是), 下面是一个实际的数据例子
4170006500740065
0031000F00EE2E006D00700033000000FFFF0000FFFFFFFF <-nc
5045544531202020
4D5033
20
0000094DD450F1500000 <- nc
C64C
D450
9925
53D13B00
4170006500740065
0032000F00022E006D00700033000000FFFF0000FFFFFFFF <-nc
5045544532202020
4D5033
20
0000094DD450F1500000 <-nc
CD4C
D450
1126
72C74500
4170006500740065
...
间隔着驱动器的信息(32Byte)
- 偏移地址00H, 长度8, 内容: 驱动器的名称, 8个字节.
然后是文件信息(32Byte)
- 偏移地址20H, 长度8, 内容: 5045544531202020. 表示第一个文件名: PETE1 (空缺部分是空格).
- 偏移地址28H, 长度3, 内容: 4D5033, mp3, 表示文件扩展名, 为ASCII字符表示.
- 偏移地址2BH, 长度1, 内容: 20. 表示文件属性, 00000000(读写); 00000001(只读); 00000010(隐藏); 00000100(系统); 00001000(卷标); 00010000(子目录); 00100000(归档).
- 偏移地址36H, 长度2, 内容为C6 4C. 表示时间 = 小时*2048 + 分钟*32+秒/2. 得出的结果换算成16进制填入即可. 也就是: 36H字节的0-4位是以2秒为单位的量值; 36H字节的5-7位和37H字节的0-2位是分钟; 37H字节的3-7位是小时.
- 偏移地址38H, 长度2, 内容为D4 50. 表示日期= (年份 - 1980)*512 + 月份*32 + 日. 得出的结果换算成16进制填入即可. 也就是: 38H字节0-4位是日期数; 38H字节5-7位和39H字节0位是月份; 39H字节的1-7位为年号, 原定义中0-119分别代表1980-2099, 目前高版本的Windows允许取0-127, 即年号最大可以到2107年.
- 偏移地址3AH, 长度2, 内容99 25, 为该文件开始簇号, 这里也是用了小端格式组织. 转换下为25 99, 根据这个就可以找到文件PETE1.mp3下一个簇号在FAT1中的位置了. 0x11E00 + 2599H*02H(因为2个字节存一个簇号)= 0x16932.
- 偏移地址3CH, 长度4, 内容: 53 D1 3B 00. 表示文件长度, 转换后为00 3B D1 53就是3,920,211 Byte
然后又是驱动器信息(32Byte)
数据区
文件等数据待的地方. 紧跟着根目录. 从2号簇开始.
参考
- 解析FAT16文件系统 http://blog.chinaunix.net/uid-23247212-id-327574.html
- FAT16文件系统格式说明 https://blog.csdn.net/deng0zhaotai/article/details/6933336
- Windows文件系统功能比较 https://docs.microsoft.com/zh-cn/windows/win32/fileio/filesystem-functionality-comparison
这篇关于使用winhex查看FAT16格式结构的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!