首页
社区
课程
招聘
[原创]FAT32简介(mbr/ebr/dpt/bpb/fat/fdt)
发表于: 2013-7-26 20:20 18964

[原创]FAT32简介(mbr/ebr/dpt/bpb/fat/fdt)

2013-7-26 20:20
18964

没上过大学,纯野路子。不当之处请指证。
当然,如果有人在这方面比我还菜的话,有以下话想说。
如果你看完了什么都没记住,这很正常。如果想简单地看明白,并记住点什么的话,还是自己动手分析计算。
我用到两个工具:       二进制编辑器程序010EDIT,论坛有,可供下载。  BOCHS,可去官网下载,免费的。如果软件不会用,请看帮助文件。

FAT32简介


图1

这是硬盘0磁头0道1扇区的内容,这部分内容一般是由分区程序生成,与操作系统无关。共三部分:硬盘主引导记录MBR(MAIN BOOT RECORD),分区表DPT(DISK PARTITION TABLE),分区结束标志(55AA)。其中MBR共446B,DPT64B,结束标志2B。MBR是一段引导程序,主要功能是检查DPT的有效性,找到活动分区,并将活动分区的第一扇区内容读入内存,并跳转到这段程序继续执行。

那么我们来看MBR具体是怎么执行的:
<bochs:4> u/200
00007c00: (                   &nbsp mov si, 0x7c00            ; be007c
00007c03: (                   &nbsp cli                       ; fa
——初始化堆栈段前关中断
00007c04: (                   &nbsp xor ax, ax                ; 33c0
00007c06: (                   &nbsp mov ss, ax                ; 8ed0
00007c08: (                   &nbsp mov sp, si                ; 8be6
00007c0a: (                   &nbsp sti                       ; fb
以下内容是将整个引导扇区内容复制到0:0600H开始的一段内存空间中,并跳转到061EH处继续执行MBR程序。
00007c0b: (                   &nbsp mov ds, ax                ; 8ed8
00007c0d: (                   &nbsp mov es, ax                ; 8ec0
00007c0f: (                   &nbsp push ax                   ; 50
00007c10: (                   &nbsp mov ax, 0x061e            ; b81e06
00007c13: (                   &nbsp push ax                   ; 50
00007c14: (                   &nbsp mov di, 0x0600            ; bf0006
00007c17: (                   &nbsp mov cx, 0x0100            ; b90001
00007c1a: (                   &nbsp cld                       ; fc
00007c1b: (                   &nbsp rep movsw word ptr es:[di], word ptr ds:[si] ;
f3a5
00007c1d: (                   &nbsp retf                      ; cb

00007c1e: (                   &nbsp mov bx, 0x0763            ; bb6307
00007c21: (                   &nbsp mov si, 0x07be            ; bebe07
00007c24: (                   &nbsp mov ax, 0x0031            ; b83100
00007c27: (                   &nbsp cmp byte ptr ds:[si], 0x80 ; 803c80

DS:[SI]相当于0x7be-0x600=0x1be。而从上图中看0x1be正是DPT开始的字节。
下面我们来看DPT的结构。DPT分为四个表项,各占16字节,每一表项描述一个分区,所以最多可以有四个分区。但现在的用法一般是:第一项描述主分区,第二项描述扩展分区,第三第四项为0。每一表项的不同字节意义如下:

第0字节 是否为活动分区,是则为80H,否则为00H

第1字节 该分区起始磁头号

第2字节 该分区起始扇区号(低6位)和起始柱磁头号(高2位)

第3字节 该分区起始柱面号的低8位

第4字节 系统标志,00H表该分区未使用,06H表高版本DOS系统,05H扩展DOS分区,65H表Netwear分区

第5字节 该分区结束磁头号

第6字节 该分区结束扇区号(低6位)和结束柱面号(高2位)

第7字节 该分区结束柱面号的低8位

第8~11字节 相对扇区号,该分区起始的相对逻辑扇区号,高位在后低位在前

第12~15字节 该分区所用扇区数,高位在后,低位在前

以上蓝字内容是复制的。我们只要知道0字节处,80H代表活动分区。那我们接着看MBR程序下面要做什么

00007c2a: (                   &nbsp jnz .+9                   ; 7509
因为17BE处的内容为80H,所以第一次执行此程序段时这个跳转不会发生。但也说明活动分区并不一定要是第一个分区。跳转的位置为:00007C35
00007c2c: (                   &nbsp inc bx                    ; 43
原来BX内容为0X0763,而0X0764-0X600=0X0164(图1中),所以下条指令改写的是图1中0X0164中的内容
00007c2d: (                   &nbsp mov byte ptr ds:[bx], al  ; 8807   AL=31H
00007c2f: (                   &nbsp inc bx                    ; 43
00007c30: (                   &nbsp mov byte ptr ds:[bx], 0x2f ; c6072f此时图1中字0X0164中的内容变为:2F31H
00007c33: (                   &nbsp inc ah                    ; fec4

00007c35: (                   &nbsp add si, 0x0010            ; 83c610
检查第二个表项
00007c38: (                   &nbsp inc al                    ; fec0
00007c3a: (                   &nbsp cmp al, 0x35              ; 3c35
00007c3c: (                   &nbsp jb .-23                   ; 72e9
跳转到00007C27处,当AL=35H,四个表项全部检查完毕,向下执行
00007c3e: (                   &nbsp mov byte ptr ds:[bx], 0x3f ; c6073f
此时BX=0765。但如果有两个活动分区,或者四个活动分区则BX值增量。
00007c41: (                   &nbsp inc bx                    ; 43
00007c42: (                   &nbsp mov word ptr ds:[bx], 0x0020 ; c7072000
00007c46: (                   &nbsp or ah, ah                 ; 0ae4
AH记录活动分区的个数:这里为1
00007c48: (                   &nbsp jnz .+6                   ; 7506
跳转至00007C50
00007c4a: (                   &nbsp mov bx, 0x06f8            ; bbf806
00007c4d: (                   &nbsp jmp .+137                 ; e98900
如果没有活动分区,则跳转至00007CD9,调用一个过程显示一段:No partition bootable(在图1中地址0F8H处)的信息。
00007c50: (                   &nbsp mov al, byte ptr ds:0x764 ; a06407
00007c53: (                   &nbsp cmp ah, 0x02              ; 80fc02
00007c56: (                   &nbsp jb .+53                   ; 7235
跳转至00007c8d,如果有两个以上活动分区则不跳转
00007c58: (                   &nbsp mov bx, 0x0744            ; bb4407
00007c5b: (                   &nbsp call .+128                ; e88000
跳至7CDE显示一段信息:Enter patrtition # to boot from, (后面的内容就是前面检查活动分区时修改的从0X164开始的一段数据)1/2/3/4?。并调用INT16H取得键盘输入,选择从哪里BOOT。
00007c5e: (                   &nbsp jmp .+5                   ; eb05
00007c60: (                   &nbsp mov al, 0x07              ; b007
00007c62: (                   &nbsp call .+133                ; e88500
00007c65: (                   &nbsp xor ah, ah                ; 32e4
00007c67: (                   &nbsp int 0x16                  ; cd16
00007c69: (                   &nbsp mov byte ptr ds:0x782, al ; a28207
00007c6c: (                   &nbsp mov cl, 0x04              ; b104
00007c6e: (                   &nbsp sub al, 0x31              ; 2c31
00007c70: (                   &nbsp jb .-18                   ; 72ee
00007c72: (                   &nbsp cmp al, cl                ; 3ac1
00007c74: (                   &nbsp jnb .-22                  ; 73ea
00007c76: (                   &nbsp shl al, cl                ; d2e0
00007c78: (                   &nbsp xor ah, ah                ; 32e4
00007c7a: (                   &nbsp add ax, 0x07be            ; 05be07
00007c7d: (                   &nbsp mov si, ax                ; 8bf0
00007c7f: (                   &nbsp cmp byte ptr ds:[si], 0x80 ; 803c80
00007c82: (                   &nbsp jnz .-36                  ; 75dc
00007c84: (                   &nbsp mov bx, 0x0782            ; bb8207
00007c87: (                   &nbsp call .+84                 ; e85400
00007c8a: (                   &nbsp mov al, byte ptr ds:0x782 ; a08207
00007c8d: (                   &nbsp sub al, 0x31              ; 2c31
00007c8f: (                   &nbsp mov cl, 0x04              ; b104
00007c91: (                   &nbsp shl al, cl                ; d2e0
00007c93: (                   &nbsp xor ah, ah                ; 32e4
00007c95: (                   &nbsp add ax, 0x07be            ; 05be07
00007c98: (                   &nbsp mov word ptr ds:0x6f6, ax ; a3f606
00007c9b: (                   &nbsp mov cx, 0x0005            ; b90500
00007c9e: (                   &nbsp push cx                   ; 51
00007c9f: (                   &nbsp mov si, word ptr ds:0x6f6 ; 8b36f606
00007ca3: (                   &nbsp mov dx, word ptr ds:[si]  ; 8b14
Ds[si]内容为图1中地址01BE处内容。也就是DPT的首字。
00007ca5: (                   &nbsp mov cx, word ptr ds:[si+2] ; 8b4c02
00007ca8: (                   &nbsp mov bx, 0x7c00            ; bb007c
00007cab: (                   &nbsp mov ax, 0x0201            ; b80102
00007cae: (                   &nbsp int 0x13                  ; cd13
此时,DX=0180,CX=0001,BX=7C00,所以是将硬盘1磁头,0柱面,1扇区的内容读入7C00起始的内存中。我认为这段程序是存在BUG的。当活动分区的起始柱面号大于FFH时就会出错,什么时候柱面号会大于FFH,细看DPT后就会明了。
00007cb0: (                   &nbsp pop cx                    ; 59
00007cb1: (                   &nbsp jnb .+18                  ; 7312
读盘成功跳转至00007cc5。否则执行磁盘复位,重复读盘或显示出错信息
00007cb3: (                   &nbsp push ax                   ; 50
00007cb4: (                   &nbsp xor ax, ax                ; 33c0
00007cb6: (                   &nbsp int 0x13                  ; cd13
00007cb8: (                   &nbsp pop ax                    ; 58
00007cb9: (                   &nbsp cmp ah, 0x80              ; 80fc80
00007cbc: (                   &nbsp jz .+2                    ; 7402
00007cbe: (                   &nbsp loop .-34                 ; e2de
00007cc0: (                   &nbsp mov bx, 0x0724            ; bb2407
00007cc3: (                   &nbsp jmp .+20                  ; eb14
00007cc5: (                   &nbsp mov bx, 0x7c00            ; bb007c
00007cc8: (                   &nbsp cmp word ptr ds:[bx+510], 0xaa55 ; 81bffe0155aa
  检查1磁头,0道,1扇区的分区表结束标志的有效性。
00007cce: (                   &nbsp jnz .+6                   ; 7506
00007cd0: (                   &nbsp mov si, word ptr ds:0x6f6 ; 8b36f606
00007cd4: (                   &nbsp push bx                   ; 53
00007cd5: (                   &nbsp ret                       ; c3
00007cd6: (                   &nbsp mov bx, 0x070f            ; bb0f07
00007cd9: (                   &nbsp call .+2                  ; e80200
00007cdc: (                   &nbsp jmp .-2                   ; ebfe
00007cde: (                   &nbsp mov al, byte ptr ds:[bx]  ; 8a07
00007ce0: (                   &nbsp or al, al                 ; 0ac0
00007ce2: (                   &nbsp jz .+17                   ; 7411
00007ce4: (                   &nbsp call .+3                  ; e80300
00007ce7: (                   &nbsp inc bx                    ; 43
00007ce8: (                   &nbsp jmp .-12                  ; ebf4
00007cea: (                   &nbsp push ax                   ; 50
00007ceb: (                   &nbsp push bx                   ; 53
00007cec: (                   &nbsp mov ah, 0x0e              ; b40e
00007cee: (                   &nbsp mov bx, 0x0007            ; bb0700
00007cf1: (                   &nbsp int 0x10                  ; cd10
00007cf3: (                   &nbsp pop bx                    ; 5b
00007cf4: (                   &nbsp pop ax                    ; 58
00007cf5: (                   &nbsp ret                       ; c3
00007cf6: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000

<bochs:5>
现在,我们先放过MBR的内容,现在开始看分区表DPT。其实,没有注释部分的MBR内容,已经比较明了了。
我们将图1中主分区与扩展分区的描述项的内容写在下面:
80         01        01 00         0C         FE FF FF         3F 00 00 00         02 AB 10 03
00        00         C1 FF        0F         FE FF FF         41 AB 10 03         40 9A 0B 1A
先看主分区:80表示活动分区。01表示分区开始于1面或者1磁头。01 00,分区开始的扇区号和柱面号。这些在MBR程序中已做过介绍。
那么接下来0C,是系统标志,0C代表的含义是,FAT32,使用LBA模式和扩展的INT 13H。另外,FAT32还用0B表示,但0B的意义与0C是有区别的,分区格式小于等于8.4GB(实际可能是7.8);但无论是0B还是0C基本没什么意义,大容量磁盘都不再会使用CHS模式来访问磁盘,而使用LBA(LBA28/LBA48等),而更大容量的磁盘甚至不再使用MBR分区格式,而是使用GPT分区格式,每个分区可以大于2TB,但我没有64位机,完全不懂。这这也是我们在研究MBR程序时说的INT13H使用上存在BUG的原因。因为每个磁道只能有111111B-1个扇区(扇区数从1开始),每个柱面的磁头号有FE个。DPT格式中柱面号最多可以表示到1111111111B(1024)个,但现在的磁盘都会超过个数,我们经常会看到EF FF FF,但这里的柱面号可能已经超过了1024,但仍然这样表示。所以,通过此项来计算分区起始或分区大小是不准确的。
NTFC的话则为07。
FE FF FF 是分区结束的磁头,扇区和柱面。通过这一项可以算出分区的大小,但前面我们刚刚说过这个是不准确的。
3F 00 00 00这个是硬盘的稳含扇区,也就是此分区的到引导区之间的扇区数目。意思是这样的,双字0000003F个扇区占多少个字节:3F*200H=7E00H,于是我们找到硬盘数据7E00H地址,看一下这个扇区。


图2

我们再看一下C盘的数据,比较发现,C盘的数据地址00H起至200H的内容与这一扇区的内容是完全一样的。其实这就是主分区的扩展引导记录EBR(EXTAND BOOT RECORD),而活动磁盘上的EBR我们又称为:第二引导扇区或系统引导扇区DBR(DOS BOOT RECORD)。也是MBR程序要读取到内存7C00H地址处的内容。这也是C盘的开始扇区。所以上文称MBR为硬盘主引导记录,而不是C盘主引导记录。
02 AB 10 03表示分区的大小(扇区数)。分区的字节数是:0310AB02*200H=621560400H,那么,621560400H+7E00H处是什么内容呢?


图3

这是哪里呢?首先这不是D盘的第一扇区。但这个扇区却有一个DPT。根据我们计算的过程,主分区应该是在这一扇区的上一扇区结束。那么这里是扩展分区的开始扇区。我们看一下扩展分区与主引导扇区间的扇区数为:41 AB 10 03。字节数为:0310AB41*200H=621568200H,正好与图3中的地址吻合。那么扩展分区的大小:40 9A 0B 1A。1A0B9A40*200H=3417348000H,再加上621568200H,减1正好是硬盘结束的地址:3A388B01FFH。

再看主分区,将621568200H-1,是主分区结束的字节地址。但是C盘却是在620917FFFH处结束。C盘共620918000H个字节,这个数字与WINDOWS看到的C盘容量(26316210176)是相同的。比主分区少了0C48400H个字节,这些字节在C盘之后。那么主分区不是C盘,C盘包含在主分区里。

现在看图3,这里的DPT也有两个分区表项。这里的DPT是主引导扇区分区表中扩展分区的再分区表。暂称作第二分区

第二分区的主分区(第二主分区):00 01 C1 FF 0B FE FF FF 3F 00 00 00 00 4F D5 92 09 。非活动分区,开始磁头号为1,扇区号与柱面号为:C1 FF。结束磁头,扇区,柱面号为:FE FF FF。主分区距分区表的字节数是7E00,而这也与D盘的00H处的数据是相同的。D盘开始于第一扩展分区7E00字节处。在硬盘中的地址为621570000H。第二主分区的大小为:0992D54F*200H=1325AA9E00H。D盘大小为:1324780000H比第二主分区小  1329E00H字节,距第二扩展分区1331A00H字节。

我们看到不仅C盘比第一分区的主分区小,D盘比第二分区的主分区小。那么C盘前面的60几个扇区,D盘前面和后面的扇区做什么用了呢?其实这些都是系统隐藏扇区,系统是无法访问的,除分区表的空间外,其他可以存储一些我们要保密的数据,在这里的数据通常情况下是安全的。但也许我们并不想要这些隐藏扇区,毕竟这些扇区也不是绝对安全的,至少破坏MBR的病毒就能找到这些扇区。要简单地解决这个问题现在只有一个办法:不使用MBR格式的分区,而使用GPT分区格式。因为MBR分区格式,必须是以柱面为单位的。不能对柱面进行分割。

好了,我们再看DPT分区表。DPT分区表的数据结构好像是一个单链表,第一分区:主分区地址,扩展分区地址指向下一个DPT分区表,NULL,NULL。第二分区:第二主分区地址,第二扩展分区地址指向第三分区DPT表,NULL,NULL。于是我们得出结论:最后一个分区:最后一个主分区地址,NULL,NULL,NULL。DPT中只要使用两个表项就可以做到很多个分区。以前的许多资料也是这样介绍DPT数据结构的。但我们通过DPT表寻找分区时并不是一帆风顺的,比如我的硬盘,230G,分为CDEF四个区,而第三分区DPT表扩展分区的隐含扇区却不是相对于第三分区分区表所在扇区的,而是相对于第二分区分区表所在扇区。原因我还不知道,是不是因为第四字节?哪位大神知道告诉我。

那么我们继续,我们看图二。DBR中也包括三部分内容:DBR程序,本分区参数记录表BPB(BIOS PARAMETER BLOCK)和结束标记55AA。这部分内容由高级格式化程序生成(与操作系统相关)。DBR程序的主要功能是判断本分区根目录前的两个文件是否是系统引导文件,并把第一个文件读入内存,并将控制权交给该文件。DBR程序从扇区0字节开始,前三个字节利用一个短转移+NOP指令(NOP指令一般是由编译器生成的,具体请参照汇编编译器关于JMP指令的编译)跳过从03H——59H共57H字节的BPB。

下面是图二中的内容的反汇编

<bochs:4> u/280
00007c00: (                   &nbsp jmp .+88                  ; eb58
跳转至7C5A
00007c02: (                   &nbsp nop                       ; 90

00007c5a: (                   &nbsp xor cx, cx                ; 33c9
00007c5c: (                   &nbsp mov ss, cx                ; 8ed1
00007c5e: (                   &nbsp mov sp, 0x7bf4            ; bcf47b
00007c61: (                   &nbsp mov es, cx                ; 8ec1
00007c63: (                   &nbsp mov ds, cx                ; 8ed9
00007c65: (                   &nbsp mov bp, 0x7c00            ; bd007c
00007c68: (                   &nbsp mov byte ptr ss:[bp+2], cl ; 884e02
00007c6b: (                   &nbsp mov dl, byte ptr ss:[bp+64] ; 8a5640
图2中偏移40H处的一个字节,是INT13H中断呼叫预设值,软盘为00H,硬盘为:80H
00007c6e: (                   &nbsp mov ah, 0x08              ; b408
00007c70: (                   &nbsp int 0x13                  ; cd13
00007c72: (                   &nbsp jnb .+5                   ; 7305
跳至00007C79。调用INT13H的8H号功能获取磁盘参数。INT13H的这一功能我不了解,听说,当磁盘大于8G时应当使用扩展的INT13H的48H号功能。如果使用8号功能则CF=1。但对于我的250G的硬盘,C盘24.5G,执行8号功能后,CF=0,而CX=FEFF,DX=FE01。所以这里肯定有没搞明白的地方。
00007c74: (                   &nbsp mov cx, 0xffff            ; b9ffff
00007c77: (                   &nbsp mov dh, cl                ; 8af1
00007c79: (                   &nbsp movzx eax, dh             ; 660fb6c6
00007c7d: (                   &nbsp inc ax                    ; 40
00007c7e: (                   &nbsp movzx edx, cl             ; 660fb6d1
00007c82: (                   &nbsp and dl, 0x3f              ; 80e23f
00007c85: (                   &nbsp mul ax, dx                ; f7e2
00007c87: (                   &nbsp xchg ch, cl               ; 86cd
00007c89: (                   &nbsp shr ch, 0x06              ; c0ed06
00007c8c: (                   &nbsp inc cx                    ; 41
00007c8d: (                   &nbsp movzx ecx, cx             ; 660fb7c9
00007c91: (                   &nbsp mul eax, ecx              ; 66f7e1
将CHS换算成LBA线性地址
00007c94: (                   &nbsp mov dword ptr ss:[bp-8], eax ; 668946f8
00007c98: (                   &nbsp cmp word ptr ss:[bp+22], 0x0000 ; 837e1600
00007c9c: (                   &nbsp jnz .+56                  ; 7538
图二中相对扇区起始偏移16 H地址处的一个字表示FAT16文件分配表的长度,FAT32位则为零
00007c9e: (                   &nbsp cmp word ptr ss:[bp+42], 0x0000 ; 837e2a00
00007ca2: (                   &nbsp jnbe .+50                 ; 7732
图2相对扇区起始偏移2AH处的两个字节表示文件系统的主次版本。这里为0不跳转
00007ca4: (                   &nbsp mov eax, dword ptr ss:[bp+28] ; 668b461c
图2相对扇区起始偏移1C处的一个双字,表示分区前隐藏扇区数目,也就是分区表到EBR的扇区偏移。
00007ca8: (                   &nbsp add eax, 0x0000000c       ; 6683c00c
至于这里为什么是0CH,可能是MS公司规定的。
00007cac: (                   &nbsp mov bx, 0x8000            ; bb0080
00007caf: (                   &nbsp mov cx, 0x0001            ; b90100
00007cb2: (                   &nbsp call .+43                 ; e82b00
转移至00007ce0。7CE0处是一个过程,将会把相对分区表偏移EAX个扇区开始的共ECX个扇区内容装入内存ES:BX处。
00007cb5: (                   &nbsp jmp .+840                 ; e94803
跳转至:0X:8000,也就是将系统控制权交给硬盘相对MBR扇区偏移3FH+CH扇区存放的程序。为了更深入理解BPB我们还要对这个程序进行分析。我们暂称这个程序为操作系统引导程序。
00007cb8: (                   &nbsp mov al, byte ptr ds:0x7dfa ; a0fa7d
由此可以看出图二中相对扇区起始偏移01F9至01FB存放的数据是出错信息相对扇区起始偏移地址的低八位。以下显示一段信息:Disk erro 换行Press any key to restart
00007cbb: (                   &nbsp mov ah, 0x7d              ; b47d
00007cbd: (                   &nbsp mov si, ax                ; 8bf0
00007cbf: (                   &nbsp lodsb al, byte ptr ds:[si] ; ac
00007cc0: (                   &nbsp test al, al               ; 84c0
00007cc2: (                   &nbsp jz .+23                   ; 7417
DBR中的出错信息共三行,用FFH间隔,用00H结束,当显示完Press any key to restart后则执行7CDB处的CBW命令。等待输入重新运行MBR。
00007cc4: (                   &nbsp cmp al, 0xff              ; 3cff
00007cc6: (                   &nbsp jz .+9                    ; 7409
00007cc8: (                   &nbsp mov ah, 0x0e              ; b40e
00007cca: (                   &nbsp mov bx, 0x0007            ; bb0700
00007ccd: (                   &nbsp int 0x10                  ; cd10
00007ccf: (                   &nbsp jmp .-18                  ; ebee
跳至7CBF
00007cd1: (                   &nbsp mov al, byte ptr ds:0x7dfb ; a0fb7d
00007cd4: (                   &nbsp jmp .-27                  ; ebe5
00007cd6: (                   &nbsp mov al, byte ptr ds:0x7df9 ; a0f97d
00007cd9: (                   &nbsp jmp .-32                  ; ebe0
跳至7CBB
00007cdb: (                   &nbsp cbw                       ; 98
00007cdc: (                   &nbsp int 0x16                  ; cd16
00007cde: (                   &nbsp int 0x19                  ; cd19

过程开始
00007ce0: (                   &nbsp pushad                    ; 6660
00007ce2: (                   &nbsp cmp eax, dword ptr ss:[bp-8] ; 663b46f8
将EAX的值与前面利用INT13H获得的磁盘参数计算出的LBA线性扇区数比较,看是否超过此范围,。
00007ce6: (                   &nbsp jb .+74                   ; 0f824a00
未超范围则跳转至7d34,否则调用扩展的INT13H。
00007cea: (                   &nbsp push 0x00000000           ; 666a00
00007ced: (                   &nbsp push eax                  ; 6650
00007cef: (                   &nbsp push es                   ; 06
00007cf0: (                   &nbsp push bx                   ; 53
00007cf1: (                   &nbsp push 0x00010010           ; 666810000100
00007cf7: (                   &nbsp cmp byte ptr ss:[bp+2], 0x00 ; 807e0200
00007cfb: (                   &nbsp jnz .+32                  ; 0f852000
00007cff: (                   &nbsp mov ah, 0x41              ; b441
00007d01: (                   &nbsp mov bx, 0x55aa            ; bbaa55
00007d04: (                   &nbsp mov dl, byte ptr ss:[bp+64] ; 8a5640
00007d07: (                   &nbsp int 0x13                  ; cd13
检查INT13H扩展功能是否存在
00007d09: (                   &nbsp jb .+28                   ; 0f821c00
00007d0d: (                   &nbsp cmp bx, 0xaa55            ; 81fb55aa
00007d11: (                   &nbsp jnz .+20                  ; 0f851400
00007d15: (                   &nbsp test cl, 0x01             ; f6c101
00007d18: (                   &nbsp jz .+13                   ; 0f840d00
00007d1c: (                   &nbsp inc byte ptr ss:[bp+2]    ; fe4602
00007d1f: (                   &nbsp mov ah, 0x42              ; b442
00007d21: (                   &nbsp mov dl, byte ptr ss:[bp+64] ; 8a5640
00007d24: (                   &nbsp mov si, sp                ; 8bf4
00007d26: (                   &nbsp int 0x13                  ; cd13
扩展读
00007d28: (                   &nbsp mov al, 0xf9              ; b0f9
00007d2a: (                   &nbsp pop eax                   ; 6658
00007d2c: (                   &nbsp pop eax                   ; 6658
00007d2e: (                   &nbsp pop eax                   ; 6658
00007d30: (                   &nbsp pop eax                   ; 6658
00007d32: (                   &nbsp jmp .+42                  ; eb2a
00007d34: (                   &nbsp xor edx, edx              ; 6633d2
00007d37: (                   &nbsp movzx ecx, word ptr ss:[bp+24] ; 660fb74e18
图2扇区起始偏移18H处的两个字节表示:每磁道的扇区数。值为003F。
00007d3c: (                   &nbsp div eax, ecx              ; 66f7f1
00007d3f: (                   &nbsp inc dl                    ; fec2
00007d41: (                   &nbsp mov cl, dl                ; 8aca
00007d43: (                   &nbsp mov edx, eax              ; 668bd0
00007d46: (                   &nbsp shr edx, 0x10             ; 66c1ea10
00007d4a: (                   &nbsp div ax, word ptr ss:[bp+26] ; f7761a
图2中相对扇区起始偏移1A处的两个字节表示磁盘的磁头数,值为FFH
00007d4d: (                   &nbsp xchg dh, dl               ; 86d6
00007d4f: (                   &nbsp mov dl, byte ptr ss:[bp+64] ; 8a5640
40H处存放驱动器号
00007d52: (                   &nbsp mov ch, al                ; 8ae8
00007d54: (                   &nbsp shl ah, 0x06              ; c0e406
00007d57: (                   &nbsp or cl, ah                 ; 0acc
以上将LBA转换为CHS
00007d59: (                   &nbsp mov ax, 0x0201            ; b80102
00007d5c: (                   &nbsp int 0x13                  ; cd13
00007d5e: (                   &nbsp popad                     ; 6661
00007d60: (                   &nbsp jb .-172                  ; 0f8254ff
如果CF=1则跳至00007cb8
00007d64: (                   &nbsp add bx, 0x0200            ; 81c30002
00007d68: (                   &nbsp inc eax                   ; 6640
00007d6a: (                   &nbsp dec cx                    ; 49
00007d6b: (                   &nbsp jnz .-143                 ; 0f8571ff
00007d6f: (                   &nbsp ret                       ; c3

过程正常返回

00007d70: (                   &nbsp dec si                    ; 4e
00007d71: (                   &nbsp push sp                   ; 54
00007d72: (                   &nbsp dec sp                    ; 4c
00007d73: (                   &nbsp inc sp                    ; 44
00007d74: (                   &nbsp push dx                   ; 52
00007d75: (                   &nbsp and byte ptr ds:[bx+si], ah ; 2020
00007d77: (                   &nbsp and byte ptr ds:[bx+si], ah ; 2020
00007d79: (                   &nbsp and byte ptr ds:[bx+si], ah ; 2020
00007d7b: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007d7d: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007d7f: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007d81: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007d83: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007d85: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007d87: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007d89: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007d8b: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007d8d: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007d8f: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007d91: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007d93: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007d95: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007d97: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007d99: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007d9b: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007d9d: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007d9f: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007da1: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007da3: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007da5: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007da7: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007da9: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007dab: (                   &nbsp add byte ptr ds:[di], cl  ; 000d
00007dad: (                   &nbsp or cl, byte ptr ss:[bp+84] ; 0a4e54
00007db0: (                   &nbsp dec sp                    ; 4c
00007db1: (                   &nbsp inc sp                    ; 44
00007db2: (                   &nbsp push dx                   ; 52
00007db3: (                   &nbsp and byte ptr ds:[bx+di+115], ch ; 206973
00007db6: (                   &nbsp and byte ptr ds:[di+105], ch ; 206d69
00007db9: (                   &nbsp jnb .+115                 ; 7373
00007dbb: (                   &nbsp imul bp, word ptr ss:[bp+103], 0x0dff ; 696e67
ff0d
00007dc0: (                   &nbsp or al, byte ptr ds:[si+105] ; 0a4469
00007dc3: (                   &nbsp jnb .+107                 ; 736b
00007dc5: (                   &nbsp and byte ptr ds:[di+114], ah ; 206572
00007dc8: (                   &nbsp jb .+111                  ; 726f
00007dca: (                   &nbsp jb .-1                    ; 72ff
00007dcc: (                   &nbsp or ax, 0x500a             ; 0d0a50
00007dcf: (                   &nbsp jb .+101                  ; 7265
00007dd1: (                   &nbsp jnb .+115                 ; 7373
00007dd3: (                   &nbsp and byte ptr ds:[bx+di+110], ah ; 20616e
00007dd6: (                   &nbsp jns .+32                  ; 7920
00007dd8: (                   &nbsp imul sp, word ptr ds:[di+121], 0x0020 ; 6b6579
20
00007ddc: (                   &nbsp jz .+111                  ; 746f
00007dde: (                   &nbsp and byte ptr ss:[bp+si+101], dh ; 207265
00007de1: (                   &nbsp jnb .+116                 ; 7374
00007de3: (                   &nbsp popa                      ; 61
00007de4: (                   &nbsp jb .+116                  ; 7274
00007de6: (                   &nbsp or ax, 0x000a             ; 0d0a00
00007de9: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007deb: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007ded: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007def: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007df1: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007df3: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007df5: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007df7: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00007df9: (                   &nbsp lodsb al, byte ptr ds:[si] ; ac
00007dfa: (                   &nbsp mov di, 0x00cc            ; bfcc00
00007dfd: (                   &nbsp add byte ptr ds:[di-86], dl ; 0055aa

下面是具体BPB各参数的意义:
FAT32系统:
0BH                2字节        每扇区的字节数一般为0200H。
0DH                1字节        每簇扇区数,取决于分区文件系统格式和分区大小。我的C盘上是20H
0EH                2字节        为操作系统保留的扇区数。也即逻辑盘引导区至文件分配表(FAT表)的偏移,以扇区为单位。图2中为26H
10H                1字节        FAT表的个数,一般为02H。
11H                2字节        FAT16中根目录中允许登记的目录项的个数。FAT32中为0。
13H                2字节        容量小于32MB时表示扇区数目,否则不使用,仅为兼容小磁盘,FAT32中为0
15H                1字节        磁盘介质类型,硬盘用F8表示。
16H                2字节        FAT16中文件分配表长度,FAT32中未使用,值为0
18H                2字节        每磁道扇区数。003F
1AH                2字节        磁盘磁头数。图二中0FFH表示255个磁头。
1CH                4字节        分区前隐藏的扇区数。即该分区分区表到引导扇区的扇区数目:0000003F
20H                4字节        逻辑盘的扇区总数。图二中为0310AAF0,即62155E000H字节。这个比C盘的实际容量:620918000H字节要大,而又比分区表DPT中所标识的字节数:621560400H要小。我们从硬盘上看,偏移0310AAF0+3F-1扇区之前都是有数据的。而从0310AAF0+3F至第一主分区结束则无数据存储,全部为0。
24H                4字节        每个FAT表所占扇区数目。
28H                2字节        FAT表镜像标志。0表示保存有两份FAT表互为备份,而1则只有一份。
2AH                2字节        文件系统主次版本(fat32系统保留未使用)
2CH                4字节        磁盘根目录起始簇号
30H                2字节        文件系统参数扇区号,通常为引导扇区的下一扇区。即01H
32H                2字节        备份分区引导扇区的扇区号
34H                12字节        保留未使用。
40H                1字节        磁盘号,为INT13H呼叫所做的预高值,80为硬盘,00为软盘
41H                1字节        用于中断13H呼叫
42H                1字节        磁盘读写参数扩展标志,值为29H
43H                4字节        格式化时随机产生的磁盘卷的序列号
47H                11字节        格式化时人工输入的磁盘卷标号
52H                8字节        文件系统标识号(FAT32)

而NTFC文件系统则不同,BPB的长度也不一样。
操作系统引导程序:


图4

00008000: (                   &nbsp movzx eax, byte ptr ss:[bp+16] ; 660fb64610
00008005: (                   &nbsp mov ecx, dword ptr ss:[bp+36] ; 668b4e24
00008009: (                   &nbsp mul eax, ecx              ; 66f7e1
0000800c: (                   &nbsp add eax, dword ptr ss:[bp+28] ; 6603461c
00008010: (                   &nbsp movzx edx, word ptr ss:[bp+14] ; 660fb7560e
00008015: (                   &nbsp add eax, edx              ; 6603c2
00008018: (                   &nbsp mov dword ptr ss:[bp-4], eax ; 668946fc
以上计算文件分配表结束后的第一个扇区相对硬盘0面0道1扇区的偏移。并存入内存7BFCH。
0000801c: (                   &nbsp mov dword ptr ss:[bp-12], 0xffffffff ; 66c746f
4ffffffff
00008024: (                   &nbsp mov eax, dword ptr ss:[bp+44] ; 668b462c
00008028: (                   &nbsp cmp eax, 0x00000002       ; 6683f802
0000802c: (                   &nbsp jb .-858                  ; 0f82a6fc
如果根目录起始簇数小于2则跳至7CD6显示一段出错信息:“NTLDR is missing”  另起行:“Press any key to restart”。为什么要与2进行比较,这与文件分配表FAT有关。FAT表中前两个表项(表项00,01)一般不用,而用来存储磁盘的介质类型。FAT32系统硬盘一般为F8 FF FF 0F  FF FF FF 0F。所以有效簇号是从2开始的。下面简介下FAT表


图6

图6是FAT表第一扇区的内容。FAT表的每一个表项是4字节。第0,1表项的值是F8 FF FF 0F  FF FF FF FF。和我们上面说的不一样?看完后面再来理解:FAT表项值只要大于等0FFFFFF8就意味着文件在此簇号结束,而0FFFFFF7(F7 FF FF 0F)则意味着坏簇。而下一行程序的数字0FFFFFF8也就可以理解了。所有小于这个数字并且大于1的数字都表示文件的下一簇号——文件往往一个簇放不下,那么就将文件用到的第一个簇号存在PDT中,找到这一簇号对应的FAT表项,则以下是一个链表,这个链表只有一个数据项:一个指针,指向下一个链表的地址。一个文件在PAT表中的各表项就是这样一个链表。当链表指向大于0FFFFFF8时,链表结束。
00008030: (                   &nbsp cmp eax, 0x0ffffff8       ; 663df8ffff0f
00008036: (                   &nbsp jnb .-868                 ; 0f839cfc   FC9C+803A=7CD6
0000803a: (                   &nbsp push eax                  ; 6650
0000803c: (                   &nbsp sub eax, 0x00000002       ; 6683e802
00008040: (                   &nbsp movzx ebx, byte ptr ss:[bp+13] ; 660fb65e0d
00008045: (                   &nbsp mov si, bx                ; 8bf3
00008047: (                   &nbsp mul eax, ebx              ; 66f7e3
0000804a: (                   &nbsp add eax, dword ptr ss:[bp-4] ; 660346fc
0000804e: (                   &nbsp mov bx, 0x8200            ; bb0082
00008051: (                   &nbsp mov di, bx                ; 8bfb
00008053: (                   &nbsp mov cx, 0x0001            ; b90100
00008056: (                   &nbsp call .-889                ; e887fc
调用7CE0过程。将相对0面0道1扇区偏移626FH扇区的一个扇区内容,读入内存8200H。
00008059: (                   &nbsp cmp byte ptr ds:[di], ch  ; 382d
0000805b: (                   &nbsp jz .+30                   ; 741e
1E+805D=807B
0000805d: (                   &nbsp mov cl, 0x0b              ; b10b
0000805f: (                   &nbsp push si                   ; 56
00008060: (                   &nbsp mov si, 0x7d70            ; be707d
00008063: (                   &nbsp rep cmpsb byte ptr es:[di], byte ptr ds:[si] ;
f3a6
在这里应当是REPE CMPSB 应该是反汇编的问题。这个操作其实是在文件目录表FDT(File Directory Table)中查找名称为NTLDR的文件,这个文件在C盘根目录。请看下面关于FDT的介绍。


图5

FDT中长文件名与否决定了表项长度,32B或64B。如果是64B则前32B为长文件名链接说明,后32字节为文件属性说明:文件长度,起始地址,日期时间等。不支持长文件名的情况下,只有32B的文件属性说明。具体来说:
0-7字节                文件名
8-A字节                文件扩展名
0B字节                文件属性。对于FAT32来讲,0至5位分别是只读位、隐藏位、系统位、卷标位、子目录位、归档位。最高两位保留未用
0C-0D字节        短文件名字节校验和
0E-0F字节        文件创建时间
10-11字节        文件创建日期
12-13字节        文件最近访问日期
14-15字节        文件存放的起始簇号高16位
16-17字节        文件最近修改时间
18-19字节        文件最近修改日期
1A-1B字节        文件存放的起始簇号低16位
1C-1F字节        文件长度(字节)
其中文件名部分,字节不足则用空格的ASCII码20填充。而0字节还有特别的含义。00表示空目录。E5表示被删除的文件,2E表示特殊文件“.”或“..”。其他值才表示文件名的第一个字符ASCII码。
00008065: (                   &nbsp pop si                    ; 5e
00008066: (                   &nbsp jz .+27                   ; 741b
8068+1B=8083。从图五可以看出当DI=8280H+0BH时跳转。
00008068: (                   &nbsp add di, cx                ; 03f9
0000806a: (                   &nbsp add di, 0x0015            ; 83c715
从805D到这里,相当于DI=DI+20H。
0000806d: (                   &nbsp cmp di, bx                ; 3bfb
0000806f: (                   &nbsp jb .-24                   ; 72e8
E8+71=59
00008071: (                   &nbsp dec si                    ; 4e
00008072: (                   &nbsp jnz .-38                  ; 75da
00008074: (                   &nbsp pop eax                   ; 6658
00008076: (                   &nbsp call .+101                ; e86500
00008079: (                   &nbsp jb .-65                   ; 72bf

0000807b: (                   &nbsp add sp, 0x0004            ; 83c404
0000807e: (                   &nbsp jmp .-939                 ; e955fc
FC55+8081=7CD6
00008081: (                   &nbsp add byte ptr ds:[bx+si], ah ; 0020

以下查找NTLDR的起始位置并将NTLDR文件完整地读入内存,并将系统控制仅交给NTLDR程序。
00008083: (                   &nbsp add sp, 0x0004            ; 83c404
00008086: (                   &nbsp mov si, word ptr ds:[di+9] ; 8b7509
SI=0
00008089: (                   &nbsp mov di, word ptr ds:[di+15] ; 8b7d0f
DI=F9A5
0000808c: (                   &nbsp mov ax, si                ; 8bc6
0000808e: (                   &nbsp shl eax, 0x10             ; 66c1e010
00008092: (                   &nbsp mov ax, di                ; 8bc7
00008094: (                   &nbsp cmp eax, 0x00000002       ; 6683f802
00008098: (                   &nbsp jb .-966                  ; 0f823afc
0000809c: (                   &nbsp cmp eax, 0x0ffffff8       ; 663df8ffff0f
000080a2: (                   &nbsp jnb .-976                 ; 0f8330fc
000080a6: (                   &nbsp push eax                  ; 6650
000080a8: (                   &nbsp sub eax, 0x00000002       ; 6683e802
000080ac: (                   &nbsp movzx ecx, byte ptr ss:[bp+13] ; 660fb64e0d
000080b1: (                   &nbsp mul eax, ecx              ; 66f7e1
000080b4: (                   &nbsp add eax, dword ptr ss:[bp-4] ; 660346fc
000080b8: (                   &nbsp mov bx, 0x0000            ; bb0000
000080bb: (                   &nbsp push es                   ; 06
000080bc: (                   &nbsp mov es, word ptr ds:0x8081 ; 8e068180
ES=2000,BX=0,EAX=1F96CFH
000080c0: (                   &nbsp call .-995                ; e81dfc
FC1D+80C3=7CE0
000080c3: (                   &nbsp pop es                    ; 07
ES=0
000080c4: (                   &nbsp pop eax                   ; 6658
EAX=F9A5
000080c6: (                   &nbsp shr bx, 0x04              ; c1eb04
000080c9: (                   &nbsp add word ptr ds:0x8081, bx ; 011e8180
将刚分配的字节数右移四位加到8081H处做为下一次分配内存的段地址。
000080cd: (                   &nbsp call .+14                 ; e80e00
80D0+0E=80DE
000080d0: (                   &nbsp jnb .+2                   ; 0f830200
000080d4: (                   &nbsp jb .-48                   ; 72d0
D0+80D6=8086,如果不是文件的最后一簇则重复读下一簇。NTLR共用10H个簇
000080d6: (                   &nbsp mov dl, byte ptr ss:[bp+64] ; 8a5640
000080d9: (                   &nbsp jmp far 2000:0000         ; ea00000020

000080de: (                   &nbsp shl eax, 0x02             ; 66c1e002
000080e2: (                   &nbsp call .+17                 ; e81100
80E5+11=80F6
000080e5: (                   &nbsp mov eax, dword ptr es:[bx+di] ; 26668b01
ES=0,DI=7E00,所以此时EAX的值等于NTLR文件起始簇号所对应FAT表项的值。
000080e9: (                   &nbsp and eax, 0x0fffffff       ; 6625ffffff0f
000080ef: (                   &nbsp cmp eax, 0x0ffffff8       ; 663df8ffff0f
而FAT表项的值,如果大于0FFFFFF8则表示此簇为文件的最后一簇,否则为文件存放的下一簇号。
000080f5: (                   &nbsp ret                       ; c3
下面的过程计算NTLR文件起始簇号所对应FAT表项的扇区(EAX)和相对扇区起始的偏移(EDX),将表项所在扇区相对0道0面1扇区的相对偏移,并将其读入内存7E00H处。而最终BX值等于FAT表中NTLR文件起始簇号所对应表项相对扇区开始的偏移。
000080f6: (                   &nbsp mov di, 0x7e00            ; bf007e
000080f9: (                   &nbsp movzx ecx, word ptr ss:[bp+11] ; 660fb74e0b
000080fe: (                   &nbsp xor edx, edx              ; 6633d2
00008101: (                   &nbsp div eax, ecx              ; 66f7f1
00008104: (                   &nbsp cmp eax, dword ptr ss:[bp-12] ; 663b46f4
00008108: (                   &nbsp jz .+58                   ; 743a
0000810a: (                   &nbsp mov dword ptr ss:[bp-12], eax ; 668946f4
0000810e: (                   &nbsp add eax, dword ptr ss:[bp+28] ; 6603461c
00008112: (                   &nbsp movzx ecx, word ptr ss:[bp+14] ; 660fb74e0e
00008117: (                   &nbsp add eax, ecx              ; 6603c1
0000811a: (                   &nbsp movzx ebx, word ptr ss:[bp+40] ; 660fb75e28
0000811f: (                   &nbsp and bx, 0x000f            ; 83e30f
00008122: (                   &nbsp jz .+22                   ; 7416
16+8124=813A
00008124: (                   &nbsp cmp bl, byte ptr ss:[bp+16] ; 3a5e10
00008127: (                   &nbsp jnb .-1109                ; 0f83abfb
FBAB+812B=7CD6H
0000812b: (                   &nbsp push dx                   ; 52
0000812c: (                   &nbsp mov ecx, eax              ; 668bc8
0000812f: (                   &nbsp mov eax, dword ptr ss:[bp+36] ; 668b4624
00008133: (                   &nbsp mul eax, ebx              ; 66f7e3
00008136: (                   &nbsp add eax, ecx              ; 6603c1
00008139: (                   &nbsp pop dx                    ; 5a

0000813a: (                   &nbsp push dx                   ; 52
0000813b: (                   &nbsp mov bx, di                ; 8bdf
0000813d: (                   &nbsp mov cx, 0x0001            ; b90100
00008140: (                   &nbsp call .-1123               ; e89dfb
FB9D+8143=7CE0H
00008143: (                   &nbsp pop dx                    ; 5a
00008144: (                   &nbsp mov bx, dx                ; 8bda
00008146: (                   &nbsp ret                       ; c3
00008147: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
00008149: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
000081f9: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
000081fb: (                   &nbsp add byte ptr ds:[bx+si], al ; 0000
000081fd: (                   &nbsp add byte ptr ds:[di-86], dl ; 0055aa

接下来跳至2000:00H处执行的程序就有点大了,20H个扇区,而实际上这个程序的有效字节大约在30000H多。这就可以做很多事情,比如:进入保护模式等,离主题越来越远了。
好了,我们回到正题。上面程序中是如何计算表项地址的?
FAT表项所在扇区相对FAT表起始扇区偏移扇区数(对应扇区)=对应簇号*4/200,因为每个FAT表项占4个字节。
FAT表项相对对应扇区偏移字节=对应簇号*4%200。
操作系统就是通过这种方法利用FDT和FAT查找并将文件读入内存。

紧接FDT的就是罗辑盘的DATA区。具体存放各种文件(以簇为单位)。当EBR,FAT,甚至FDT损坏后,其实,我们仍然可以通过搜索DATA区的办法来恢复文件。

注:本帖由看雪论坛志愿者PEstone 重新将DOC整理排版,若和原文有出入,以原作者附件为准


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 5
支持
分享
最新回复 (11)
雪    币: 101
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
楼主估计是下了不少功夫
2013-7-26 20:28
0
雪    币: 351
活跃值: (22)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
FAT32还算简单的
你看过刘伟写的那本数据恢复的书
并写过恢复类软件的话 对磁盘的理解会更深
2013-7-26 20:49
0
雪    币: 11096
活跃值: (17617)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
支持楼主。楼主没有上过大学,但很厉害
2013-7-26 21:02
0
雪    币: 20
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
标记下…!^_^
2013-7-26 22:08
0
雪    币: 396
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
很好,支持一下。
2013-7-26 22:41
0
雪    币: 524
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
标记一下
2013-8-4 17:25
0
雪    币: 23
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
看到楼上那些大牛,表示膜拜啊!
2013-8-5 08:35
0
雪    币: 25
活跃值: (77)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
励志哥呀
2013-8-8 15:03
0
雪    币: 33
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
分析的不错,顶一个。
2013-12-20 16:28
0
雪    币: 8
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
好多笑脸啊
2013-12-20 17:55
0
雪    币: 43
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
如果是NTFS简介就好了
2013-12-22 21:57
0
游客
登录 | 注册 方可回帖
返回
//