注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

熊猫正正的博客

熊猫正正的天空

 
 
 

日志

 
 

MBR 分析  

2012-03-09 00:00:17|  分类: BookKit学习与研 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
转自一毛的空间

大概描述下这段代码的用途:
1.BIOS 加电自检 ( Power On Self Test — POST )。BIOS执行内存地址为 FFFF:0000H 处的跳转指令,跳转到固化在ROM中的自检程序处,对系统硬件(包括内存)进行检查。
2.下面的代码(也就是磁盘的0柱面0磁道1扇区的代码)会被bios加载的内存地址0000:7c00h处,然后跳转的7c00处开始执行.
3.然后就是重头戏了,这段代码首先把自己复制到内存地址0000:0600h处(参见上面的Entry部分,为什么要挪地呢,后面会解释),然后跳到此处继续执行.
4.接下来就该查找活动分区了,因为我们的最终目的是引导操作系统,而操作系统一般都放在活动分区,所以要先查找活动分区(其实mbr里的大部代码都是在进行活动分区的查找与载入),如果不存在活动分区就显示错误信息然后当机,如果找到了还必须得确认只有一个活动分区,查找活动分区的代码见上面的FindActiveDpt.
5.载入找到的活动分区的第一个扇区的内容到内存地址0000:7c00h处(现在你明白为什么一开始我们就把自己搬到了0600处了吧).
6.跳到7c00h处(也就是活动分区的第一个扇区,好像叫dbr)继续执行.
7.由dbr来载入系统引导程序ntldr,然后……此处省略好多字…….

上面只是大概描述了一下,要想理解还得看代码啊,其实代码中也有好多的小技巧,自己慢慢探索吧.

下面的代码是我从我的机器上用WinHex抠出来,放到IDA中的,做了一些注释

seg000:7C00 ;

seg000:7C00 ; +-------------------------------------------------------------------------+

seg000:7C00 ; |   This file has been generated by The Interactive Disassembler (IDA)    |

seg000:7C00 ; |           Copyright (c) 2011 Hex-Rays, <support@hex-rays.com>           |

seg000:7C00 ; |                      License info: B3-432E-F558-21                      |

seg000:7C00 ; |                             Ilfak Guilfanov                             |

seg000:7C00 ; +-------------------------------------------------------------------------+

seg000:7C00 ;

seg000:7C00 ; Input MD5   : 4FD66ADA219B7146149D1260F57772E0

seg000:7C00

seg000:7C00 ; File Name   : C:\Documents and Settings\lzz\桌面\mbr.bin

seg000:7C00 ; Format      : Binary file

seg000:7C00 ; Base Address: 0000h Range: 7C00h - 7E00h Loaded length: 0200h

seg000:7C00

seg000:7C00                 .686p

seg000:7C00                 .mmx

seg000:7C00                 .model flat

seg000:7C00

seg000:7C00 ; ===========================================================================

seg000:7C00

seg000:7C00 ; Segment type: Pure code

seg000:7C00 seg000          segment byte public 'CODE' use16

seg000:7C00                 assume cs:seg000

seg000:7C00                 ;org 7C00h

seg000:7C00                 assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing

seg000:7C00

seg000:7C00 ; =============== S U B R O U T I N E =======================================

seg000:7C00

seg000:7C00

seg000:7C00 Entry           proc far

seg000:7C00                 xor     ax, ax

seg000:7C02                 mov     ss, ax

seg000:7C04                 mov     sp, 7C00h

seg000:7C07                 sti                     ; 关闭所有中断

seg000:7C08                 push    ax

seg000:7C09                 pop     es

seg000:7C0A                 push    ax

seg000:7C0B                 pop     ds              ; 初始化段寄存器

seg000:7C0C                 cld                     ; 设置方向标志为递增

seg000:7C0D                 mov     si, 7C1Bh

seg000:7C10                 mov     di, 61Bh

seg000:7C13                 push    ax              ; 段地址 0

seg000:7C14                 push    di              ; 偏移量 61bh

seg000:7C15                 mov     cx, 1E5h

seg000:7C18                 rep movsb               ; 把7C1B处的代码复制到61B处

seg000:7C1A                 retf                    ; 跳到段地址0偏移量61bh处 也就是执行下面7c1b的代码

seg000:7C1A Entry           endp

seg000:7C1A

seg000:7C1B ; ---------------------------------------------------------------------------

seg000:7C1B

seg000:7C1B FindActiveDpt:                          ; 载入分区表的地址

seg000:7C1B                 mov     bp, 7BEh

