MBR 代码

今天顺手分析了微软默认安装的mbr程序。
它主要是寻找active partition,然后将这个分区的boot sector 读入7c00,并执行。否则显示错误信息。
读磁盘用到了13H中断,显示用到了10H中断

Typical boot sector code also expects to be loaded at physical address 0x7c00, even though all the memory from physical address 0x501 (address 0x500 is the last one used by the BIOS)[citation needed] to somewhere short of 0x9ffff is typically available in Real mode (a total of up to 640 KB minus the first 1281 bytes of memory)[22] Since 0x7c00 is the location where the MBR is already running, one of the first tasks of an MBR is usually to relocate itself somewhere else in memory -- most often at 0x600 (for Microsoft code). A conventional Volume Boot Record is only one sector long; but it does no harm and is trivial to allow the MBR to load significantly more than just one sector. Some bootloaders are longer than one sector, so loading more than one sector can speed up the boot process.

seg000:7C00 ;
seg000:7C00 ; +-------------------------------------------------------------------------+
seg000:7C00 ; |     This file is generated by The Interactive Disassembler (IDA)        |
seg000:7C00 ; |     Copyright (c) 2007 by DataRescue sa/nv, <ida@datarescue.com>        |
seg000:7C00 ; |        Licensed to: Robert Munro, Symantec, 1 user, std, 04/2007        |
seg000:7C00 ; +-------------------------------------------------------------------------+
seg000:7C00 ;
seg000:7C00 ; Input MD5   : C02F1917A683DB5218705E219FE54F8C
seg000:7C00
seg000:7C00 ; ---------------------------------------------------------------------------
seg000:7C00 ; File Name   : C:\mbr.bin
seg000:7C00 ; Format      : Binary file
seg000:7C00 ; Base Address: 7C00h Range: 83C00h - 83E00h 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 _Start:
seg000:7C00                 xor     ax, ax
seg000:7C02                 mov     ss, ax
seg000:7C04                 mov     sp, 7C00h
seg000:7C07                 sti                     ; disable interrupt
seg000:7C08                 push    ax
seg000:7C09                 pop     es
seg000:7C0A                 push    ax
seg000:7C0B                 pop     ds              ; set (ss es ds) to zero
seg000:7C0C                 cld                     ; make si and ei increase  forward
seg000:7C0D                 mov     si, offset _COPY_TO_600 ; 1BE is the first partition position
seg000:7C10                 mov     di, 61Bh
seg000:7C13                 push    ax
seg000:7C14                 push    di              ; prepare for retf,push cs and ip
seg000:7C15                 mov     cx, 1E5h        ; 7C00+200-7C1B = 1E5
seg000:7C18                 rep movsb               ; copy remain code to 0:61B
seg000:7C1A                 retf                    ; jump to 0:61B
seg000:7C1A                                         ; it means copy all mbr to 0:600,and run at that position
seg000:7C1B ; ---------------------------------------------------------------------------
seg000:7C1B
seg000:7C1B _COPY_TO_600:                           ; DATA XREF: seg000:7C0Do
seg000:7C1B                 mov     bp, 1BEh+600h   ; 1BE is the first partition position
seg000:7C1E                 mov     cl, 4
seg000:7C20
seg000:7C20 loc_83C20:                              ; CODE XREF: seg000:7C2Aj
seg000:7C20                 cmp     [bp+0], ch      ; looking for active partition
seg000:7C23                 jl      short loc_83C2E ; bp points to active partition
seg000:7C25                 jnz     short loc_83C3A ; 600+1b5
seg000:7C27                 add     bp, 10h
seg000:7C2A                 loop    loc_83C20       ; looking for active partition
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 loc_83C2E:                              ; CODE XREF: seg000:7C23j
seg000:7C2E                 mov     si, bp          ; bp points to active partition
seg000:7C30
seg000:7C30 loc_83C30:                              ; CODE XREF: seg000:7C38j
seg000:7C30                 add     si, 10h         ; points to another partition
seg000:7C33                 dec     cx
seg000:7C34                 jz      short loc_83C4F
seg000:7C36                 cmp     [si], ch
seg000:7C38                 jz      short loc_83C30 ; points to another partition
seg000:7C3A
seg000:7C3A loc_83C3A:                              ; CODE XREF: seg000:7C25j
seg000:7C3A                 mov     al, ds:7B5h     ; 600+1b5
seg000:7C3D
seg000:7C3D _DisplayString:                         ; CODE XREF: seg000:7C69j
seg000:7C3D                                         ; seg000:7C7Fj ...
seg000:7C3D                 mov     ah, 7
seg000:7C3F                 mov     si, ax
seg000:7C41
seg000:7C41 loc_83C41:                              ; CODE XREF: seg000:7C4Dj
seg000:7C41                 lodsb                   ; [si]=>al
seg000:7C42
seg000:7C42 loc_83C42:                              ; CODE XREF: seg000:7C44j
seg000:7C42                 cmp     al, 0
seg000:7C44                 jz      short loc_83C42
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 loc_83C41 ; [si]=>al
seg000:7C4F ; ---------------------------------------------------------------------------
seg000:7C4F
seg000:7C4F loc_83C4F:                              ; CODE XREF: seg000:7C34j
seg000:7C4F                 mov     [bp+10h], cl
seg000:7C52                 call    ReadPartition
seg000:7C55                 jnb     short loc_83C81 ; discern if it's legal boot sector
seg000:7C57
seg000:7C57 loc_83C57:                              ; CODE XREF: seg000:7C8Dj
seg000:7C57                 inc     byte ptr [bp+10h]
seg000:7C5A                 cmp     byte ptr [bp+4], 0Bh ; WIN95 OSR2 FAT32
seg000:7C5E                 jz      short loc_83C6B
seg000:7C60                 cmp     byte ptr [bp+4], 0Ch ; WIN95 OSR2 FAT32, LBA-mapped
seg000:7C64                 jz      short loc_83C6B
seg000:7C66                 mov     al, ds:7B6h
seg000:7C69                 jnz     short _DisplayString
seg000:7C6B
seg000:7C6B loc_83C6B:                              ; 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    ReadPartition
seg000:7C7A                 jnb     short loc_83C81 ; discern if it's legal boot sector
seg000:7C7C                 mov     al, ds:7B6h
seg000:7C7F                 jmp     short _DisplayString
seg000:7C81 ; ---------------------------------------------------------------------------
seg000:7C81
seg000:7C81 loc_83C81:                              ; CODE XREF: seg000:7C55j
seg000:7C81                                         ; seg000:7C7Aj
seg000:7C81                 cmp     word ptr ds:7DFEh, 0AA55h ; discern if it's legal boot sector
seg000:7C87                 jz      short loc_83C94
seg000:7C89                 cmp     byte ptr [bp+10h], 0 ; if it's a illeagle boot sector,then try to change another one
seg000:7C8D                 jz      short loc_83C57
seg000:7C8F                 mov     al, ds:7B7h
seg000:7C92                 jmp     short _DisplayString
seg000:7C94 ; ---------------------------------------------------------------------------
seg000:7C94
seg000:7C94 loc_83C94:                              ; 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 ReadPartition   proc near               ; CODE XREF: seg000:7C52p
seg000:7C9B                                         ; seg000:7C77p
seg000:7C9B                 mov     di, 5
seg000:7C9E                 mov     dl, [bp+0]
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:7CA3                                         ; http://en.wikipedia.org/wiki/INT_13
seg000:7CA5                 jb      short loc_83CCA ; jump if execute wrong
seg000:7CA7                 mov     al, cl          ; maximum sector number
seg000:7CA9                 and     al, 3Fh
seg000:7CAB                 cbw                     ; al=>ax
seg000:7CAC                 mov     bl, dh          ; maximum head number
seg000:7CAE                 mov     bh, ah
seg000:7CB0                 inc     bx
seg000:7CB1                 mul     bx              ; sector number * head number
seg000:7CB3                 mov     dx, cx
seg000:7CB5                 xchg    dl, dh
seg000:7CB7                 mov     cl, 6
seg000:7CB9                 shr     dh, cl
seg000:7CBB                 inc     dx
seg000:7CBC                 mul     dx
seg000:7CBE                 cmp     [bp+0Ah], dx
seg000:7CC1                 ja      short loc_83CE6
seg000:7CC3                 jb      short loc_83CCA ; read 1 sector
seg000:7CC5                 cmp     [bp+8], ax      ; LBA of first sector in the partition
seg000:7CC8                 jnb     short loc_83CE6
seg000:7CCA
seg000:7CCA loc_83CCA:                              ; CODE XREF: ReadPartition+Aj
seg000:7CCA                                         ; ReadPartition+28j ...
seg000:7CCA                 mov     ax, 201h        ; read 1 sector
seg000:7CCD                 mov     bx, 7C00h       ; into memory(7c00)
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:7CD6                                         ; read the patition boot sector into 7c00
seg000:7CD8                 jnb     short locret_83D2B ; jump if succeed
seg000:7CDA                 dec     di
seg000:7CDB                 jz      short locret_83D2B
seg000:7CDD                 xor     ah, ah
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 loc_83CCA ; read 1 sector
seg000:7CE6 ; ---------------------------------------------------------------------------
seg000:7CE6
seg000:7CE6 loc_83CE6:                              ; CODE XREF: ReadPartition+26j
seg000:7CE6                                         ; ReadPartition+2Dj
seg000:7CE6                 mov     dl, [bp+0]
seg000:7CE9                 pusha
seg000:7CEA                 mov     bx, 55AAh
seg000:7CED                 mov     ah, 41h ; 'A'
seg000:7CEF                 int     13h             ; DISK -
seg000:7CF1                 jb      short loc_83D29
seg000:7CF3                 cmp     bx, 0AA55h
seg000:7CF7                 jnz     short loc_83D29
seg000:7CF9                 test    cl, 1
seg000:7CFC                 jz      short loc_83D29
seg000:7CFE                 popa
seg000:7CFF
seg000:7CFF loc_83CFF:                              ; CODE XREF: ReadPartition+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
seg000:7D17                 int     13h             ; DISK -
seg000:7D19                 popa
seg000:7D1A                 popa
seg000:7D1B                 jnb     short locret_83D2B
seg000:7D1D                 dec     di
seg000:7D1E                 jz      short locret_83D2B
seg000:7D20                 xor     ah, ah
seg000:7D22                 mov     dl, [bp+0]
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 loc_83CFF
seg000:7D29 ; ---------------------------------------------------------------------------
seg000:7D29
seg000:7D29 loc_83D29:                              ; CODE XREF: ReadPartition+56j
seg000:7D29                                         ; ReadPartition+5Cj ...
seg000:7D29                 popa
seg000:7D2A                 stc
seg000:7D2B
seg000:7D2B locret_83D2B:                           ; CODE XREF: ReadPartition+3Dj
seg000:7D2B                                         ; ReadPartition+40j ...
seg000:7D2B                 retn
seg000:7D2B ReadPartition   endp
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 39h dup(0)
seg000:7DB5                 db 2Ch                  ; string offset 1
seg000:7DB6                 db  44h ; D             ; string offset 2
seg000:7DB7                 db  63h ; c             ; string offset 3
seg000:7DB8                 dd 6E19BDAh             ; signature
seg000:7DBC                 dw 0
seg000:7DBE partition1      db 80h, 2 dup(1), 0, 7, 0EFh, 2 dup(0FFh), 3Fh, 3 dup(0)
seg000:7DBE                 db 0D1h, 33h, 0F9h, 0Dh
seg000:7DCE partition2      db 10h dup(0)
seg000:7DDE partition3      db 10h dup(0)
seg000:7DEE partition4      db 10h dup(0)
seg000:7DFE                 dw 0AA55h
seg000:7DFE seg000          ends
seg000:7DFE
seg000:7DFE
seg000:7DFE                 end

posted @ 2009-05-22 15:11  Fan Zhang  阅读(505)  评论(0编辑  收藏  举报