前几天在江民网站上看到了数据恢复的一些文章,觉得很好,但有些地方不是很明白
例如下面这个主引导记录:
8001 0100BFE 7FFD 3F00 00003F04 7D000000
41FE0FFE FFFF7E04 7D004788 2C040000
我知道 7FFD是 C区的结束扇区号和柱面号 ,41FE是 D区的起始扇区号和柱面号 ,很多文章中都写出如果知道了 41FE就可以推出 7FFD,或者知道了 7FFD就可以推出 41FE,可是 ,这是怎么推出来的呢 ?我看了一些文章,要什么高二位,低六位,我百思不得其解 ,请大家赐教 !
现在将我写的《硬盘扇区读写技术 - 修复硬盘与恢复文件》一书中,有关主引导记录和分区表的一段内容,摘录如下,希望能对你有所帮助。
第 2章 硬盘的数据结构
硬盘只有建立起完整的数据结构,才能正常使用。数据结构由六部分组成,分别是主引导记录、主分区表和分区表链、分区引导记录、文件分配表、文件目录表和数据区。了解硬盘的数据结构,是对硬盘物理扇区进行读写编程的基础。
特别是本书介绍的通过读取扇区数据恢复文件的方法,已经完全不用考虑被操作硬盘安装的是什么操作系统,甚至不用考虑硬盘上还有没有操作系统。因为这种恢复文件的方法,是通过调用 BIOS磁盘服务程序来完成的,而 BIOS对硬盘的管理级别高于所有的操作系统。但是这种操作必须了解有关的数据结构和文件的存储方式,才能按照文件的存储规律将它们恢复出来。因此,了解硬盘的数据结构,是学习本书编程技术必须具备的重要基础知识之一。
从本章开始要为以后学习物理扇区读写编程做一些必要地准备,介绍一些必备的常识。这期间为了对物理扇区寻址,经常要进行繁琐的数学运算。为了使运算过程更简明、直观,容易被读者理解。笔者以自己使用的一块 IBM生产的 18G硬盘作为标本,为全书所有的数学运算和编程提供参照。
笔者使用的硬盘分为一个主分区C和一个扩展分区,扩展分区又分成D、E、F、G四个逻辑驱动器,C也是一个逻辑驱动器。从 C到 F四个逻辑驱动器的容量都是 2047M,采用 FAT16分区格式,逻辑驱动器 G的容量是 9170M,采用 FAT32分区格式。这块硬盘虽然容量小点,但因为是 SCSI硬盘,所以速度很快。硬盘上安装了两个操作系统,C盘安装 WINDOWS 98第二版;D盘安装 WINDOWS 2000 PROFESSIONAL,采用双启动方式安装。
通常将逻辑驱动器看作一个独立的盘,所以笔者硬盘中的五个逻辑驱动器,今后在叙述中就简称为C盘、D盘、E盘、F盘和G盘。
2.1 主引导记录
硬盘的主引导记录也称 MBR,位于 0柱面 0磁头 1扇区。该扇区的 512个字节有三部分内容,除了主引导记录外,还有分区表和结束标志 55 AA。
主引导记录的作用非常重要,它是硬盘启动时最先加载的扇区数据。下面通过分析硬盘的启动过程,来说明它的重要性:
1. 计算机系统接通电源以后,主板 BIOS加电进行自检。自检的内容很多,是一个很复杂的过程,这里只介绍与硬盘有关的部分。
2. 将硬盘第一个扇区,也就是0柱面0磁头1扇区读入内存。
3. 检查结束标志,也就是扇区最后两个字节的值是否等于 aa55H(存储顺序是低字节在前,高字节在后)。若不等则打印屏幕提示,然后死机。
4. 执行主引导记录中的程序,将控制权转交给主引导程序。
5. 主引导程序首先将自己读入内存,然后查找在分区表中是否有活动分区。找到活动分区以后,将分区引导记录读入内存。
6. 检查结束标志是否等于 aa55H,然后执行分区引导记录中的启动程序,将控制权交给操作系统。
7. 操作系统加载系统文件,计算机启动。
通过对以上过程的分析可以看出,如果主引导记录不正常,后面所有的启动过程都不可能正常执行。
有一种特殊情况,使计算机启动过程的前两步与上面介绍的不一样。如果硬盘上安装了多系统引导软件,如 PartitionMagician分区软件,则该软件将主引导记录替换成自己的一段程序。这段程序将 BIOS引向软件设置的专用分区,然后根据操作者的选择激活某一个分区,再进入正常的启动过程。类似 PartitionMagician这样的分区软件还有很多,它们各有自己的特点,这些情况都不在本书的讨论范围之内。
通常情况下,一块硬盘上只有一个主引导记录。
主引导记录扇区所在的磁道,通常称其为 0磁道,它属于隐藏磁道,这个磁道的 63个扇区属于隐藏扇区。操作系统的所有命令,除了 FDISK以外都不能访问它们。就连格式化程序 FORMAT,对它们也无能为力。
正因为如此, 0磁道的 63个扇区就成了一些病毒程序代码、操作系统的引导代码、应用软件用于自我保护的识别标记、 BIOS功能扩展程序代码的栖息之地。
由于 INT13H中断能调用 BIOS磁盘服务程序,直接对硬盘物理扇区进行操作,并且这种操作与分区无关。所以要想读写硬盘 0磁道的某个扇区,在程序中使用 INT13H中断调用功能即可达到目的。
使用调试程序 DEBUG,通过 INT13H中断调用可以读出这些扇区内容, BEBUG程序应在 DOS实模式下执行。
所有对 INT13H中断的调用都应在 DOS实模式下运行,因为 WINDOWS 95以上的操作系统都是保护模式,对 INT13H中断调用的支持不尽相同。
举例来说, WINDOWS 95不支持 INT13H中断调用;而 WINDOWS 98在 DOS窗口下支持 INT13H中断调用; WINDOWS 2000不支持 INT13H中断调用,但可以使用 API函数 CreateFile对物理扇区进行读写。
为了将程序的编译和运行环境统一起来,本书中所有程序统一使用 DOS实模式,可以是 DOS 6.22、 DOS 7.0和 DOS 7.1。
本书介绍的工具程序和应用范例,是指硬盘处于不正常状态时,如何利用硬盘物理扇区读写技术修复数据结构和恢复文件。在这种情况下,是不可能启动被修复硬盘上的 WINDOWS系统的。
在硬盘不能启动的情况下,可以有两种操作模式。第一种模式是用软盘启动,在软盘上运行有关的工具程序,对硬盘扇区进行读写操作。这种操作模式简便易行,但程序的运行速度比较慢。第二种模式是用一块正常的硬盘启动,运行有关的工具程序,这块硬盘设置为第一硬盘。将不能启动的硬盘设置为第二硬盘,在 INT13H中断调用的入口参数中,把有关寄存器的参数设定为 81H,就能对有问题的硬盘扇区进行读写操作。
以下是用 DEBUG读取笔者硬盘主引导记录的过程,关于 INT13H中断的使用方法,在后面有关章节和附录中再详细说明。
F:\>debug
-a 100 ;由 100H开始输入指令代码
-g
Program terminated normally
-d 200 l200 ;显示缓冲区 200H处的数据,长度 200H字节
-q
0000 33 C0 8E D0 BC 00
0010 BF 1B 06 50 57 B9 E5 01-F3 A4 CB BE BE 07 B1 04
0020 38
0030 EE 83 C6 10 49 74 16 38
0040
0050 96
0060
0070 41 CD 13 58 72 16 81 FB-55 AA 75 10 F6 C1 01 74
0080 0B
0090
00B0 AA 74
00D0 D5
00E0 56 33 F6 56 56 52 50 06-53 51 BE 10 00 56 8B F4
0100
0110 D6 C7 F8 B1 ED CE DE D0-A7 A1 A3 B0 B2 D7 B0 B3
0120 CC D0 F2 CE DE B7 A8 BC-CC D0 F8 A1 A3 00 BC D3
0130 D4 D8 B2 D9 D7 F7 CF B5-CD B3 CA B1 B3 F6 CF D6
0140 B4 ED CE F3 A1 A3 B0 B2-D7 B0 B3 CC D0 F2 CE DE
0150 B7 A8 BC CC D0 F8 A1 A3-00 C8 B1 C9 D9 B2 D9 D7
0160 F7 CF B5 CD B3 00 00 00-00 00 00 00 00 00 00 00
0170 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0180 00 00 00 8B FC 1E 57 8B-F5 CB 00 00 00 00 00 00
0190 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
01B0 00 00 00 00 00 00 00 00-39 25
01D0 41 05
01E0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
1 2 3 4 5 6 7 8 第二个分区表项记录的是下一分区的有关参数。 E:\>debug Program terminated normally
将 16个字节按表 2-1的格式分为八段,分别进行说明。
第一、二、四、五段与表中的内容一样,不必重复。
第三段是两个字节,组成一个字。如何从中算出扇区值和柱面值,请参阅对第六段的分析。
第六段也是一个字,存储顺序低字节在前,高字节在后。 7fH的低 6位表示扇区值,高 2位与后面 04H连成 10位,表示柱面数。为了更直观地说明这种换算规律,先用二进制表示它们,最后再换算成十进制。 7fH转成二进制 “01111111B”,它的低 6位转换为十进制 “111111B”= 63。高 2位 “01B”与 04H的二进制 “00000100B”合成 10位二进制数 “0100000100B”,转为十进制是 260。最后得到分区结束扇区值是 63,柱面值是 260。
为什么要详细地解说这种运算过程?因为今后在编程时这种运算经常用到,稍有疏忽就会出错。
第七段是一个双字,存储顺序低字节在前,高字节在后,写成十六进制是 0000003fH,十进制是 63。
第八段是一个双字,它的值是十六进制 003ffa86H,十进制为 4192902。
第七段和第八段的两组数据在利用扩展 INT13H中断进行物理扇区寻址时非常有用。现在先简要说明一下,更详细的内容在 “工具篇 ”里再作介绍。
扩展 INT13H中断调用不再使用前面介绍的 CHS寻址方式,改用线性寻址方式,扇区编号从 0开始,前面说的 0柱面 0磁头 1扇区在线性寻址方式下就是 0号扇区。
用 0加上第七段的值 63,就是存放C盘分区引导记录的扇区地址。 63再加上第八段的 4192902等于 4192965,就是存放D盘分区链表记录的扇区地址。
依此类推,就可把硬盘上所有逻辑驱动器的分区链表扇区地址,以及分区引导记录扇区地址找出来。在以后有关编程的章节中,这是很重要的核心内容。
分区表项二:(位移 1ceH至 1ddH,编号 463到 478)
00 00 41 05
将 16个字节按表 2-1的格式分为八段,与第一个分区表项相同的字段就不重复说明了。
在这个表项中,第三段的数据对于编程非常重要,它记录了下一个分区起始柱面地址和扇区地址。根据前面对第六段数据的计算方法,可以算出柱面值是 261,扇区值是 1。这两个值和第二段记录的磁头号构成 CHS地址( 261、 0、 1),作为使用基本 INT13H中断调用对下一个逻辑驱动器寻址的依据。
由于两个字节不是独立使用,需将一个字节的高 2位与另一字节合并使用,所以使编程中的数据处理很麻烦。笔者在这里介绍一种简便算法:将第三段的第一个字节减 1后左移两位,再加上第二个字节的值,就是柱面值。具体算式是( 41H-1) ×2×2+ 05H。
第三段第一个字节(编号是 465H)的值,还可以用来判断下一个逻辑驱动器是否是硬盘上的最后一个。因为在 CHS寻址方式中,扇区不可能为 0。只有在硬盘最后一个逻辑驱动器上,因为没有第二个分区表项,所以该字节为 0。
对分区表数据的解读和处理,是进行物理扇区读写编程的重点内容。为了加深印象,根据上面计算出的 CHS地址,用 DEBUG将D盘的分区链表记录读出来,扇区地址是 261柱面 0磁头 1扇区。
-a 100
1cH 29-32 4 隐藏扇区数
20H 33-36 4 逻辑驱动器总扇区数
-g
-d 200 l200
-q
在图 2-1中,位移从 00H到 1bdH就是主引导记录。如果用编号来表示字节,设起始号为 1,就是从第 1到第 446字节。为什么要换算成编号呢?因为在今后编写程序的源代码时,或者是手工编制扇区字节的数据时,某些场合用编号计算是比较方便的。
譬如在《工具篇》中介绍的读扇区工具程序,可以将每个扇区的 512个字节,按照每行 32个字节,一共 16行的格式显示在屏幕上。如果从 1开始编号,则感觉很有对称性,容易查找某一个字节。如果用位移值计算,就感觉不太方便。
字节位移是从 0开始计数,而字节编号是从 1开始编号,所以对同一个字节来说,字节编号的值要比字节位移的值大 1。
位移从 1beH到 1fdH是分区表,编号为 447到 510,有关分区表的内容在下一节讨论。
最后两个字节是结束标志 55 AA。因为两个字节组成一个字,存入硬盘的顺序是低字节在前,高字节在后,所以 55 AA写成十六进制应为 aa 55H。
结束标志 55 AA是查找系统数据扇区的标志,据此对扇区进行搜索,可用于寻找主引导记录、主分区表或分区链表所在的扇区地址。
2.2 分区表
分区表占用 0柱面 0磁头 1扇区的 64个字节,位移从 1beH到 1fdH。它共有四个分区表项,每个分区表项占 16个字节。一般只使用两个表项,另外两个表项全为 0。
分区表项的格式如表 2-1所示。(注:表 2-1中的偏移量和字节编号是第一个表项的值,后面的表项按照相同的规律递增)
表 2-1
偏移量 字节编号 字节 内容说明
1beH 447 1 BOOT ID: 80H表示可启动分区,否则为 00H
1bfH 448 1 分区起始磁头号
1caH 459-462 4 分区内扇区总数
通常说的分区表指的是主分区表,另外在扩展分区的每一个逻辑驱动器中,都有一个分区链表,对它们的解读方法基本是相同的。
下面将图 2-1中的两个分区表项单独列出来,详细进行分析。
分区表项一:(位移 1beH至 1cdH,编号 447到 462)
1 2 3 4 5 6 7 8
80 01 01 00 06 fe