seg000:7C1E                 mov     cl, 4           ; 分区表最多有四项

seg000:7C20

seg000:7C20 GetDpt:                                 ; CODE XREF: seg000:7C2Aj

seg000:7C20                 cmp     [bp+0], ch

seg000:7C23                 jl      short IsActive  ; 找到活动分区

seg000:7C25                 jnz     short InvalidPt ; 显示错误信息

seg000:7C27                 add     bp, 10h

seg000:7C2A                 loop    GetDpt          ; 不是活动分区,检查下一个分区

seg000:7C2C                 int     18h             ; TRANSFER TO ROM BASIC

seg000:7C2C                                         ; causes transfer to ROM-based BASIC (IBM-PC)

seg000:7C2C                                         ; often reboots a compatible; often has no effect at all

seg000:7C2E

seg000:7C2E IsActive:                               ; CODE XREF: seg000:7C23j

seg000:7C2E                 mov     si, bp          ; 找到活动分区

seg000:7C30

seg000:7C30 VerifyOnlyActive:                       ; CODE XREF: seg000:7C38j

seg000:7C30                 add     si, 10h         ; 确认只有一个活动分区

seg000:7C33                 dec     cx

seg000:7C34                 jz      short IsOnlyActive

seg000:7C36                 cmp     [si], ch

seg000:7C38                 jz      short VerifyOnlyActive ; 确认只有一个活动分区

seg000:7C3A

seg000:7C3A InvalidPt:                              ; CODE XREF: seg000:7C25j

seg000:7C3A                 mov     al, ds:7B5h     ; 显示错误信息

seg000:7C3D

seg000:7C3D ShowErrorMsg:                           ; CODE XREF: seg000:7C69j

seg000:7C3D                                         ; seg000:7C7Fj ...

seg000:7C3D                 mov     ah, 7

seg000:7C3F                 mov     si, ax

seg000:7C41

seg000:7C41 MsgLoop:                                ; CODE XREF: seg000:7C4Dj

seg000:7C41                 lodsb

seg000:7C42

seg000:7C42 ShowDone:                               ; CODE XREF: seg000:7C44j

seg000:7C42                 cmp     al, 0

seg000:7C44                 jz      short ShowDone

seg000:7C46                 mov     bx, 7

seg000:7C49                 mov     ah, 0Eh

seg000:7C4B                 int     10h             ; - VIDEO - WRITE CHARACTER AND ADVANCE CURSOR (TTY WRITE)

seg000:7C4B                                         ; AL = character, BH = display page (alpha modes)

seg000:7C4B                                         ; BL = foreground color (graphics modes)

seg000:7C4D                 jmp     short MsgLoop

seg000:7C4F ; ---------------------------------------------------------------------------

seg000:7C4F

seg000:7C4F IsOnlyActive:                           ; CODE XREF: seg000:7C34j

seg000:7C4F                 mov     [bp+10h], cl

seg000:7C52                 call    ReadDbr         ; 读取dbr到0x7c00处

seg000:7C55                 jnb     short ReadSussess

seg000:7C57

seg000:7C57 loc_7C57:                               ; CODE XREF: seg000:7C8Dj

seg000:7C57                 inc     byte ptr [bp+10h]

seg000:7C5A                 cmp     byte ptr [bp+4], 0Bh

seg000:7C5E                 jz      short loc_7C6B

seg000:7C60                 cmp     byte ptr [bp+4], 0Ch

seg000:7C64                 jz      short loc_7C6B

seg000:7C66                 mov     al, ds:7B6h

seg000:7C69                 jnz     short ShowErrorMsg

seg000:7C6B

seg000:7C6B loc_7C6B:                               ; CODE XREF: seg000:7C5Ej

seg000:7C6B                                         ; seg000:7C64j

seg000:7C6B                 add     byte ptr [bp+2], 6

seg000:7C6F                 add     word ptr [bp+8], 6

seg000:7C73                 adc     word ptr [bp+0Ah], 0

seg000:7C77                 call    ReadDbr

seg000:7C7A                 jnb     short ReadSussess

seg000:7C7C                 mov     al, ds:7B6h

seg000:7C7F                 jmp     short ShowErrorMsg

seg000:7C81 ; ---------------------------------------------------------------------------

seg000:7C81

seg000:7C81 ReadSussess:                            ; CODE XREF: seg000:7C55j

seg000:7C81                                         ; seg000:7C7Aj

seg000:7C81                 cmp     ds:MagicNumber, 0AA55h ; 可引导标志

