win2K的MBR分析

源代码来自于reactOS当中的win2k.asm
org 7c00h
segment .text

bits 16

start:

        jmp short main

        nop

 

首先两句定义整个代码的运行位置,org 7C00H指示整个代码的其实位置在7C00处,这样可以减少不必要的便宜运算。也就是整个MBR加载到系统之后不存在偏移。而后面的bits 16则是表明整个代码段都是16位对齐,start后面是MBR的开始,这一句通过汇编会生成两字节的调整指令和一跳空操作指令。紧跟三条跳转指令后面的是MBR当中的一些属性值。

OEMName                 db 'MSWIN4.0'                 ;厂商标志和OS版本号
BytesPerSector		dw 512                        ;每扇区的字节数

SectsPerCluster      db 1 ;每簇的扇区数 ReservedSectors dw 1 ;第一个FAT开始之前的扇区数,包括引导扇区 NumberOfFats db 2 ;该分区上FAT的副本数 MaxRootEntries dw 0 ; 对FAT32分区而言,本字段必须设置为 0 TotalSectors dw 0 ; 对FAT32分区而言,本字段必须设置为 0 MediaDescriptor db 0f8h ; 媒体被类型信息,值0xF8表示硬盘 SectorsPerFat dw 0 ; 对FAT32分区而言,本字段必须设置为 0 SectorsPerTrack dw 18 ;包含使用INT13h的磁盘的“每道扇区数”几何结构值 NumberOfHeads dw 2 ;使用INT 13h的磁盘的“磁头数”几何结构值 HiddenSectors dd 0 ;分区上引导扇区之前的扇区数 TotalSectorsBig dd 0 ;全部扇区 SectorsPerFatBig dd 0 ;只被FAT32使用,该分区每个FAT所占的扇区数 ExtendedFlags dw 0 ;此域为FAT32特有。Bits0-3:   活动的FAT(active FAT)数目,只在镜像禁止时才效。Bits 4-6:  保留Bits 7: 0 表示FAT实时镜像到所的FAT表中

          ;1 表示只一个活动的FAT表。这个表就是Bits0-3所指定的那个

;Bits8-15: 保留 FSVersion dw 0 ;此域为FAT32特有 RootDirStartCluster dd 0 ;根目录所在第一个簇的簇号 FSInfoSector dw 0 ;只供FAT32使用, FAT32分区的保留区中的文件系统信息 BackupBootSector dw 6 ;如果不为0,表示在保留区中引导记录的备份数据所占的扇区数,通常为6 Reserved1 times 12 db 0 ;12个字节均为0x00 保留 BootDrive db 80 ;用于BIOS中断0x13得到磁盘驱动器参数,0x00为软盘,0x80为硬盘 Reserved db 0 ;保留 ExtendSig db 29h ;段必须要有能被Windows 2000所识别的值0x28或0x29 SerialNumber dd 00000000h ;在格式化磁盘时所产生的一个随机序号,它有助于区分磁盘 VolumeLabel db 'NO NAME ' ;卷标也作为一个特殊的文件(有文件名无文件内容)保存在根目录中 FileSystem db 'FAT32 ' ;通常设置为“FAT32”

