绕过操作系统提供的API来读取文件,肯定要了解硬盘结构和所用的文件系统。Dos下,设置
好CHS(Cylinder/Header/Sector)参数后,通过调用BIOS提供的13H中断,就可以得到制定扇区的内容,但由于INT 13H的有8.456GB的容量限制,而且CHS的方式要求每柱面扇区数相等,磁盘空间的利用率不高,于是扩展INT 13H出现了。
新式大容量的硬盘,透过扩展INT 13H,指定逻辑块地址后就可访问;为了兼容INT 13H的方式,内部装有一个地址翻译器,把CHS地址转换成LBA(逻辑块地址)。
出于安全的考虑, Windows 98以后,保护模式下的程序(ring 3)已经不能调用BIOS中断了,如果还要读指定扇区的内容,我们只能转而采用其它的方法。在Windows下,所有的设备都被当成一个个的文件,硬盘也不例外,这里我们就会用ReadFile来打开物理硬盘(注意:只是读物理硬盘,而不是读文件)。整个读文件的流程如下:
1. 打开物理硬盘
2. 读取MBR(主引导扇区)的内容
3. 分析MBR的内容,得到各Partition Entry(磁盘分区)的信息
4. 读取磁盘分区的引导记录(Boot Record,引导记录在各磁盘分区的第一扇区)
5. 根据磁盘分区引导记录的内容,得到FAT表的位置所在
6. 按照FAT表项中的簇链表,依次读取文件所用各簇的内容
在介绍MBR前,描述一下电脑的启动过程也有会有帮助,过程共有4步:
1. CPU和BIOS上电自检
2. BIOS决定哪一个设备为“启动设备”
3. BIOS把“启动设备”第一个物理扇区的内容读入内存,让CPU从该内存起始地址开始执
行。如果“启动设备”是硬盘,这一步就是读取MBR的内容,接下来的动作如下:
4. MBR中的代码读入“主活动分区”上的引导记录(Boot Record,注意与MBR的区别)到内
存中,接着CPU由此内存起始处开始执行。
MBR
读文件的流程也说了,启动过程也讲了,接下来就轮到各数据结构了。MBR结构很简单,由
启动电脑的可执行代码、分区入口(共四项)、引导记录结束标志(0x55 0xAA)三部分组成,
共512字节。
Offset | Description | Size |
000h | Executable Code (Boots Computer) | 446 Bytes |
1BEh | 1st Partition Entry (See NextTable) | 16 Bytes |
1CEh | 2nd Partition Entry | 16 Bytes |
1DEh | 3rd Partition Entry | 16 Bytes |
1EEh | 4th Partition Entry | 16 Bytes |
1FEh | Boot Record Signature (55hAAh) | 2 Bytes |
分区入口(Partiton Entry)
MBR中共有4个分区入口,一个入口代表了一个分区。分区入口结构中,记录了该分区起始和
结束的CHS参数,但由于CHS不适合用于8.456GB的硬盘,于是我们就把偏移(offset)为08h的
项就做它的代替品。
Offset | Description | Size |
00h | Current State of Partition(00h=Inactive, 80h=Active) | 1 Byte |
01h | Beginning of Partition - Head | 1 Byte |
02h | Beginning of Partition - Cylinder/Sector (See Below) | 1 Word |
04h | Type of Partition (See List Below) | 1 Byte |
05h | End of Partition - Head | 1 Byte |
06h | End of Partition -Cylinder/Sector | 1 Word |
08h | Number of Sectors Betweenthe MBR and the First Sector in the Partition | 1 Double Word |
0Ch | Number of Sectors in thePartition | 1 Double Word |
分区入口只有4个,要支持4个以上的分区怎么办呢?FAT32中,一般第一个分区是主分区,
其它所有的分区都包含在扩展分区(Extended Partiton)中。为了读取主分区外的分区,还
是需要一点技巧的,虽然不多。分区表中的第一项指定了主分区的位置,第二项指定了扩展
分区的位置。为了读取非主分区,你读入扩展分区所在位置的第一个扇区。该扇区内容的格
式与MBR相同,除了“可执行代码”处故意设置为空外。第一项的内容就是驱动器上下一个分
区的信息(D盘的信息),所不同的是,所有的扇区号都是相对于这个新的“MBR”的,扩展分区
就像是一块虚拟的硬盘。也许这样讲很不好理解,一个例子也许能让你更明白,让我们看一
个有三个分区(C,D,E)的硬盘分区表是什么样子的吧!
硬盘的MBR
入口#1 - 指向第一个分区(C盘)
入口#2 - 指向整个扩展分区(包含D盘和E盘)
在你读入扩展分区的第一个扇区后,另一个“MBR”就出现了,
扩展分区的MBR
入口#1 - 指向第二个分区(D盘)
入口#2 - 指向除了第二个分区外的扩展分区
现在,所有入口中的扇区号(特别是入口中偏移位置为08h)不再是针对硬盘的偏移了,而是
针对扩展分区起始位置的偏移。然而,CHS(柱面/磁头/山区)依然正确。
接下来,你再次读入扩展分区所在的第一个扇区,又一个MBR出现了。
剩余扩展分区的MBR
入口#1 - 指向第三个分区(E盘)
入口#2为空,因为这是最后一个分区
一直持续这种方式,直到不再有剩余分区止。
我们已经知道了分区存放的位置,进一步的,就是要分析该分区上的目录和文件。非常幸运
的,我们知道各个分区的第一扇区存放的是引导记录,如果不知道引导记录的格式,游戏也
无法继续下去,而更幸运的,我们还知道引导记录的格式。
转自:http://blog.csdn.net/swimmer2000/article/details/2239441
参考资料:
http://www.easeus.com/resource/fat32-disk-structure.htm
http://www.codeproject.com/KB/system/change_drive_sn.aspx
http://support.microsoft.com/kb/140418/en-us