seg000:7C87                 jz      short GoToDbr   ; 如果dbr有效就跳去dbr

seg000:7C89                 cmp     byte ptr [bp+10h], 0

seg000:7C8D                 jz      short loc_7C57

seg000:7C8F                 mov     al, ds:7B7h

seg000:7C92                 jmp     short ShowErrorMsg

seg000:7C94 ; ---------------------------------------------------------------------------

seg000:7C94

seg000:7C94 GoToDbr:                                ; CODE XREF: seg000:7C87j

seg000:7C94                 mov     di, sp

seg000:7C96                 push    ds

seg000:7C97                 push    di

seg000:7C98                 mov     si, bp

seg000:7C9A                 retf

seg000:7C9B

seg000:7C9B ; =============== S U B R O U T I N E =======================================

seg000:7C9B

seg000:7C9B

seg000:7C9B ReadDbr         proc near               ; CODE XREF: seg000:7C52p

seg000:7C9B                                         ; seg000:7C77p

seg000:7C9B                 mov     di, 5

seg000:7C9E                 mov     dl, [bp+0]      ; 读取磁盘的参数,读取失败后cf置位

seg000:7CA1                 mov     ah, 8

seg000:7CA3                 int     13h             ; DISK - DISK - GET CURRENT DRIVE PARAMETERS (XT,AT,XT286,CONV,PS)

seg000:7CA3                                         ; DL = drive number

seg000:7CA3                                         ; Return: CF set on error, AH = status code, BL = drive type

seg000:7CA3                                         ; DL = number of consecutive drives

seg000:7CA3                                         ; DH = maximum value for head number, ES:DI -> drive parameter

seg000:7CA5                 jb      short Int13_ReadLoop ; 读取活动分区的dbr到0x7c00处

seg000:7CA7                 mov     al, cl          ; CL的6,7位=柱面数的高2位

seg000:7CA7                                         ; CL的低6位=每磁道的扇区数

seg000:7CA9                 and     al, 3Fh         ; AL=每磁道的扇区数(sectors)

seg000:7CAB                 cbw

seg000:7CAC                 mov     bl, dh          ; BL=DH=磁盘的磁头数(headers),注意这里的数值是从0开始的

seg000:7CAC                                         ; 所以要加1才是磁头的个数

seg000:7CAE                 mov     bh, ah          ; 读取磁盘参数成功后AH=0,所以这里BH=0

seg000:7CB0                 inc     bx

seg000:7CB1                 mul     bx              ; AX=(磁头数+1)*扇区数

seg000:7CB3                 mov     dx, cx          ; CH和CL的高两位构成柱面数

seg000:7CB5                 xchg    dl, dh

seg000:7CB7                 mov     cl, 6

seg000:7CB9                 shr     dh, cl          ; DX=磁盘的柱面数

seg000:7CBB                 inc     dx

seg000:7CBC                 mul     dx              ; 算出全部扇区数((磁头数+1)*扇区数*(柱面数+1))存入AX,DX

seg000:7CBC                                         ; 注意:这里计算出来的扇区数可能小于磁盘的总扇区数

seg000:7CBE                 cmp     [bp+0Ah], dx

seg000:7CC1                 ja      short Int13_Extend ; 如果当前分区的扇区数大于磁盘的总扇区数时,就只能通过

seg000:7CC1                                         ; int 13h 的扩展功能去访问磁盘

seg000:7CC3                 jb      short Int13_ReadLoop ; 读取活动分区的dbr到0x7c00处

seg000:7CC5                 cmp     [bp+8], ax

seg000:7CC8                 jnb     short Int13_Extend

seg000:7CCA

seg000:7CCA Int13_ReadLoop:                         ; CODE XREF: ReadDbr+Aj

seg000:7CCA                                         ; ReadDbr+28j ...

seg000:7CCA                 mov     ax, 201h        ; 读取活动分区的dbr到0x7c00处

seg000:7CCD                 mov     bx, 7C00h

seg000:7CD0                 mov     cx, [bp+2]

seg000:7CD3                 mov     dx, [bp+0]

seg000:7CD6                 int     13h             ; DISK - READ SECTORS INTO MEMORY

seg000:7CD6                                         ; AL = number of sectors to read, CH = track, CL = sector

seg000:7CD6                                         ; DH = head, DL = drive, ES:BX -> buffer to fill

seg000:7CD6                                         ; Return: CF set on error, AH = status, AL = number of sectors read

seg000:7CD8                 jnb     short Return    ; 读取成功,返回

