MBR的反编译程序

本文是介绍MBR的反编译程序的。MBR是放在硬盘的0柱面,0磁头(head),1扇区的 
那一段区。MBR是由FDISK程序创建的。所有操作系统的FDISK程序都会创建类似的MBR 
记录。MBR是多个分区的前提,每个MBR中包括了四个分区表记录。在您的计算机加电 
之后,INT19被调用了。一般来说,INT19先从第一个软盘驱动器中读启动扇区记录。 
如果在软盘中找到了启动的扇区,那么这个扇区的数据就被读入到内存的0000:7c00 
地址上,INT19也跳到了这个地址上。但是,如果没有在软盘中找到这个扇区的话,INT 
19就从第一个硬盘中去读。同样,如果成功的话,也会把MBR导入到相同的内存地址 
0000:7c00,INT19也会跳这个地址。MBR中包括的一段小程序是定出在分区表中的活动分 
区。这样的活动分区找到之,那个分区的启动扇区也被读入到0000:7c00地址,MBR程序 
也转移到了这个地址。每一个操作系统都有固定的启动扇区的格式。在启动扇区里的程 
序要能定出操作系统启动程序的位置(或是核心本身,或者是一个启动管理器),然后 
将它读入内存。 
另:在Ctrl-Alt-Del键被按下时,INT19也会被调用。在大多数系统中,Ctrl-Alt-Del三?nbsp;
键同时按下表示热启动您的计算机,回到INT19调用前的状态。 
 ===== 
数据存放的位置: 
   MBR程序放在偏移为0000的位置。 
   MBR消息放在偏移为008b的位置。 
   分区表放在偏移为00be的位置。 
   签名放在偏移为00fe的位置。 
关于谁干什么事的总结: 
    如果一个活动分区找到了,这个分区的启动数据被读入到0000:7c00的位置,MBR程 
序也跳到0000:7c00的位置。这段程序找到指向分区表的入口,入口描述的是这段分区是 
怎样被启动的。启动程序用这些数据来决定用来启动的驱动器和这个驱动器分区在硬盘上 
的位置。 
    如果没有找到这样的活动分区入口,ROM BASIC会转入INT 18的调用。所有其他的错 
误导致系统的挂起,可以看HANG的标记。 
 
注意(非常之重要): 
  1)活动分区入口的第一个字节的内容是80h。在INT13被调用之前,这个字节被导 
入到DL寄存器中。当INT13被调用时,DL表示的是BIOS的设备号码。因为这个原因,由MBR 
程序读的启动扇区只能从BIOS设备号码为80的硬盘中读入。这便是为什么不能从任何硬盘 
启动的原因。?nbsp;
   
  2)MBR程序是用基于INT 13h (ah=02h)的中断的CHS来读取活动分区的启动扇区位置 
的。活动分区的启动扇区内的位置是在分区表内用CHS格式表明的。如果这个驱动器小于 
528M,这个CHS一定要是(L-CHS,见BIOS TYPES文档)。在LBA中没有任何地址是有用的。 
(另一个LBA不能解决>528M问题的原因)   这点大家别信,西西。 
 
 
==== 
    这是一张整个MBR记录的表(hex 和ascii格式) 
OFFSET 0 1 2 3  4 5 6 7  8 9 A B  C D E F  *0123456789ABCDEF* 
000000 fa33c08e d0bc007c 8bf45007 501ffbfc *.3.....|..P.P...* 
000010 bf0006b9 0001f2a5 ea1d0600 00bebe07 *................* 
000020 b304803c 80740e80 3c00751c 83c610fe *...<.t..<.u.....* 
000030 cb75efcd 188b148b 4c028bee 83c610fe *.u......L.......* 
000040 cb741a80 3c0074f4 be8b06ac 3c00740b *.t..<.t.....<.t.* 
000050 56bb0700 b40ecd10 5eebf0eb febf0500 *V.......^.......* 
000060 bb007cb8 010257cd 135f730c 33c0cd13 *..|...W.._s.3...* 
000070 4f75edbe a306ebd3 bec206bf fe7d813d *Ou...........}.=* 
000080 55aa75c7 8bf5ea00 7c000049 6e76616c *U.u.....|..Inval* 
000090 69642070 61727469 74696f6e 20746162 *id partition tab* 
0000a0 6c650045 72726f72 206c6f61 64696e67 *le.Error loading* 
0000b0 206f7065 72617469 6e672073 79737465 * operating syste* 
0000c0 6d004d69 7373696e 67206f70 65726174 *m.Missing operat* 
0000d0 696e6720 73797374 656d0000 00000000 *ing system......* 
0000e0 00000000 00000000 00000000 00000000 *................* 
0000f0 TO 0001af SAME AS ABOVE 
0001b0 00000000 00000000 00000000 00008001 *................* 
0001c0 0100060d fef83e00 00000678 0d000000 *......>....x....* 
0001d0 00000000 00000000 00000000 00000000 *................* 
0001e0 00000000 00000000 00000000 00000000 *................* 
0001f0 00000000 00000000 00000000 000055aa *..............U.* 
==== 
   这是MBR的反编译程序: 
   这个扇区被导入到内存的0000:7c00位置,但是它又马上将自己重定位到0000:0060的 
