2024年1月17日发(作者:)

MBR引导代码分析

整理:太虚野老

用WinHex读MBR,如下:

图中3个用红色矩形框框住的是3个字符串(Invalid partition table、Error loading

operating system、Missing operating system)的地址相关的,分别是0x12C、0x144、0x163。用蓝色矩形框框住的,MBR里面的1B8偏移位置为磁盘签名,该签名由ntldr写入,Windows就是靠这个磁盘签名来确定是从哪块硬盘启动的,如果两个磁盘签名相同了,那么ntldr就会随机更改一块磁盘,但是下次就不会出现这种情况了。实际MBR的可执行代码到0x12B处结束。MBR引导代码的作用就是加载活动分区的引导代码。用IDA Pro反汇编MBR后如下(包括分析):

;// MBR在系统启动时由BIOS INT 19H自动加载到0000:7c00处,为512个字节.下面这段代码实现把0000:7c1b处MBR代码复制485个字节到0000:061b处,为什么不从0000:7c00第 1 页 共 8 页

开始复制512个到0000:06cc处,因为前面1b 个字节为复制代码,所以忽略.空出的0000:7c00

开始的空间将读入活动分区的操作系统的引导扇区.

seg000:0000 33 C0 xor ax, ax ;//ax寄存器清0

seg000:0002 8E D0 mov ss, ax ;// 栈寄存器ss=0

seg000:0004 BC 00 7C mov sp, 7C00h ;//栈指针—SS:SP=0000:7C00

seg000:0007 FB sti ;//允许中断

seg000:0008 50 push ax ; 这条PUSH指令在0008处,前面的

8个字节指令已经执行,所以push指令输入的数据覆盖前面的0000-0001空间,没有关系.

seg000:0009 07 pop es ;//附加数据段寄存器es=0

seg000:000A 50 push ax;

seg000:000B 1F pop ds ;//数据段寄存器ds=0

seg000:000C FC cld ;//使方向标志寄存器DF=0,规定

其后的串操作为正向串操作

;把7C1Bh处的长1E5h的代码拷贝到61Bh处

seg000:000D BE 1B 7C mov si, 7C1Bh ;//用于movsb

seg000:0010 BF 1B 06 mov di, 61Bh ;//用于movsb ,将[DS:SI]中字节传

送到[ES:DI]中

seg000:0013 50 push ax ;//保存ax,di,用于第001a处指令

retf(同ret),使ax->cs,di->ip,实现指令跳转

seg000:0014 57 push di

seg000:0015 B9 E5 01 mov cx, 1E5h ;//用于rep movsb中的rep,每次cx

减1,到0不执行movsb ,200H-1BH=1E5

seg000:0018 F3 A4 rep movsb

seg000:001A CB retf ;//相当于pop ip; pop cs,即执行

retf指令后跳转到061BH处执行

seg000:001B

; ---------------------------------------------------------------------------

seg000:001B BD BE 07 mov bp, 7BEh ;// 600h+1BEh=7BEh,分区表起始偏移为1BEh,07BEH开始的16个字节是第一个分区表项

seg000:001E B1 04 mov cl, 4 ;//硬盘的mbr分区表最多有4个表

项, 用于loop

seg000:0020

seg000:0020 loc_10020: ; CODE XREF: seg000:002A↓j

seg000:0020 38 6E 00 cmp [bp+0], ch ;//检查分区指示符. cx寄存器

前面用movsb减为0,所以ch=0. 判断第一个分区表项的第一个字节是否为活动分区,因为

cmp是有符号数据比较,如果[bp+0]=80, 80H为负数,则其比0小

seg000:0023 7C 09 jl short loc_1002E ;//如果是80,活动分区,则

跳到002E地址.这里有点问题, 如果[bp+0x0]是符号位为1的任意数的话,也是小于0,也

会跳到002E地址

seg000:0025 75 13 jnz short loc_1003A ;//分区指示符不为0就跳

转(显示分区表无效)

seg000:0027 83 C5 10 add bp, 10h ;//指向下一个表项(每一个表

项的长度为10h字节)

第 2 页 共 8 页

seg000:002A E2 F4 loop loc_10020 ;//cx不为0就循环

;四表项的状态字节都为0就执行ROM BASIC中断. 只有IBM个人计算机有Basic包括在

ROM中;Int 18h中断服务程序就是启动ROM-Basic,如果没有ROM BASIC,中断18H通常会显

示消息 NO ROM BASIC 然后"系统暂停",并且系统中断

seg000:002C CD 18 int 18h

;//找到活动分区后,还要检查剩余分区的启动标志是否为0;不允许存在多个活动分区

seg000:002E

seg000:002E loc_1002E: ; CODE XREF: seg000:0023