seg000:7CDA                 dec     di

seg000:7CDB                 jz      short Return

seg000:7CDD                 xor     ah, ah          ; 如果读取出错就复位磁盘重新读取,有5次机会

seg000:7CDF                 mov     dl, [bp+0]

seg000:7CE2                 int     13h             ; DISK - RESET DISK SYSTEM

seg000:7CE2                                         ; DL = drive (if bit 7 is set both hard disks and floppy disks reset)

seg000:7CE4                 jmp     short Int13_ReadLoop ; 读取活动分区的dbr到0x7c00处

seg000:7CE6 ; ---------------------------------------------------------------------------

seg000:7CE6

seg000:7CE6 Int13_Extend:                           ; CODE XREF: ReadDbr+26j

seg000:7CE6                                         ; ReadDbr+2Dj

seg000:7CE6                 mov     dl, [bp+0]

seg000:7CE9                 pusha

seg000:7CEA                 mov     bx, 55AAh

seg000:7CED                 mov     ah, 41h ; 'A'   ; 测试是否支持int 13h 扩展如果出错CF置位,如果支持的话

seg000:7CED                                         ; BX=AA55h

seg000:7CEF                 int     13h             ; DISK -

seg000:7CF1                 jb      short NotSupportLargeDisk

seg000:7CF3                 cmp     bx, 0AA55h

seg000:7CF7                 jnz     short NotSupportLargeDisk

seg000:7CF9                 test    cl, 1

seg000:7CFC                 jz      short NotSupportLargeDisk

seg000:7CFE                 popa

seg000:7CFF

seg000:7CFF Int13_Extend_ReadLoop:                  ; CODE XREF: ReadDbr+8Cj

seg000:7CFF                 pusha

seg000:7D00                 push    0

seg000:7D02                 push    0

seg000:7D04                 push    word ptr [bp+0Ah]

seg000:7D07                 push    word ptr [bp+8]

seg000:7D0A                 push    0

seg000:7D0C                 push    7C00h

seg000:7D0F                 push    1

seg000:7D11                 push    10h

seg000:7D13                 mov     ah, 42h ; 'B'

seg000:7D15                 mov     si, sp          ; 用int 13h 扩展功能读取dbr到0x7c00

seg000:7D17                 int     13h             ; DISK -

seg000:7D19                 popa

seg000:7D1A                 popa

seg000:7D1B                 jnb     short Return

seg000:7D1D                 dec     di

seg000:7D1E                 jz      short Return

seg000:7D20                 xor     ah, ah

seg000:7D22                 mov     dl, [bp+0]      ; 读取出错的话重置磁盘,重新读,有5次机会

seg000:7D25                 int     13h             ; DISK - RESET DISK SYSTEM

seg000:7D25                                         ; DL = drive (if bit 7 is set both hard disks and floppy disks reset)

seg000:7D27                 jmp     short Int13_Extend_ReadLoop

seg000:7D29 ; ---------------------------------------------------------------------------

seg000:7D29

seg000:7D29 NotSupportLargeDisk:                    ; CODE XREF: ReadDbr+56j

seg000:7D29                                         ; ReadDbr+5Cj ...

seg000:7D29                 popa

seg000:7D2A                 stc                     ; 读取错误 cf=1

seg000:7D2B

seg000:7D2B Return:                                 ; CODE XREF: ReadDbr+3Dj

seg000:7D2B                                         ; ReadDbr+40j ...

seg000:7D2B                 retn

seg000:7D2B ReadDbr         endp ; sp-analysis failed

seg000:7D2B

seg000:7D2B ; ---------------------------------------------------------------------------

seg000:7D2C aInvalidPartiti db 'Invalid partition table',0

seg000:7D44 aErrorLoadingOp db 'Error loading operating system',0

seg000:7D63 aMissingOperati db 'Missing operating system',0

seg000:7D7C                 db    0

seg000:7D7D                 db    0

seg000:7D7E                 db    0

seg000:7D7F                 db    0

seg000:7D80                 db    0

seg000:7D81                 db    0

seg000:7D82                 db    0

seg000:7D83                 db    0

seg000:7D84                 db    0

seg000:7D85                 db    0

seg000:7D86                 db    0

seg000:7D87                 db    0

seg000:7D88                 db    0

seg000:7D89                 db    0

seg000:7D8A                 db    0

seg000:7D8B                 db    0

seg000:7D8C                 db    0

seg000:7D8D                 db    0

seg000:7D8E                 db    0

seg000:7D8F                 db    0

seg000:7D90                 db    0