位?nbsp;
。 
BEGIN:   #    NOW AT 0000:7C00, RELOCATE 
0000:7C00 FA            CLI                     #禁止中断 
0000:7C01 33C0          XOR     AX,AX           #设置堆栈段地址为0000 
0000:7C03 8ED0          MOV     SS,AX 
0000:7C05 BC007C        MOV     SP,7C00         #设置堆栈指针为7c00 
0000:7C08 8BF4          MOV     SI,SP           #SI = 7c00 
0000:7C0A 50            PUSH    AX 
0000:7C0B 07            POP     ES              #ES = 0000:7c00 
0000:7C0C 50            PUSH    AX 
0000:7C0D 1F            POP     DS              #DS = 0000:7c00 
0000:7C0E FB            STI                     #开中断 
0000:7C0F FC            CLD                     #清除方向 
0000:7C10 BF0006        MOV     DI,0600         #DI = 0600 
0000:7C13 B90001        MOV     CX,0100         #移动 256 个word (512 bytes) 
 
0000:7C16 F2            REPNZ                   #把 MBR 从 0000:7c00 
0000:7C17 A5            MOVSW                   #移动到 0000:0600 
0000:7C18 EA1D060000    JMP     0000:061D       #跳至NEW_LOCATION 
NEW_LOCATION:# NOW AT 0000:0600 
0000:061D BEBE07      MOV     SI,07BE           #指向入口的第一个字节 
0000:0620 B304        MOV     BL,04             #有4个入口 
SEARCH_LOOP1: # 查找活动分区 
0000:0622 803C80      CMP     BYTE PTR [SI],80  #是不是活动分区? 
0000:0625 740E        JZ      FOUND_ACTIVE      #是,栈指针指向7c00 
0000:0627 803C00      CMP     BYTE PTR [SI],00  #是不是不活动分区? 
0000:062A 751C        JNZ     NOT_ACTIVE        #跳转至NOT_ACTIVE 
0000:062C 83C610      ADD     SI,+10            #增量表指针加16 
0000:062F FECB        DEC     BL                #减少计数 
0000:0631 75EF        JNZ     SEARCH_LOOP1      #循环 
0000:0633 CD18        INT     18                #跳至 ROM BASIC 
FOUND_ACTIVE: # 找到了活动分区 
0000:0635 8B14        MOV     DX,[SI]           #设置DH/DL为INT 13 
0000:0637 8B4C02      MOV     CX,[SI+02]        #设置CH/CL为INT 13 
0000:063A 8BEE        MOV     BP,SI             #保存表指针 
SEARCH_LOOP2: # 确定只有一个活动分区 
0000:063C 83C610      ADD     SI,+10            #增量表指针加16 
0000:063F FECB        DEC     BL                #减少计数 
0000:0641 741A        JZ      READ_BOOT         #如果表结束,跳转 
0000:0643 803C00      CMP     BYTE PTR [SI],00  #是不是非活动分区 
0000:0646 74F4        JZ      SEARCH_LOOP2      #是,循环 
NOT_ACTIVE:   #  多于一个活动分区 
0000:0648 BE8B06      MOV     SI,068B           #显示 "Invld prttn tbl" 
DISPLAY_MSG:  #  显示消息循环 
0000:064B AC          LODSB                     #取得消息的字符 
0000:064C 3C00        CMP     AL,00             #判断消息的结尾 
0000:064E 740B        JZ      HANG              #是 
0000:0650 56          PUSH    SI                #保存SI 
0000:0651 BB0700      MOV     BX,0007           #屏幕属性 
0000:0654 B40E        MOV     AH,0E             #显示一个字符 
0000:0656 CD10        INT     10 
0000:0658 5E          POP     SI                #恢复SI 
0000:0659 EBF0        JMP     DISPLAY_MSG       #循环 
HANG:         #挂起系统 
0000:065B EBFE        JMP     HANG              #停在这儿 
READ_BOOT:   #读活动分区的数据 
0000:065D BF0500      MOV     DI,0005        #INT 13 的尝试次数 
INT13RTRY:   #INT 13的重试循环 
0000:0660 BB007C      MOV     BX,7C00 
0000:0663 B80102      MOV     AX,0201           #读入一个扇区 
0000:0666 57          PUSH    DI                #保存DI 
0000:0667 CD13        INT     13                #把扇区读入0000:7c00 
0000:0669 5F          POP     DI                #重存DI 
0000:066A 730C        JNB     INT13OK           #没有INT 13,跳转 
0000:066C 33C0        XOR     AX,AX             #调用INT 13 ,硬盘重置 
0000:066E CD13        INT     13 
0000:0670 4F          DEC     DI                #DI-- 
0000:0671 75ED        JNZ     INT13RTRY         #如果非零,重试 
0000:0673 BEA306      MOV     SI,06A3           #显示"Errr ldng systm" 
0000:0676 EBD3        JMP     DISPLAY_MSG       #跳转至显示循环 
INT13OK: #INT 13 出错 
0000:0678 BEC206      MOV     SI,06C2            #"missing op sys" 
0000:067B BFFE7D      MOV     DI,7DFE            #指向签名 
0000:067E 813D55AA    CMP     WORD PTR [DI],AA55 #签名是否正确? 
0000:0682 75C7        JNZ     DISPLAY_MSG        #不正确,跳至显示消息循环 
0000:0684 8BF5        MOV     SI,BP              #设置SI 
0000:0686 EA007C0000  JMP     0000:7C00          #跳转至启动扇区,SI指向分区 
表入 
?nbsp;
 
