zoukankan
html css js c++ java
MBR代码分析
西西,很早以前的东东了,都不太记得了,有什么错误和不足欢迎大家指出
机器加电或按reset键后都要进行系统复位,复位后CS=FFFFH,IP=0000H
那么自然就从FFFF:0000H处开始执行指令,这个地方只有一条JMP指令
跳转到系统自检程序处,系统自检完成后把软盘的第一个扇区(如果由软盘启动)
或者硬盘的第一个扇区,即
MBR
扇区(如果由硬盘启动)读入到0:7C00H处
然后把控制权交出,从0:7C00H处继续执行,下面就是硬盘的
MBR
代码分析
其中的引导扇区是指硬盘相应分区的第一个扇区,是和操作系统有关的
操作系统的引导是由它来完成的,而
MBR
并不负责,
MBR
和操作系统无关
他的任务是把控制权转交给操作系统的引导程序
程序流程:
1 将程序代码由0:7C00H移动到0:0600H(注,BIOS把
MBR
放在0:7C00H处)
2 搜索可引导分区,即80H标志
成功:goto 3
失败:跳入ROM BASIC
无效分区表:goto 5
3 读引导扇区
失败:goto 5
成功:goto 4
4 验证引导扇区最后是否为55AAH
失败:goto 5
成功:goto 6
5 打印错误进入无穷循环
6 跳到0:7C00H进行下一步启动工作
下面将用汇编语言写出这一段代码,并进行说明。
;
MBR
.ASM
; MASM
MBR
; LINK
MBR
; EXE2BIN
MBR
.MODEL tiny
.CODE
;设置寄存器及堆栈值
org 0
Head:
Start:
cli
xor ax,ax
mov ss,ax
mov sp,7C00H ;ss:sp=0:7C00H
mov si,sp
push ax
pop es
push ax
pop ds ;es=ds=0
sti
;将程序代码由0:7C00H移动到0:0600H处
cld
mov di,600H
mov cx,100H ;100H Words=512 Bytes,即一个扇区大小
repne movsw
db 0EAH ;这个是FAR JUMP的机器码
dw offset Continue+600H, 0000H ;这个是跳转目的地址,即0:061DH
;搜索可引导分区
Continue:
mov si,600H+1BEH ;si指向分区表
mov bl,4 ;四个分区
FindBoot:
cmp byte ptr[si],80H
je SaveRec ;读扇区位置
cmp byte ptr[si],0
jne Invaild ;无效分区
add si,10H
dec bl
jnz FindBoot
int 18H ;进入ROM BASIC
;读取引导分区的扇区,柱面号
SaveRec:
mov dx,[si]
mov cx,[si+2]
mov bp,si
;检查其余分区表
FindNext:
add si,10H
dec bl
jz SetRead
cmp byte ptr[si],0 ;是否存在非法分区
je FindNext
Invaild:
mov si,offset ErrMsg1+600H
;字符串输出子程序
PrintStr:
lodsb
cmp al,0
je DeadLock
push si
mov bx,7
mov ah,0EH ;输出字符
int 10H
pop si
jmp short PrintStr ;下一字符
DeadLock:
jmp short DeadLock ;无穷循环,也可以写成jmp $
;读引导扇区
SetRead:
mov di,5 ;读取次数
ReadBoot:
mov bx,7C00H
mov ax,201H
push di
int 13H ;cx,dx已经在SaveRec处得到
pop di
jnc GoBoot ;成功则启动
xor ax,ax
int 13H ;reset驱动器,然后再读取
dec di
jnz ReadBoot
mov si,offset ErrMsg2+600H
jmp short PrintStr 失败输出信息,并进入无穷循环
;检查读入的引导扇区
GoBoot:
mov si,offsetErrMsg3+600H
mov di,7C00H+1FEH
cmp word ptr[di],0AA55H
jne PrintStr ;非AA55标志则输出错误信息
mov si,bp ;si指向可启动分区
db 0EAH,0,7CH,0,0 ;跳转至0:7C00H
ErrMsg1 db Invaild partition table,0
ErrMsg2 db Error loading operating system,0
ErrMsg3 db Missing operating system,0
Tail:
FillNum equ 1BEH-(Tail-Head) ;计算填0数目
db FillNum dup(0)
;四个分区表项数据,跟分区情况有关,详细含义另解
PartTable db 80H,1,1,0,4,4,0D1H,2,11H,0,0,0,0FEH,0FFH,0,0
db 0,0,0C1H,3,5,4,0D1H,0FEH,0FFH,0FFH,0,0,0ACH,53H,0,0
db 20H dup(0)
ID dw 0AA55H
end start
;如果开始试用org 600H,那么访问数据时就不必加上600H,如mov si,offset
ErrMsg2+600H
;可写为mov si,offset ErrMsg2,这时就不能用exe2bin得到数据,必须试用
debug
;
debug
mbr
.exe
;-nmbr.bin
;-rcx 200
;-wcs:600
;-q
在硬盘的第一个扇区上保存着分区信息,称为主分区表,共有四项
读取分区表必须使用bios的int 13h,一般使用
debug
就可以了
debug
-a
xxxx:0100 mov ax,201
mov bx,200
mov cx,1
mov dx,80 ;如果是第二个硬盘则是81...
int 13
int 20
xxxx:????
-g
这时xxxx:0200开始的512字节就是分区表所在的扇区,前面一部分为
MBR
,
在
debug
中用-d3be l40就可以看到64字节的分区表信息,16个字节为一项
用-e命令就可以修改,改完后可以重新写回去,只要把前面代码中的
mov ax,201改为mov ax,301即可,或者直接把102处的2改成3,比如:
-e 102
xxxx:0102 02.3
-g=100
这样就写回去了,不过要小心哦,呵呵,弄不好就坏了,大家还是把分区
表手抄一份存下来吧,会省去很多麻烦的
下来说一下分区表项的具体意义,取其中一项举个例子:
80 01 01 00 0B 3F FF 00 3F 00-00 00 81 4F 2F 00
1 (80)引导标志,80代表可引导,00代表不可引导,一般必须且只能
有一个分区表项的引导标志为80,除非你自己修改
MBR
2 (01)分区开始磁头
3,4 (01 00)=(1,0)分区开始柱面和扇区(后面后详解)
5 (0B)分区类型(后面有详解)
6 (3F)=(63)分区结束磁头
7,8 (FF 00)=(768,63分区结束柱面和扇区(同上)
9-12 (3F 00 00 00)=(63)此分区前扇区总数,即相对扇区数
13-16 (81 4F 2F 00)=(002F4F81H=3100545)此分区扇区总数
由于柱面和扇区共用两个字节表示,而柱面号为10位,最大1023,扇区号为6位,最大63
扇区号
______|____
| |
( 7 6 5 4 3 2 1 0 ) ( 7 6 5 4 3 2 1 0 )
|___| |_____________|
|________________________|
|_
柱面号
关于分区类型,常见的有:
00 未用,Unused
01 DOS-12(FAT 12)
02 XENIX
04 DOS-16(FAT 16)(分区<32M时用的,还有么?)
05 EXTEND(DOS扩展分区)
06 BIGDOS(>32M)(这个才是现在常说的FAT 16)
07 HPFS(OS/2)(好像NTFS也是这个标记)
0B FAT 32
0F 这个一时不确定,西西
50 DM
63 386/ix(unix)
64 NET286(Novell)
65 NET386(Novell)
FF BBT(UNIX Bad Block Table)
下面有几个平衡式用来计算分区参数:
1 第一分区参数平衡式
扇区总数=(结束柱面+1)*磁头数*每柱面扇区数-相对扇区数
例如:3100545=(768+1)*64*63-63
2 其它分区参数平衡式
扇区总数=(结束柱面-起始柱面+1)*磁头数*每柱面扇区数
00 00 C1 01 05 3F FF FD C0 4F-2F 00 C0 90 0F 00
000F90C0H=1020096,(FF FD)=(1021,63),(C1 01)=(769,1)
例如:1020096=(1021-769+1)*64*63
3 第一分区相对扇区=每柱面扇区数
其它分区相对扇区=上一分区相对扇区+上一分区扇区总数
扩展分区信息是一个链状结构,很多人不知道在删分区时把前面的分区删掉导致后面的分区找不到,原因就在于此,我们从主分区表中取出扩展分区项进行一下分析,如下:
00 00 01 C0 05 FE BF 6E C0 10-2F 00 EF A6 69 00
由此我们可以得到数据:
开始磁头:00
开始柱面扇区:01 C0=(192,0)
用
debug
debug
-a100
xxxx:0100 mov ax,201
mov bx,200
mov cx,05c0 ;开始柱面扇区号
mov dx,80 ;dh中为开始磁头号,这里为0
int 13
int 20
xxxx:????
-g=100
-d3be l10
读出的扇区中有两个16字节的分区表项和最后的一个55AA标志,这两个
分区表项为:
00 01 01 C0 06 FE 7F 97 3F 00-00 00 99 F2 34 00
00 00 41 98 05 FE BF 6E D8 F2-34 00 17 B4 34 00
第一个分区类型为6,其实这是第一个逻辑分区,含义和主分区表项相同
第二个分区类型为5,这其实是指向下一个扩展分区表的从这里我们可以得到:
开始磁头:0
开始柱面扇区:41 98=(408,1)
继续用
debug
读出(mov cx,9841)得到
00 01 41 98 06 FE BF 6E 3F 00-00 00 D8 B3 34 00
只有一个表项,是第二个逻辑盘,而且是逻辑盘链的最后一个可以看到,主分区表是非常重要的,所以除了小心操作外,还应当进行备份最安全的备份方式就是用笔抄下来,呵呵,放到安全的地方,当然,每次重新进行分区后还应当及时更新的说,:P
从前面可以看出,分区表里最重要的还是柱面号,其它比如磁头号都是0或者1或者最大值,扇区号都是1或63(最大值),扇区总数什么的也都能算出来,所以分区时最好把各分区的柱面号记下来,这样一旦分区信息被破坏就可以进行恢复了。
如果主分区表不幸丢失或者逻辑分区链被破坏,那么只要从硬盘上找出还存在的分区信息,就有可能部分恢复分区信息,甚至全部可以恢复,不过这样的麻烦大家还是尽量避免吧,怎么恢复呢,偶也没干过,下回一边说一边练,呵呵
查看全文
相关阅读:
Maven项目文档
Maven外部依赖
Nexus使用
android -chrome 调试
gradle问题 cordova
OTS parsing error: invalid version tag woff和ttf文件被Filter拦截
生产者和消费者模式--java设计模式
Procedure-Function oracle
ImageIO(图像处理)
wpf表单验证
原文地址:https://www.cnblogs.com/ahuo/p/411585.html
最新文章
C89:异常处理
MFC:BMP图像
数据结构:字典树(Trie树)
数据结构:二叉树
数据结构:队列
数据结构:链表
数据结构:堆/栈
数据结构:哈希表
MFC:基础篇 第一章 MFC初始化
OpenCV2:小学篇 图像灰度变换技术-阈值化处理
热门文章
微信小程序1. Forgot to add page route in app.json. 2. Invoking Page() in async task.
HTML 居中(水平、垂)
width,height为多少px时,A4纸打印时刚好一页?(转载)
读书方法(如果努力有用的话,那还要天才干什么!)
html5 直接点击呼叫号码
背景乐 歌曲
HTML5 判别当前浏览设备 如何有网页判别设备
iOS 海外版发布APP,设置名称注意
fmdb的使用教程
swift3.0懒加载,自定义构造函数创建
Copyright © 2011-2022 走看看