通过后面的注释,还不能对整个属性有一个大概的了解。并且在在上面的属性当中实际有些数值是不正确的,比如BootDrive,实际上MBR有一些信息是在系统安装的时候进行填写,这里只是为了占位符,所以填入的是0,接下来是开头位置的jmp指令的main标号。(具体的FAT分析可以参考FAT手册)
main:
00007C5A  33C9              xor        cx,cx
00007C5C  8ED1              mov        ss,cx            ; 
00007C5E  BCF47B            mov        sp,0x7bf4        ; 首先设置段寄存器和相应的堆栈,注意这里的堆栈式向下增长的,所以当sp设置为7c00的时候不会覆盖掉代码段
00007C61  8EC1              mov        es,cx
00007C63  8ED9              mov        ds,cx
00007C65  BD007C            mov        bp,0x7c00        ;这里SP不等于BP,其中BP和SP之间的数据用于局部变量
00007C68  884E02            mov        [bp+0x2],cl      ;这里bp+2实际上是最开头的第三个nop指令
;**********************************************************************
00007C6B  8A5640            mov        dl,[bp+BootDrive]
00007C6E  B408              mov        ah,0x8
00007C70  CD13              int        0x13            ;获取整个磁盘的参数				 
00007C72  7305              jnc        drive_param_ok  ; 这一条跳转应该不陌生了吧,INT13调用会设置进位标志
drive_param_error:
00007C74  B9FFFF            mov        cx,0xffff        ; We couldn't determine the drive parameters
00007C77  8AF1              mov        dh,cl            ; So just set the CHS to 0xff
drive_param_ok:
00007C79  660FB6C6          movzx    eax,dh            ;将获得的参数数据用于计算整个磁盘的大小,假设没有跳转的话,下面的inc指令将使得整个ax溢出,也就是ax为0,所以整个大小为0
00007C7D  40                inc        ax              ; BIOS的int 13进行读取磁盘的数据操作,功能08H 功能描述:读取驱动器参数 
00007C7E  660FB6D1          movzx    edx,cl            ; 入口参数:AH=08H,DL=驱动器,00H~7FH:软盘;80H~0FFH:硬盘 
00007C82  80E23F            and        dl,0x3f         ; 出口参数:CF=1——操作失败,AH=状态代码,参见功能号01H中的说明,否则, BL=01H — 360K;=02H — 1.2M;=03H — 720K;=04H — 1.44M 
00007C85  F7E2              mul        dx              ; CH=柱面数的低8位  ; CL的位7-6=柱面数的该2位 ;CL的位5-0=扇区数 ;DH=磁头数
                                                       ;上面的mul指令执行之后,数据dx:ax存放的是磁头数目*扇区数目
