`
szy56szy
  • 浏览: 12648 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

windows 7 的 MBR 分析

 
阅读更多

windows 7 的 MBR 分析
2010年10月04日
  000001C0  21           /* 起始 sector 号 */
  000001C1  00           /* 起始 cylinder 号 */
  000001C2  07           /* 系统属性 ID 标记 
  00h:未知操作系统 
  01h:DOS FAT12(16位扇区数) 
  02h:XENIX 
  04h:DOS FAT16(16位扇区数) 
  05h:DOS 扩展分区(DOS 3.3+) 
  06h:DOS 4.0 (Compaq 3.31), 32位扇区数 
  07h:HPFS/NTFS
  0ah:OS/2
  0bh:win95 fat32
  0ch:win95 fat32 (LBA)
  ... ...
  */
  000001C3  DF           /* 结束 header 号 */
  000001C4  13           /* 结束 sector 号 */
  000001C5  0C           /* 结束 cylinder 号 */
  000001C6  00080000      /* 此分区前的扇区总数 */  
  000001CA  00200300     /* 此分区的扇区总数 */
  /************** DPT2 分区表2:从 0x1CE 到 0x1DD *******************/
  000001CE  00              
  000001CF  DF  /* 起始 header */
  000001D0  14            /* sector */  
  000001D1  0C            /* cylinder */
  000001D2  07            /* file type flag */
  000001D3  FE            /* 结束 header */
  000001D4  FF            /* sector */
  000001D5  FF            /* cylinders */
  000001D6  00280300
  000001DA  00C83C01
  /********  1DE - 1ED  =  DPT3 **********************/
  000001DE  00
  000001DF  00
  000001E0  00
  000001E1  00
  000001E2  00
  000001E3  00
  000001E4  00
  000001E5  00
  000001E6  00000000
  000001EA  00000000
  /***************  1EE - 1FD = DPT4 ********************/
  000001EE  00
  000001EF  00
  000001F0  00
  000001F1  00
  000001F2  00
  000001F3  00
  000001F4  00 
  000001F5  00
  000001F6  00000000
  000001FA  00000000
  000001FE  55AA            /* MBR 标记 */  分区3 和分区4 都是空的。
  上面的代码是用 nasm 中的 ndisasmw 反汇编出来的结果的。事实上,还有一部分不是代码部分,是数据区域 从 0x00 - 0x162 :这是 MBR 的主体代码区域
  从 0x162 - 0x1bd:这是 MBR 用到的数据区域 
  从 0x1be - 0x1fd: 这是 MBR 的磁盘分区表区域 
  从 0x1fe - 0x1ff:这是 MBR 的标志 "55AA"  1、 mbr 前期准备工作  00000000  33C0              xor ax,ax
  00000002  8ED0              mov ss,ax
  00000004  BC007C            mov sp,0x7c00
  00000007  8EC0              mov es,ax
  00000009  8ED8              mov ds,ax 0000000B  BE007C            mov si,0x7c00
  0000000E  BF0006            mov di,0x600
  00000011  B90002            mov cx,0x200
  00000014  FC                cld
  00000015  F3A4              rep movsb 00000017  50                push ax
  00000018  681C06            push word 0x61c
  0000001B  CB                retf 代码中,把所有 segment 都设为 0,然后从 0x7c00 开始复制 512 bytes 到 0x600 区域,然后转到 0x61c 开始执行
  实际上是把 mbr 重新复制到 0x600 处,然后从指令 retf 的下一条指令,即:指令 sti 处开始继续执行下去。
  但是此时,ip 是位于 0x61c 处,0x61c 与 0x7c1c 代码是一样的。  关于 0x7c00:
  bios 执行完最后的一步工作是:0x19 中断从硬盘 0 扇区(即:MBR)读取 1 个 sector(512 bytes)到内存 0x7c00 处。
  再跳到 0x7c00 处交由 MBR 代码继续执行。 2、 读磁盘到 0x7c00 
  MBR 的下一步工作就是读磁盘,下面来看一看 MBR 是如何读磁盘。
  (1)读磁盘前检查分区是否可启动 
  代码接着走到: 0000001C  FB                sti
  0000001D  B90400            mov cx,0x4
  00000020  BDBE07            mov bp,0x7be               /* MBR 的 0x1be 即:DPT1 */
  00000023  807E0000          cmp byte [bp+0x0],0x0      /* 检查 DPT1 的 boot indicator */
  00000027  7C0B              jl 0x34                    /* 如果不是 0 的话,视为 0x80,进行下一次读工作 */
  00000029  0F850E01          jnz word 0x13b             /* 不是,打印出错信息,最后 hlt 停机 */   跳到 0x34 处是读磁盘的代码,而跳到 0x13b 处是打印出错信息,最终的结果是 hlt 
  打印出错信息,稍后再看,下一步先看一看 MBR 是如何读磁盘。
  (2)读磁盘的方式
  在 win7 的 MBR 中使用 int 0x13 扩展功能来读取磁盘,代码接着走到: 代码接着:
  0000002D  83C510            add bp,byte +0x10
  00000030  E2F1              loop 0x23
  00000032  CD18              int 0x18 00000034  885600            mov [bp+0x0],dl          /* 首次的 dl 值是 int 0x19 中断遗留下的,dl = 0x80 */ 00000037  55                push bp /* 如果不成功的反复读 5 次 */
  00000038  C6461105          mov byte [bp+0x11],0x5   /* DPT1[0] 内存作为临时变量。
  [bp + 0x11] 实际上是 DPT2 的 boot indicator 处,而 [bp + 0x10] 则是 DPT1 的最后一个 byte 
  ★ 代码接下来测试是否支持 int 0x13 的扩展功能
  ★ 如果支持,则:置标志位为 1 
  ★ 如果不支持,则跳到 0x87 处,而 0x87 是使用 int 0x13 原有功能来读取磁盘。(非扩展) 
  (3)使用 int 0x13 扩展来读取磁盘  代码接着:
  /* 以下是使用 int 0x13 扩展功能读 disk */
  00000061  666800000000      push dword 0x0
  00000067  66FF7608          push dword [bp+0x8]   /* start sectors for read */
  0000006B  680000            push word 0x0
  0000006E  68007C            push word 0x7c00   /* buffer address */
  00000071  680100            push word 0x1
  00000074  681000            push word 0x10
  00000077  B442              mov ah,0x42
  00000079  8A5600            mov dl,[bp+0x0]      /* hard disk */
  0000007C  8BF4              mov si,sp            /* buffer_packet 的 address */
  0000007E  CD13              int 0x13             /* 从disk 0x100000 读入*/
  00000080  9F                lahf
  00000081  83C410            add sp,byte +0x10    /* skip buffer */
  00000084  9E                sahf
  00000085  EB14              jmp short 0x9b 代码使用 int 0x13 的 0x42 号功能读扇区。 红色标注部分:这部分实际上是一个局部分变量,这个变量是个 struct(结构体),其定义用 c 描述如下:  这个 struct 的大小为 16 bytes 即:0x10 bytes,对就于指令 push word 0x10 
  它将从 [bp + 0x8] 处得出从哪个 sector 开始读,这个 [bp + 0x8] 从前面分析得知:它是 DPT1 的"分区前面的扇区数"
  实际上它是标明分区1从哪个逻辑扇区开始。从前面可知:这个值就是 2048,因此,代码是从扇区 2048 开始读, 
  这个 2048 就是分区1 的开始扇区,它是个逻辑扇区概念,而非(cylinder/head/sector)表示法。 
  ★ 代码中将从 2048 号扇区开始读 1 个扇区到 0x7c00 处,最后,代码将跳到 0x9b 处 
  更详细的 int 0x13 / ah = 0x42 用法,见:int 0x13 扩展读(ax = 0x42)
  (4)使用 int 0x13 原有功能来读取磁盘 代码接着:
  /* read sector into memory */
  00000087  B80102            mov ax,0x201          /* al =1 --> 读 1 个 sector */
  0000008A  BB007C            mov bx,0x7c00         /* es:bx = buffer */
  0000008D  8A5600            mov dl,[bp+0x0]       /* hard disk */
  00000090  8A7601            mov dh,[bp+0x1]       /* 从哪个 head 开始读 */
  00000093  8A4E02            mov cl,[bp+0x2]       /* 从哪个 sector 开始读 */
  /* 其中低 6 bits 是 sector,高2位是cylinder *./
  00000096  8A6E03            mov ch,[bp+0x3]       /* 从哪个 cylinder 开始读 */
  00000099  CD13              int 0x13 如果不支持 int 0x13 扩展则使用原有功能读磁盘。
  原有的读磁盘模式是:指定 head、cylinder 以及 sector 使用 int 0x13 原有功能的缺点:
  由于使用 cylinder/head/sector 的模式:
  cylinder 最大只支持 0x3ff,head 最大只支持 0xff,sector 最大只支持 0x3f
  那么:
  最大的访问容量为:(0x3ff * 16065 + 0xff * 63 + 0x3f) * 512 ≈ 8g,超过 8g 的磁盘将无法访问。 因此,有必要引入扩展的 int 0x13 功能  int 0x13 扩展功能的优点:
  显而易见:int 0x13 扩展功能可访问的容量远远超过原有功能,可以说访问多大都行,
  它使用了 struct 的访问模式:提供 64 位的起始扇区值,16 位的一次访问扇区数。
  理论上,可以说是非常惊人的访问容量。 (5)读后续处理 代码接着:
  /**** 读完后续处理 */
  0000009B  6661              popad
  0000009D  731C              jnc 0xbb           /* succssed jump */
  /* 不成功的话,反得读 5 次 */
  0000009F  FE4E11            dec byte [bp+0x11] /* 进行 5 次读 disk */
  000000A2  750C              jnz 0xb0
  /* 读完 5 次后,仍旧不成功,打印出错信息,htl */
  000000A4  807E0080          cmp byte [bp+0x0],0x80
  000000A8  0F848A00          jz word 0x136
  000000AC  B280              mov dl,0x80
  000000AE  EB84              jmp short 0x34
  /* 读 sector 不成功时,disk controller 复位再重新读 */
  000000B0  55                push bp
  000000B1  32E4              xor ah,ah
  000000B3  8A5600            mov dl,[bp+0x0]
  000000B6  CD13              int 0x13
  000000B8  5D                pop bp
  000000B9  EB9E              jmp short 0x59 这段代码功能是处理 int 0x13 后续工作,如果 int 0x13 读失败,则将 disk controller 复位,再重新读,反复读 5 次,
  仍旧不成功的,将打印出错信息后 hlt 
  (6)成功读取后 代码接着:
  /* 读 sector 成功后 */
  000000BB  813EFE7D55AA      cmp word [0x7dfe],0xaa55
  000000C1  756E              jnz 0x131         /* 不是,打印错信息,hlt */
  000000C3  FF7600            push word [bp+0x0]
  000000C6  E88D00            call word 0x156    /* 从 64H 读 1 byte */ 
  000000C9  7517              jnz 0xe2          /* 缓冲区满,不能写*/
  000000CB  FA                cli
  000000CC  B0D1              mov al,0xd1       /* 准备写数据到 0x60 端口中*/
  000000CE  E664              out 0x64,al
  000000D0  E88300            call word 0x156
  000000D3  B0DF              mov al,0xdf
  000000D5  E660              out 0x60,al
  000000D7  E87C00            call word 0x156
  000000DA  B0FF              mov al,0xff
  000000DC  E664              out 0x64,al
  000000DE  E87500            call word 0x156
  000000E1  FB                sti
  000000E2  B800BB            mov ax,0xbb00
  000000E5  CD1A              int 0x1a
  000000E7  6623C0            and eax,eax
  000000EA  753B              jnz 0x127 代码中再次核对,是否 55aa 标志,如果不是将打印出错信息后 hlt 
  代码中还将测试键盘读/写缓冲区,然后往键盘端口 0x60 写命令字。 
  call word 0x156 这个子过程就是测试读/写缓冲区过程。
  代码最终将转去 0x127 执行 
  (7)代码最终会返回到 0x7c00 继续执行  代码接着:
  000000FB  666807BB0000      push dword 0xbb07
  00000101  666800020000      push dword 0x200
  00000107  666808000000      push dword 0x8
  0000010D  6653              push ebx
  0000010F  6653              push ebx
  00000111  6655              push ebp
  00000113  666800000000      push dword 0x0
  00000119  6668007C0000      push dword 0x7c00
  0000011F  6661              popad
  00000121  680000            push word 0x0
  00000124  07                pop es
  00000125  CD1A              int 0x1a
  /* 最终代码会重新跳会到 0x7c00 处执行 */
  00000127  5A                pop dx
  00000128  32F6              xor dh,dh
  0000012A  EA007C0000        jmp word 0x0:0x7c00
  0000012F  CD18              int 0x18 在 0x127 处的代码是 MBR 代码的最终出口。
  代码显示:MBR 最终的出口是:重新跳会到 0x7c00 继续执行,而此时,0x7c00 处已经是 分区1 的代码。(即:2048 扇区)
  很抱歉,我暂时不了解 int 0x1a 第 0xbb00 的作用。如果您了解 int 0x1a 中断第 0xbb00 作用,请您留言。:) 
  3、 MBR 将分区1的 1 个扇区读入 0x7c00 后,跳到 0x7c00 处继续执行。 
  下面看看 MBR 剩余的错误处理模块: 代码接着:
  /* 打印出错信息,hlt */
  00000131  A0B707            mov al,[0x7b7]            /* 索引号为 9A */
  00000134  EB08              jmp short 0x13e
  00000136  A0B607            mov al,[0x7b6]            /* 索引号为 7B */
  00000139  EB03              jmp short 0x13e
  0000013B  A0B507            mov al,[0x7b5]            /* 索引号为 63 */
  0000013E  32E4              xor ah,ah
  00000140  050007            add ax,0x700
  00000143  8BF0              mov si,ax
  00000145  AC                lodsb
  00000146  3C00              cmp al,0x0
  00000148  7409              jz 0x153
  0000014A  BB0700            mov bx,0x7
  0000014D  B40E              mov ah,0xe
  0000014F  CD10              int 0x10
  00000151  EBF2              jmp short 0x145
  00000153  F4                hlt
  00000154  EBFD              jmp short 0x153 这里需要使用 MBR 的字符串信息:  代码接着:
  /********** 下面的区域是 mbr 常量符: mbr_str **************/
  /*
  char *mbr_str = "Invalid partition table."
  "Error loading operation system."
  "Missing operation system."
  */
  00000163  496E7661 6C696420 70617274 6974696F 
  00000173  6E207461 626C6500 4572726F 72206C6F
  00000183  6164696E 67206F70 65726174 696E6720
  00000193  73797374 656D004D 69737369 6E67206F
  000001A3  70657261 74696E67 20737973 74656D  /* 下面是字符串索引值 */
  000001B2  00
  000001B3  00
  000001B4  00
  000001B5  63
  000001B6  7B
  000001B7  9A
  000001B8  46
  000001B9  69
  000001BA  6C
  000001BB  65
  000001BC  20
  000001BD  73 在出错处理过程里,根据索引值找到相应的出错信息,然后使用 int 0x10 打印出错信息,最后是 hlt 停机指令。 
  4、最后的 1BE ~ 1FD 是磁盘分区表。 四、总结 MBR 的作用   MBR 的作用主要为:检测分区的合法性, 然后,读活动分区(分区1)的引导记录到 0x7c00,重新返回到 0x7c00 执行。 
分享到:
评论

相关推荐

    windows7的MBR分析.pdf

    windows7的MBR分析.pdf

    Windows 7的MBR引导代码分析【汇编】

    把Windows 7的MBR引导代码翻译为汇编代码,并进行分析

    Windows启动之MBR,PBR分析

    Windows启动之MBR,PBR汇编源代码分析!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    MBR病毒分析

    MBR病毒分析 一、基础知识 1、 Windows启动过程 系统引导过程主要由以下几个步骤组成(以硬盘启动为例) 1、 开机; 2、 BIOS加电自检(POST---Power On Self Test),内存地址为0fff:0000; 3、 将硬盘第一个扇区(0头0道...

    刚Windows xp读出来的MBR代码详细分析

    花了两天时间,查了上百篇资料,终于彻底地完成了从我电脑里读出来的MBR的代码注释,接下来准备分析DBR代码。

    MBR病毒分析1

    1、 开机 3、 将硬盘第一个扇区(0 头 0 道 1 扇区,也就是 Boot Sector)读入内存地址 0000:7c00 处 4、 检查(WORD)000

    WishRecy数据恢复软件

    4、兼容全线Windows系统:完美兼容Win2000、WinXp、Win2003、Win2008、Vista、Win7、win8、Win10、WinAll; 5、急速扫描智能分析:基于底层存储技术,扫描速度极快,多线程分析处理数据,不用完全扫描即可分析全盘...

    winss解决方案.pdf

    原因分析 win8/win10系统均添加快速启动功能,预装的win8/win10电脑默认都是UEFI引导和GPT硬盘,传统的引导方式为Legacy引导和MBR硬盘,UEFI必须跟GPT对应,同理Legacy必须跟MBR对应。如果BIOS开启UEFI,而硬盘分区...

    WishData数据恢复软件

    4、兼容全线Windows系统:完美兼容Win2000、WinXp、Win2003、Win2008、Vista、Win7、win8、Win10、WinAll; 5、急速扫描智能分析:基于底层存储技术,扫描速度极快,多线程分析处理数据,不用完全扫描即可分析全盘...

    hopeData数据恢复软件.zip

    4、兼容全线Windows系统:完美兼容Win2000、WinXp、Win2003、Win2008、Vista、Win7、win8、Win10、WinAll; 5、急速扫描智能分析:基于底层存储技术,扫描速度极快,多线程分析处理数据,不用完全扫描即可分析全盘...

    PQVF(给XP找回纯DOS的软件)

    PQVF软件是部分网友分析了PQ Magic的相关文件,并提取了部分文件制作的软件,可以让那些Windows XP用户迅速引导到纯DOS下,重新启动后又可以正常使用Windows XP启动。  下载后的pqvf.exe文件是一个自解压程序,...

    PQVF制造自己的一键还原

    PQVF软件是部分网友分析了PQ Magic的相关文件,并提取了部分文件制作的软件,可以让那些Windows XP用户迅速引导到纯DOS下,重新启动后又可以正常使用Windows XP启动。  下载后的pqvf.exe文件是一个自解压程序,...

    R-Studio 誤刪檔案救援

    * 识别和分析动态(Windows 2000/XP/2003/Vista)、基本和 BSD (UNIX) 分区布局方案。 * 损坏的 RAID 恢复。如果操作系统不能识别出您的 RAID,您可以从其组件创建一个虚拟的 RAID。这样的虚拟 RAID 可以当作真实的 ...

    极限数据恢复软件.zip

    4、兼容全线Windows系统:完美兼容Win2000、WinXp、Win2003、Win2008、Vista、Win7、win8、Win10、WinAll; 5、急速扫描智能分析:基于底层存储技术,扫描速度极快,多线程分析处理数据,不用完全扫描即可分析全盘...

    超级数据恢复软件-简单易用且功能强大的文件恢复软件

    MOD/ 3GP/ RMVB/ PDF/ WAV/ ZIP/ RAR/ AMR/ SWF/ X3F/ LXE/ FLV/ NEF/ SR2/ CDR/ RAF/ CR2/ PNG等多种文件的恢复,对于被CHKDSK磁盘检查后变成FILEnnnn.CHK的文件也能识别恢复出来,支持MBR分区表和Vista和Win7的GPT...

    兔卫士 优化系统 是你的电脑快如飞

    16)磁盘整理,提供最快速的磁盘分析和整理,和动辄超过几个小时的Windows自带磁盘整理相比,这个整理不仅能智能防止系统出现更多的碎片文件,还能在几分钟内完成磁盘的整理。 17)插件清理,用户可以用此功能来扫描...

    易我数据恢复向导.V2.1.0 破解版

    向导模式引导数据恢复:它将一步步的指引你轻松简单的完成数据恢复,智能化的分区分析和文件搜索,简单的功能设置。《易我数据恢复向导》能够恢复以下原因导致的文件丢失:有意或无意的文件删除、病毒破坏、格式化、...

    易我数据恢复向导V2.1.0绿色

    智能化的分区分析和文件搜索,简单的功能设置。 《易我数据恢复向导》能够恢复以下原因导致的文件丢失: 有意或无意的文件删除 病毒破坏 格式化 FDISK或其他磁盘分区工具使用不当 所有其他非物理破坏造成的数据...

Global site tag (gtag.js) - Google Analytics