seg000:7D91                 db    0

seg000:7D92                 db    0

seg000:7D93                 db    0

seg000:7D94                 db    0

seg000:7D95                 db    0

seg000:7D96                 db    0

seg000:7D97                 db    0

seg000:7D98                 db    0

seg000:7D99                 db    0

seg000:7D9A                 db    0

seg000:7D9B                 db    0

seg000:7D9C                 db    0

seg000:7D9D                 db    0

seg000:7D9E                 db    0

seg000:7D9F                 db    0

seg000:7DA0                 db    0

seg000:7DA1                 db    0

seg000:7DA2                 db    0

seg000:7DA3                 db    0

seg000:7DA4                 db    0

seg000:7DA5                 db    0

seg000:7DA6                 db    0

seg000:7DA7                 db    0

seg000:7DA8                 db    0

seg000:7DA9                 db    0

seg000:7DAA                 db    0

seg000:7DAB                 db    0

seg000:7DAC                 db    0

seg000:7DAD                 db    0

seg000:7DAE                 db    0

seg000:7DAF                 db    0

seg000:7DB0                 db    0

seg000:7DB1                 db    0

seg000:7DB2                 db    0

seg000:7DB3                 db    0

seg000:7DB4                 db    0

seg000:7DB5                 db  2Ch ; ,             ; 这里就是分区表的内容了

seg000:7DB6                 db  44h ; D

seg000:7DB7                 db  63h ; c

seg000:7DB8                 db 0B6h ; 

seg000:7DB9                 db  7Ch ; |

seg000:7DBA                 db 0B6h ; 

seg000:7DBB                 db  7Ch ; |

seg000:7DBC                 db    0

seg000:7DBD                 db    0

seg000:7DBE                 db  80h ; ?

seg000:7DBF                 db    1

seg000:7DC0                 db    1

seg000:7DC1                 db    0

seg000:7DC2                 db    7

seg000:7DC3                 db 0FEh ; 

seg000:7DC4                 db 0FFh

seg000:7DC5                 db 0FFh

seg000:7DC6                 db  3Fh ; ?

seg000:7DC7                 db    0

seg000:7DC8                 db    0

seg000:7DC9                 db    0

seg000:7DCA                 db 0ECh ; 

seg000:7DCB                 db 0EDh ; 

seg000:7DCC                 db 0E1h ; 

seg000:7DCD                 db    4

seg000:7DCE                 db    0

seg000:7DCF                 db 0FEh ; 

seg000:7DD0                 db 0FFh

seg000:7DD1                 db 0FFh

seg000:7DD2                 db  0Fh

seg000:7DD3                 db 0FEh ; 

seg000:7DD4                 db 0FFh

seg000:7DD5                 db 0FFh

seg000:7DD6                 db  2Bh ; +

seg000:7DD7                 db 0EEh ; 

seg000:7DD8                 db 0E1h ; 

seg000:7DD9                 db    4

seg000:7DDA                 db 0D5h ; 

seg000:7DDB                 db  5Dh ; ]

seg000:7DDC                 db 0BFh ; 

seg000:7DDD                 db  0Dh

seg000:7DDE                 db    0

seg000:7DDF                 db    0

seg000:7DE0                 db    0

seg000:7DE1                 db    0

seg000:7DE2                 db    0

seg000:7DE3                 db    0

seg000:7DE4                 db    0

seg000:7DE5                 db    0

seg000:7DE6                 db    0

seg000:7DE7                 db    0

seg000:7DE8                 db    0

seg000:7DE9                 db    0

seg000:7DEA                 db    0

seg000:7DEB                 db    0

seg000:7DEC                 db    0

seg000:7DED                 db    0

seg000:7DEE                 db    0

seg000:7DEF                 db    0

seg000:7DF0                 db    0

seg000:7DF1                 db    0

seg000:7DF2                 db    0

seg000:7DF3                 db    0

seg000:7DF4                 db    0

seg000:7DF5                 db    0

seg000:7DF6                 db    0

seg000:7DF7                 db    0

seg000:7DF8                 db    0

seg000:7DF9                 db    0

seg000:7DFA                 db    0

seg000:7DFB                 db    0

seg000:7DFC                 db    0

seg000:7DFD                 db    0

seg000:7DFE MagicNumber     dw 0AA55h               ; DATA XREF: seg000:ReadSussessr

seg000:7DFE seg000          ends                    ; 可引导标志

seg000:7DFE

seg000:7DFE

seg000:7DFE                 end

  评论这张
 
阅读(82)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017