00007C87  86CD              xchg    cl,ch              ; 两个寄存器交换之后,CX向右移动六位就可以得到柱面数
00007C89  C0ED06            shr        ch,0x6          ; 
00007C8C  41                inc        cx              ;
00007C8D  660FB7C9          movzx    ecx,cx
00007C91  66F7E1            mul        ecx             ; 柱面数*先前的结果得到最终磁盘驱动器的大小,并保存到局部变量当中
00007C94  668946F8          mov        [bp-0x8],eax    ; 
00007C98  837E1600          cmp        word [bp+TotalSectors],byte +0x0    ; 
00007C9C  7538              jnz        print_ntldr_error_message            ; 
00007C9E  837E2A00          cmp        word [bp+FSVersion],byte +0x0        ; 上面进行MBR的属性分析,如果属性不满足则打印出错信息
00007CA2  7732              ja        print_ntldr_error_message             ;
/*****************************************************************
整个FAT32文件系统支持多系统启动的,而FAT32真正的boot sector有三个扇区长,所以微软对FAT32的启动进行了扩展,其中扇区0是传统的MBR,扇区1保存的是文件系统信息
扇区2用于存放额外的启动代码。为了实现多系统启动,所以就约定将win2k的boot sector存放到第十三个sector,前面的第二个sector用于存放98的boot 
00007CA4  668B461C          mov        eax,[bp+HiddenSectors]    ; Get the count of hidden sectors
00007CA8  6683C00C          add        eax,byte +0xc            ; Add 12 to that value so that we are loading the 13th sector of the volume
00007CAC  BB0080            mov        bx,0x8000                ; Read the sector to address 0x8000
00007CAF  B90100            mov        cx,0x1                    ; Read just one sector
00007CB2  E82B00            call    read_sectors            ; Read it
00007CB5  E94803            jmp        0x8000                    ; Jump to the next sector of boot code
print_disk_error_message:
00007CB8  A0FA7D            mov        al,[DISK_ERR_offset_from_0x7d00]
putchars:
00007CBB  B47D              mov        ah,0x7d
00007CBD  8BF0              mov        si,ax           ;这一段实际上是组装整个四,其中si等于7dbf,最后面的代码到了7d6f,然后ret本身一个字节,
get_another_char:                                      ;后面的NTLDR包含11字节,filter包含49字节,同时filter的0可以作为NTLDR的结尾符号;NTLDR_ERR包含19字节,那么7DBF刚好指向DISK_ERR
00007CBF  AC                lodsb
00007CC0  84C0              test    al,al
00007CC2  7417              jz      reboot            ;如果数据等于0,则直接重启
00007CC4  3CFF              cmp     al,0xff           ;最后这里会设置零标志位
00007CC6  7409              jz      print_reboot_message
00007CC8  B40E              mov     ah,0xe
00007CCA  BB0700            mov     bx,0x7
00007CCD  CD10              int     0x10
00007CCF  EBEE              jmp     short get_another_char;如果上面的跳转不成功就会循环打印数据
print_reboot_message:
00007CD1  A0FB7D            mov        al,[RESTART_ERR_offset_from_0x7d00]
00007CD4  EBE5              jmp        short putchars
print_ntldr_error_message:
00007CD6  A0F97D            mov        al,[NTLDR_ERR_offset_from_0x7d00]
00007CD9  EBE0              jmp        short putchars
reboot:
00007CDB  98                cbw
00007CDC  CD16              int        0x16         ;等待
00007CDE  CD19              int        0x19         ;发出重启中断
read_sectors:
00007CE0  6660              pushad
00007CE2  663B46F8          cmp        eax,[bp-0x8] ;首先验证要读的地址是不是在范围内,如果在磁盘驱动范围内,就跳转到7D34开始执行
00007CE6  0F824A00          jc         near 0x7d34
00007CEA  666A00            o32        push byte +0x0;这里利用66前缀强制压入堆栈两个字节也就是0是以word类型存在于堆栈当中
00007CED  6650              push    eax
00007CEF  06                push    es
00007CF0  53                push    bx
00007CF1  666810000100      push    dword 0x10010
00007CF7  807E0200          cmp     byte [bp+0x2],0x0 ;查看是否有改动,最初是设置为0,如果不是等于0则表明已经执行过一次,直接跳过下面的执行
00007CFB  0F852000          jnz     near 0x7d1f
00007CFF  B441              mov     ah,0x41
00007D01  BBAA55            mov     bx,0x55aa
00007D04  8A5640            mov     dl,[bp+BootDrive]
00007D07  CD13              int     0x13              ;利用int 13执行磁盘检验,
00007D09  0F821C00          jc      near 0x7d29
00007D0D  81FB55AA          cmp     bx,0xaa55
00007D11  0F851400          jnz     near 0x7d29
00007D15  F6C101            test    cl,0x1
00007D18  0F840D00          jz      near 0x7d29
00007D1C  FE4602            inc     byte [bp+0x2]    ;设置执行标志
00007D1F  B442              mov     ah,0x42
00007D21  8A5640            mov     dl,[bp+BootDrive]
00007D24  8BF4              mov     si,sp            ;执行int 13中断,AH=42,其中si依次为0x10010,由于bx没有改变,所以这里堆栈当中是8000,es为0,而eax则开始读取的地址,加上开始压入堆栈的word 0组成中断的参数
00007D26  CD13              int     0x13             ;具体分析可以参考上一篇
00007D28  B0F9              mov     al,0xf9          ;仅仅作为占位符号
00007D2A  6658              pop        eax
00007D2C  6658              pop        eax
00007D2E  6658              pop        eax
00007D30  6658              pop        eax           ;清空压入的堆栈参数
00007D32  EB2A              jmp        short 0x7d5e  ;跳过正常的读取流程
00007D34  6633D2            xor        edx,edx       ;恢复原来的C、H、S值,然后利用这些值进行BIOS读取,因为BIOS有标准BIOS和LBA BIOS,所以在上面需要进行判断
00007D37  660FB74E18        movzx      ecx,word [bp+SectorsPerTrack]
00007D3C  66F7F1            div        ecx           ;edx:eax除以ecx得到磁道号,磁道号存放在eax当中
00007D3F  FEC2              inc        dl            ;递增dl,因为dl存放的是余数,所以这里dl实际上扇区号
00007D41  8ACA              mov        cl,dl
00007D43  668BD0            mov        edx,eax       ;
00007D46  66C1EA10          shr        edx,0x10      ;edx向右移动16位,也就是清空edx
00007D4A  F7761A            div        word [bp+NumberOfHeads];磁道号除以磁头数,得到柱面号,余数dl当中存放磁头号
00007D4D  86D6              xchg       dl,dh                  ;交换之后存放到dh当中,因为dl需要存放函数参数
00007D4F  8A5640            mov        dl,[bp+BootDrive]
00007D52  8AE8              mov        ch,al
00007D54  C0E406            shl        ah,0x6
00007D57  0ACC              or         cl,ah
00007D59  B80102            mov        ax,0x201
00007D5C  CD13              int        0x13
00007D5E  6661              popad                   ;验证上面的int 13是否正确执行,如果没能得到正确结果则显示错误,然后退出
00007D60  0F8254FF          jc        near print_disk_error_message
00007D64  81C30002          add        bx,0x200     ;bx存放读入的当前扇区的尾部的位置
00007D68  6640              inc        eax
00007D6A  49                dec        cx
00007D6B  0F8571FF          jnz        near read_sectors
00007D6F  C3                ret                     ;从这里结束整个read过程

NTLDR        db 'NTLDR      '
filler        times 49    db 0

NTLDR_ERR    db 0dh,0ah,'NTLDR is missing',0ffh
DISK_ERR    db 0dh,0ah,'Disk error',0ffh
RESTART_ERR    db 0dh,0ah,'Press any key to restart',0dh,0ah
more_filler    times 16    db 0

NTLDR_offset_from_0x7d00                        db 0
NTLDR_ERR_offset_from_0x7d00                    db 0ach
DISK_ERR_offset_from_0x7d00                        db 0bfh
RESTART_ERR_offset_from_0x7d00                    db 0cch
                        dw 0

                        dw 0aa55h

*******************************************************************************************************

根据上面的分析,整个流程转到8000,开始执行

00008000  660FB64610        movzx eax,byte [bp+NumberOfFats]    ;获得分区上的FAT表项数目
00008005  668B4E24            mov ecx,[bp+SectorsPerFatBig]           ;该分区每个FAT表项所占的扇区数,利用这个数目加上隐藏和保留的数据可以得出起始根目录
00008009  66F7E1                 mul ecx                                                      ;
0000800C  6603461C           add eax,[bp+HiddenSectors]                 ;
00008010  660FB7560E       movzx edx,word [bp+ReservedSectors]    ;
00008015  6603C2                add eax,edx                                               ;
00008018  668946FC           mov [bp-0x4],eax                                       ; 将起始根目录的所在的扇区号存放起来
0000801C  66C746F4FFFFFFFF  mov dword [bp-0xc],0xffffffff           ; 保存0Xffffffff,加上之前使用的三个区间,实际上局部存储都已经被使用了
00008024  668B462C          mov eax,[bp+RootDirStartCluster]         ;读取根目录开始的簇
00008028  6683F802          cmp eax,byte +0x2                                      ;如果小于2,那么不存在用于启动的根目录
0000802C  0F82A6FC          jc near print_ntldr_error_message        ;
00008030  663DF8FFFF0F      cmp eax,0xffffff8                                     ; 将根目录开始的簇和最大的簇号比较,如果没有借位说明超出界限
00008036  0F839CFC          jnc near print_ntldr_error_message     ;
search_root_directory_cluster:
0000803A  6650                    push eax                                                      ; 保存根目录的起始簇号
0000803C  6683E802          sub eax,byte +0x2                                      ;对簇号进行调整,因为起始的两个簇没有使用,所以减去2
00008040  660FB65E0D     movzx ebx,byte [bp+SectsPerCluster]    ; 保存每个簇拥有的扇区数目
00008045  8BF3                   mov si,bx                                                      ;
00008047  66F7E3               mul ebx                                                        ;
0000804A  660346FC          add eax,[bp-0x4]                                         ; 跳过前面保存的数据,直接得到根目录的扇区号,同时EDX保存磁头号和柱面号
read_directory_sector:
0000804E  BB0082              mov bx,0x8200                                             ;
00008051  8BFB                   mov di,bx                                                       ;
00008053  B90100              mov cx,0x1                                                     ;
00008056  E887FC             call read_sectors                                         ; 由于一个扇区是512字节,以十六进制表示就为0x200,所以这次的存放地址是0x8200
check_entry_for_ntldr:
00008059  382D                 cmp [di],ch                                                      ; 测试读到的第一个数据是否为0
0000805B  741E                  jz ntldr_not_found                                        ; 如果为零,则表明NTLDR不存在
0000805D  B10B                 mov cl,0xb                                                      ;
0000805F  56                       push si                                                           ;
00008060  BE707D            mov si,NTLDR ;0x7d70                               ;
00008063  F3A6                  repe cmpsb                                                   ;进行循环比较,比较次数为11
00008065  5E                      pop si                                                              ;
00008066  741B                 jz ntldr_found                                                 ;如果相等,就表明找到NTLDR
00008068  03F9                 add di,cx                                                          ; 否则跳过前面的11个字符串
0000806A  83C715            add di,byte +0x15                                          ; 同时增加
0000806D  3BFB                cmp di,bx                                                        ; 与bx进行比较,如果没有超出一个扇区的范围,就循环比较,直到找到NTLDR为止,
0000806F  72E8                 jc check_entry_for_ntldr                              ;
00008071  4E                     dec si                                                               ; 否则循环进行搜索
00008072  75DA                jnz read_directory_sector                            ;
00008074  6658                pop eax                                                            ; 如果还没能找到NTLDR,则搜索下一个FAT表项
00008076  E86500           call get_fat_entry                                            ;
00008079  72BF                jc search_root_directory_cluster               ;
ntldr_not_found:
0000807B  83C404            add sp,byte +0x4
0000807E  E955FC            jmp print_ntldr_error_message
ntldr_load_segment_address    dw    0x2000
ntldr_found:
00008083  83C404            add sp,byte +0x4                    ; 调整sp,覆盖掉原来保存的根目录
00008086  8B7509            mov si,[di+0x9]                        ;
00008089  8B7D0F           mov di,[di+0xf]                          ;
0000808C  8BC6               mov ax,si                                   ;
0000808E  66C1E010      shl eax,0x10                             ;组装NTLDR的起始簇号
00008092  8BC7              mov ax,di                                     ;
00008094  6683F802          cmp eax,byte +0x2                ; 其中EAX肯定比2要大,否则就出错
00008098  0F823AFC          jc near print_ntldr_error_message    ;
0000809C  663DF8FFFF0F      cmp eax,0xffffff8                    ;
000080A2  0F8330FC          jnc near print_ntldr_error_message    ;
load_next_ntldr_cluster:
000080A6  6650                    push eax                                  ;
000080A8  6683E802          sub eax,byte +0x2                    ;
000080AC  660FB64E0D    movzx ecx,byte [bp+SectsPerCluster]    ;
000080B1  66F7E1               mul ecx                                ;
000080B4  660346FC          add eax,[bp-0x4]                    ;
000080B8  BB0000              mov bx,0x0                            ;
000080BB  06                        push es                                ;
000080BC  8E068180         mov es,[ntldr_load_segment_address]    ;
000080C0  E81DFC            call read_sectors                    ; 将数据读到指定的位置
000080C3  07                       pop es                                ;
000080C4  6658                  pop eax                                ;
000080C6  C1EB04            shr bx,0x4                            ; bx当中包含传递的数目,用于找到下一个存放数据的内存地址
000080C9  011E8180         add [ntldr_load_segment_address],bx    ;
000080CD  E80E00            call get_fat_entry                    ;获取下一个FAT的簇号在EAX当中
000080D0  0F830200         jnc near jump_to_ntldr                ;
000080D4  72D0                 jc load_next_ntldr_cluster            ;
jump_to_ntldr:
000080D6  8A5640             mov dl,[bp+BootDrive]                ;
000080D9  EA00000020        jmp 0x2000:0x0                        ;
get_fat_entry:
000080DE  66C1E002         shl eax,0x2                               ; 根目录的扇区号乘以4
000080E2  E81100               call load_fat_sector                ;
000080E5  26668B01          mov eax,[es:bx+di]                   ; BX等于0,这里实际上是检验整个
000080E9  6625FFFFFF0F      and eax,0xfffffff                    ;
000080EF  663DF8FFFF0F      cmp eax,0xffffff8                    ; 比较一下是否越界
000080F5  C3                ret                                    ;
load_fat_sector:
000080F6  BF007E            mov di,0x7e00                        ; 将FAT表项加载到7e00,刚好是7C00+200
000080F9  660FB74E0B  movzx ecx,word [bp+SectsPerCluster]    ; 得到每一个簇里面包含多少扇区
000080FE  6633D2            xor edx,edx                              ;
00008101  66F7F1            div ecx                                       ;得到簇号存放在EAX当中
00008104  663B46F4       cmp eax,[bp-0xc]                    ; 如果EAX等于0xFFFFFFFF那么就执行函数返回,表明已经达到簇的极限了
00008108  743A                 jz load_fat_sector_end          ;
0000810A  668946F4       mov [bp-0xc],eax                    ; 更新原来保存的起始簇号的信息
0000810E  6603461C       add eax,[bp+HiddenSectors]            ;
00008112  660FB74E0E     movzx ecx,word [bp+ReservedSectors]    ;
00008117  6603C1            add eax,ecx                            ; 跳过保留的信息
0000811A  660FB75E28    movzx ebx,word [bp+ExtendedFlags]    ;
0000811F  83E30F            and bx,byte +0xf                    ; 验证FAT是否有效
00008122  7416                 jz load_fat_sector_into_memory        ; 如果有效就将FAT当中的数据读取到内存当中去
00008124  3A5E10            cmp bl,[bp+NumberOfFats]                 ; 根据bl当中的标志来判断是否还有后续的FAT表项需要分析
00008127  0F83ABFB       jnc near print_ntldr_error_message    ;
0000812B  52                     push dx                                ;
0000812C  668BC8          mov ecx,eax                            ;将当前的FAT偏移暂时保存到ECX当中
0000812F  668B4624       mov eax,[bp+SectorsPerFatBig]        ; 得到每一个FAT表项占用的扇区数目
00008133  66F7E3            mul ebx                                ;由于整个EBX存放的是FAT表项的数目
00008136  6603C1            add eax,ecx                        ;跳到下一个FAT表项
00008139  5A                      pop dx                                ;恢复dx
load_fat_sector_into_memory:
0000813A  52                   push dx                                 ;
0000813B  8BDF             mov bx,di                              ;
0000813D  B90100        mov cx,0x1                            ;
00008140  E89DFB        call read_sectors                ;
00008143  5A                  pop dx                                ; Restore dx
load_fat_sector_end:
00008144  8BDA           mov bx,dx                            ;表明读取了多少数据
00008146  C3                ret                                         ; 返回
00008147  0000              add [bx+si],al
00008149  0000              add [bx+si],al
0000814B  0000              add [bx+si],al
0000814D  0000              add [bx+si],al
0000814F  0000              add [bx+si],al
00008151  0000              add [bx+si],al
00008153  0000              add [bx+si],al
00008155  0000              add [bx+si],al
00008157  0000              add [bx+si],al
00008159  0000              add [bx+si],al
0000815B  0000              add [bx+si],al
0000815D  0000              add [bx+si],al
0000815F  0000              add [bx+si],al
00008161  0000              add [bx+si],al
00008163  0000              add [bx+si],al
00008165  0000              add [bx+si],al
00008167  0000              add [bx+si],al
00008169  0000              add [bx+si],al
0000816B  0000              add [bx+si],al
0000816D  0000              add [bx+si],al
0000816F  0000              add [bx+si],al
00008171  0000              add [bx+si],al
00008173  0000              add [bx+si],al
00008175  0000              add [bx+si],al
00008177  0000              add [bx+si],al
00008179  0000              add [bx+si],al
0000817B  0000              add [bx+si],al
0000817D  0000              add [bx+si],al
0000817F  0000              add [bx+si],al
00008181  0000              add [bx+si],al
00008183  0000              add [bx+si],al
00008185  0000              add [bx+si],al
00008187  0000              add [bx+si],al
00008189  0000              add [bx+si],al
0000818B  0000              add [bx+si],al
0000818D  0000              add [bx+si],al
0000818F  0000              add [bx+si],al
00008191  0000              add [bx+si],al
00008193  0000              add [bx+si],al
00008195  0000              add [bx+si],al
00008197  0000              add [bx+si],al
00008199  0000              add [bx+si],al
0000819B  0000              add [bx+si],al
0000819D  0000              add [bx+si],al
0000819F  0000              add [bx+si],al
000081A1  0000              add [bx+si],al
000081A3  0000              add [bx+si],al
000081A5  0000              add [bx+si],al
000081A7  0000              add [bx+si],al
000081A9  0000              add [bx+si],al
000081AB  0000              add [bx+si],al
000081AD  0000              add [bx+si],al
000081AF  0000              add [bx+si],al
000081B1  0000              add [bx+si],al
000081B3  0000              add [bx+si],al
000081B5  0000              add [bx+si],al
000081B7  0000              add [bx+si],al
000081B9  0000              add [bx+si],al
000081BB  0000              add [bx+si],al
000081BD  0000              add [bx+si],al
000081BF  0000              add [bx+si],al
000081C1  0000              add [bx+si],al
000081C3  0000              add [bx+si],al
000081C5  0000              add [bx+si],al
000081C7  0000              add [bx+si],al
000081C9  0000              add [bx+si],al
000081CB  0000              add [bx+si],al
000081CD  0000              add [bx+si],al
000081CF  0000              add [bx+si],al
000081D1  0000              add [bx+si],al
000081D3  0000              add [bx+si],al
000081D5  0000              add [bx+si],al
000081D7  0000              add [bx+si],al
000081D9  0000              add [bx+si],al
000081DB  0000              add [bx+si],al
000081DD  0000              add [bx+si],al
000081DF  0000              add [bx+si],al
000081E1  0000              add [bx+si],al
000081E3  0000              add [bx+si],al
000081E5  0000              add [bx+si],al
000081E7  0000              add [bx+si],al
000081E9  0000              add [bx+si],al
000081EB  0000              add [bx+si],al
000081ED  0000              add [bx+si],al
000081EF  0000              add [bx+si],al
000081F1  0000              add [bx+si],al
000081F3  0000              add [bx+si],al
000081F5  0000              add [bx+si],al
000081F7  0000              add [bx+si],al
000081F9  0000              add [bx+si],al
000081FB  0000              add [bx+si],al
000081FD  0055AA            add [di-0x56],dl        ; We can't forget the infamous boot signature

你可能感兴趣的:(windows,内核)