#这儿是消息 
0000:0680 ........ ........ ......49 6e76616c *           Inval* 
0000:0690 69642070 61727469 74696f6e 20746162 *id partition tab* 
0000:06a0 6c650045 72726f72 206c6f61 64696e67 *le.Error loading* 
0000:06b0 206f7065 72617469 6e672073 79737465 * operating syste* 
0000:06c0 6d004d69 7373696e 67206f70 65726174 *m.Missing operat* 
0000:06d0 696e6720 73797374 656d00.. ........ *ing system.     * 
#无用的数据 
0000:06d0 ........ ........ ......00 00000000 *           .....* 
0000:06e0 00000000 00000000 00000000 00000000 *................* 
0000:06f0 00000000 00000000 00000000 00000000 *................* 
0000:0700 00000000 00000000 00000000 00000000 *................* 
0000:0710 00000000 00000000 00000000 00000000 *................* 
0000:0720 00000000 00000000 00000000 00000000 *................* 
0000:0730 00000000 00000000 00000000 00000000 *................* 
0000:0740 00000000 00000000 00000000 00000000 *................* 
0000:0750 00000000 00000000 00000000 00000000 *................* 
0000:0760 00000000 00000000 00000000 00000000 *................* 
0000:0770 00000000 00000000 00000000 00000000 *................* 
0000:0780 00000000 00000000 00000000 00000000 *................* 
0000:0790 00000000 00000000 00000000 00000000 *................* 
0000:07a0 00000000 00000000 00000000 00000000 *................* 
0000:07b0 00000000 00000000 00000000 0000.... *............    * 
#分区表从0000:07be开始。每一个分区表入口是16个字节这个表定义了一个单个的主分 
区并 
 是活动分区。 
0000:07b0 ........ ........ ........ ....8001 *            ....* 
0000:07c0 0100060d fef83e00 00000678 0d000000 *......>....x....* 
0000:07d0 00000000 00000000 00000000 00000000 *................* 
0000:07e0 00000000 00000000 00000000 00000000 *................* 
0000:07f0 00000000 00000000 00000000 0000.... *............    * 
#最后两个字节一定包括了55aah的数据。 
0000:07f0 ........ ........ ........ ....55aa *..............U.* 

 

出处http://www.jijiao.com.cn/DOS/tech/analysis/00000000.htm

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值