_ _ (_) | | __ ____ __ _ _ _ _ __ ___ _ __ _ __ ___ | |_ \ \ / /\ \/ /| || | | || '_ ` _ \ | '_ \ | '_ \ / _ \| __| \ V / > < | || |_| || | | | | || |_) |_ | | | || __/| |_ \_/ /_/\_\| | \__,_||_| |_| |_|| .__/(_)|_| |_| \___| \__| _/ | | | |__/ |_| /---------------------------------------------------------------------------------------\ |>...................[ 磁盘分区引导记录DBR的简单分析 ]...................<| |>......................[ by nEINEI/vxjump.net ]......................<| |>......................[ 2012-02-21 ]......................<| \>...................... [ neineit_at_gmail.com ] ...................... drive parameter // 此时 DL,DH,CH,CL 将存储磁盘驱动器信息 seg000:0083 73 05 jnb short loc_8A ; cf = 0,读取成功则跳转loc_8A seg000:0085 B9 FF FF mov cx, 0FFFFh seg000:0088 8A F1 mov dh, cl seg000:008A seg000:008A loc_8A: seg000:008A 66 0F B6 C6 movzx eax, dh ; 最大磁头号 seg000:008E 40 inc ax seg000:008F 66 0F B6 D1 movzx edx, cl ; cl - 0~5 扇区数,,6,7柱面号高两位 seg000:0093 80 E2 3F and dl, 3Fh ; 取0~5bit数据 seg000:0096 F7 E2 mul dx ; ax = 磁头 * 扇区(Heads * Sectors) seg000:0098 86 CD xchg cl, ch seg000:009A C0 ED 06 shr ch, 6 ; 计算柱面号低6位 seg000:009D 41 inc cx ; 获得完整的柱面号数据0~9bit ,在cx中是总的柱面号 seg000:009E 66 0F B7 C9 movzx ecx, cx seg000:00A2 66 F7 E1 mul ecx ; 计算出最大磁盘空间( [Sectors * Heads] * Cylinders) seg000:00A5 66 A3 20 00 mov ds:20h, eax ; eax存储磁盘空间,我本机磁盘3ffc00,记录到ds->0x7c20地址 seg000:00A9 C3 retn seg000:00A9 get_disk_space endp // 准备拷贝分区数据到扩展段es中 seg000:0065 B8 00 0D mov ax, 0D00h seg000:0068 8E C0 mov es, ax ; 存放读如磁盘数据的缓存空间,es=0xd00 seg000:006A assume es:nothing seg000:006A 33 DB xor bx, bx seg000:006C C6 06 0E 00 10 mov byte ptr ds:0Eh, 10h ; ds:0Eh偏移存放保留扇区数,这里用作后面的计算 seg000:0071 E8 53 00 call call_read // 读取16个扇区数据到es段指向的内存中 seg000:00C7 call_read proc near seg000:00C7 seg000:00C7 66 60 pushad seg000:00C9 1E push ds seg000:00CA 06 push es seg000:00CB seg000:00CB loc_CB: seg000:00CB 66 A1 10 00 mov eax, ds:10h ; BPB->0X10 -- 始终为0,此处用来记录已经读取的扇区数 seg000:00CF 66 03 06 1C 00 add eax, ds:1Ch ; BPB->0X1C --隐藏扇区数 seg000:00D4 66 3B 06 20 00 cmp eax, ds:20h ; NTFS 未使用BPB->0X20 ,一般为0,此处已经被修改为记录磁盘空间大小 seg000:00D4 seg000:00D9 0F 82 3A 00 jb loc_117 // 正常,跳转 seg000:00DD 1E push ds seg000:00DE 66 6A 00 push large 0 seg000:00E1 66 50 push eax seg000:00E3 06 push es seg000:00E4 53 push bx seg000:00E5 66 68 10 00 01+ push large 10010h seg000:00EB 80 3E 14 00 00 cmp byte ptr ds:14h, 0 seg000:00F0 0F 85 0C 00 jnz loc_100 seg000:00F4 E8 B3 FF call sub_AA // 检查是否支持扩展int 13 seg000:00F7 80 3E 14 00 00 cmp byte ptr ds:14h, 0 seg000:00FC 0F 84 61 00 jz loc_161 // 不支持扩展int 13读,出错,打印"A disk read error...“ seg000:0100 // 扩展int13读 seg000:0100 loc_100: seg000:0100 B4 42 mov ah, 42h ; 'B' seg000:0102 8A 16 24 00 mov dl, ds:24h seg000:0106 16 push ss seg000:0107 1F pop ds seg000:0108 assume ds:nothing seg000:0108 8B F4 mov si, sp seg000:010A CD 13 int 13h ; DISK - IBM/MS Extension - EXTENDED READ (DL - drive, DS:SI - disk address packet) seg000:010C 66 58 pop eax seg000:010E 5B pop bx seg000:010F 07 pop es seg000:0110 assume es:nothing seg000:0110 66 58 pop eax seg000:0112 66 58 pop eax seg000:0114 1F pop ds seg000:0115 EB 2D jmp short loc_144 seg000:0117 ; --------------------------------------------------------------------------- seg000:0117 // 正常会执行到这里,读取循环每次读取1个扇区数据,将读取出来的数据放到了,es:bx 指向的空间 seg000:0117 loc_117: seg000:0117 66 33 D2 xor edx, edx seg000:011A 66 0F B7 0E 18+ movzx ecx, ds:word_18 ; BPB->0X18 每磁道扇区数 seg000:0120 66 F7 F1 div ecx seg000:0123 FE C2 inc dl seg000:0125 8A CA mov cl, dl seg000:0127 66 8B D0 mov edx, eax seg000:012A 66 C1 EA 10 shr edx, 10h seg000:012E F7 36 1A 00 div ds:word_1A ; BPB->0X1A 磁头数 seg000:0132 86 D6 xchg dl, dh seg000:0134 8A 16 24 00 mov dl, ds:byte_24 ; BPB-0X24 ,物理驱动器号 seg000:0138 8A E8 mov ch, al seg000:013A C0 E4 06 shl ah, 6 seg000:013D 0A CC or cl, ah seg000:013F B8 01 02 mov ax, 201h ; AH -0X02 ,int13 读扇区 seg000:013F ; AL - 0X01, 读1个扇区 seg000:013F ; DL - 0x80,读硬盘驱动器 seg000:013F ; DH - 0x01, 所读的磁头号 seg000:013F ; CH - 0X00, 所读柱面号,低8bit seg000:013F ; CL - 0X01, 扇区号+柱面号高2bit seg000:013F ; seg000:013F ; 输出:es:bx== 0xd00:0 ,存放读出来的扇区数据 seg000:0142 CD 13 int 13h ; DISK - READ SECTORS INTO MEMORY seg000:0142 ; AL = number of sectors to read, CH = track, CL = sector seg000:0142 ; DH = head, DL = drive, ES:BX -> buffer to fill seg000:0142 ; Return: CF set on error, AH = status, AL = number of sectors read seg000:0144 // 读取完毕es:bx 指针下移0x200个字节 seg000:0144 loc_144: seg000:0144 0F 82 19 00 jb loc_161 seg000:0148 8C C0 mov ax, es seg000:014A 05 20 00 add ax, 20h ; ' ' ; buffer 下移200个字节,为了继续读下一个扇区 seg000:014D 8E C0 mov es, ax seg000:014F assume es:nothing seg000:014F 66 FF 06 10 00 inc ds:dword_10 ; BPB->0X10 数值加1 seg000:0154 FF 0E 0E 00 dec ds:word_E ; 保留扇区数字减1,初始值为0xf,当为0时,不再读取 seg000:0158 0F 85 6F FF jnz loc_CB ; BPB->0X10 -- 始终为0,此处用来记录已经读取的扇区数,每次加1 seg000:015C 07 pop es ; 读取16个扇区数据完毕 seg000:015D assume es:nothing seg000:015D 1F pop ds seg000:015E 66 61 popad seg000:0160 C3 retn----------------------------返回到这里----\ seg000:0161 | | ---------------------------------------------------------------------------------------/ | \|/ seg000:0074 68 00 0D push 0D00h seg000:0077 68 6A 02 push 26Ah seg000:007A CB retf // 段地址:偏移 =》0xD00:026A ,跳向了0xd26a地址,即ntldr部分 此时内存中的数据情况: 0xd000 = 60*10 +0xca00 这里开始计算 ---| | 0060:C9FA EB 52 90 4E 54 46 53 20 20 20 ......隦怤TFS 0060:CA0A 20 00 02 04 00 00 00 00 00 00 00 F8 00 00 3F 00 ..........?.?. 0060:CA1A 80 00 3F 00 00 00 00 00 00 00 80 00 80 00 40 DC .?.........@? 0060:CA2A 3F 00 00 00 00 00 5A 52 05 00 00 00 00 00 88 FB ?.....ZR......堺 0060:CA3A 07 00 00 00 00 00 F6 00 00 00 02 00 00 00 88 F1 ......?......堮 0060:CA4A 34 B0 23 35 B0 B0 00 00 00 00 FA 33 C0 8E D0 BC 4?5鞍....?缼屑 0060:CA5A 00 7C FB B8 C0 07 8E D8 E8 16 00 B8 00 0D 8E C0 .|?庁?.?.幚 0060:CA6A 33 DB C6 06 0E 00 10 E8 53 00 68 00 0D 68 6A 02 3燮....鑃.h..hj. 0060:CA7A CB 8A 16 24 00 B4 08 CD 13 73 05 B9 FF FF 8A F1 藠.$.??s.?婑 0060:CA8A 66 0F B6 C6 40 66 0F B6 D1 80 E2 3F F7 E2 86 CD f.镀@f.堆?麾喭 0060:CA9A C0 ED 06 41 66 0F B7 C9 66 F7 E1 66 A3 20 00 C3 理.Af.飞f麽f?.? 0060:CAAA B4 41 BB AA 55 8A 16 24 00 CD 13 72 0F 81 FB 55 碅华U?$.?r.侞U 0060:CABA AA 75 09 F6 C1 01 74 04 FE 06 14 00 C3 66 60 1E 猽.隽.t.?..胒`. 0060:CACA 06 66 A1 10 00 66 03 06 1C 00 66 3B 06 20 00 0F .f?.f....f;. .. 0060:CADA 82 3A 00 1E 66 6A 00 66 50 06 53 66 68 10 00 01 ?..fj.fP.Sfh... 0060:CAEA 00 80 3E 14 00 00 0F 85 0C 00 E8 B3 FF 80 3E 14 .>....?.璩>. 0060:CAFA 00 00 0F 84 61 00 B4 42 8A 16 24 00 16 1F 8B F4 ...刟.碆?$...嬼 0060:CB0A CD 13 66 58 5B 07 66 58 66 58 1F EB 2D 66 33 D2 ?fX[.fXfX.?f3? 0060:CB1A 66 0F B7 0E 18 00 66 F7 F1 FE C2 8A CA 66 8B D0 f.?..f黢娛f嬓 0060:CB2A 66 C1 EA 10 F7 36 1A 00 86 D6 8A 16 24 00 8A E8 f陵.?..喼?$.婅 0060:CB3A C0 E4 06 0A CC B8 01 02 CD 13 0F 82 19 00 8C C0 冷..谈..?.?.尷 0060:CB4A 05 20 00 8E C0 66 FF 06 10 00 FF 0E 0E 00 0F 85 . .幚f.......? 0060:CB5A 6F FF 07 1F 66 61 C3 A0 F8 01 E8 09 00 A0 FB 01 o..fa脿??.狖. 0060:CB6A E8 03 00 FB EB FE B4 01 8B F0 AC 3C 00 74 09 B4 ?..嬸?.t.? 0060:CB7A 0E BB 07 00 CD 10 EB F2 C3 0D 0A 41 20 64 69 73 .?.?腧?.A dis 0060:CB8A 6B 20 72 65 61 64 20 65 72 72 6F 72 20 6F 63 63 k read error occ 0060:CB9A 75 72 72 65 64 00 0D 0A 4E 54 4C 44 52 20 69 73 urred...NTLDR is 0060:CBAA 20 6D 69 73 73 69 6E 67 00 0D 0A 4E 54 4C 44 52 missing...NTLDR 0060:CBBA 20 69 73 20 63 6F 6D 70 72 65 73 73 65 64 00 0D is compressed.. 0060:CBCA 0A 50 72 65 73 73 20 43 74 72 6C 2B 41 6C 74 2B .Press Ctrl+Alt+ 0060:CBDA 44 65 6C 20 74 6F 20 72 65 73 74 61 72 74 0D 0A Del to restart.. 0060:CBEA 00 00 00 00 00 00 00 00 00 00 00 00 00 00 83 A0 ..............儬 0060:CBFA B3 C9 00 00 55 AA 05 00 4E 00 54 00 4C 00 44 00 成..U?.N.T.L.D. 0060:CC0A 52 00 04 00 24 00 49 00 33 00 30 00 00 E0 00 00 R...$.I.3.0..?. 0060:CC1A 00 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .0.............. 0060:CC2A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0060:CC3A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0060:CC4A 00 00 00 00 00 00 00 00 00 00 00 00 EB 12 90 90 ............?悙 0060:CC5A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ //跳到这里执行代码 0060:CC6A 8C C8 8E D8 C1 E0 04 FA 8B E0 FB E8 03 FE 66 0F 屓庁拎.鷭帑?. 0060:CC7A B7 06 0B 00 66 0F B6 1E 0D 00 66 F7 E3 66 A3 4E ?..f.?..f縻f 0060:CC8A 02 66 8B 0E 40 00 80 F9 00 0F 8F 0E 00 F6 D9 66 .f?@.?.?.鲑f 0060:CC9A B8 01 00 00 00 66 D3 E0 EB 08 90 66 A1 4E 02 66 ?...f余?恌.f 0060:CCAA F7 E1 66 A3 52 02 66 0F B7 1E 0B 00 66 33 D2 66 麽f.f.?..f3襢 0060:CCBA F7 F3 66 A3 56 02 E8 71 04 66 8B 0E 4A 02 66 89 黧f.鑡.f?J.f? 0060:CCCA 0E 22 02 66 03 0E 52 02 66 89 0E 26 02 66 03 0E .".f..R.f?&.f.. 0060:CCDA 52 02 66 89 0E 2A 02 66 03 0E 52 02 66 89 0E 3A R.f?*.f..R.f?: 0060:CCEA 02 66 03 0E 52 02 66 89 0E 42 02 66 B8 90 00 00 .f..R.f?B.f笎.. 0060:CCFA 00 66 8B 0E 22 02 E8 5F 09 66 0B C0 0F 84 57 FE .f?".鑏.f.?刉? 0060:CD0A 66 A3 2E 02 66 B8 A0 00 00 00 66 8B 0E 26 02 E8 f?.f笭...f?&.? 0060:CD1A 46 09 66 A3 32 02 66 B8 B0 00 00 00 66 8B 0E 2A F.f?.f赴...f?* 0060:CD2A 02 E8 34 09 66 A3 36 02 66 A1 2E 02 66 0B C0 0F .?.f?.f?.f.? 0060:CD3A 84 24 FE 67 80 78 08 00 0F 85 1B FE 67 66 8D 50 ?x...?f峆 .... 关于BPB的信息说明可参考wikipedia: http://en.wikipedia.org/wiki/BIOS_parameter_block -----------------------EOF--------------------------------------------------------------