磁盘学习+MBR学习
http://blog.csdn.net/zcc1414/article/details/12208897
磁头数: 硬盘总共有几个磁头,也就是几面盘片,硬盘式由多个盘片组成的,
而每个盘片上都有一个读写磁头复制该盘片的读写操作,磁头数最大为255
柱面数: 表示硬盘每一面盘片上有几条磁道,最大为1023 10个二进制位。
扇区: 表示每一条 磁道/柱面 上有几个扇区,最大为63 6个二进制位。每个扇区一般为 512 字节
CHS寻址方式 中, 磁头 柱面 扇区 的取值范围 为 0~255 , 0~1023 , 1~63
BIOS int 13H 是BIOS 提供的磁盘基本输入输出中断调用,它可以完成磁盘的复位,读写,校验,定位,诊断,格式化等功能。
使用CHS寻址方式, 因此最大识别访问 8GB左右的硬盘。
现代大容量硬盘一般采用 LBA 线性地址方式寻址,替代CHS寻址。
MBR
处理器加电/复位后,如果硬盘式首选的启动设备,
那么ROM-BIOS 将试图读取硬盘的0面0道1扇区。这就是主引导扇区
读取的主引导扇区数据有512字节,ROM-BIOS将它加载到逻辑地址0x0000:0x7c00处
也就是物理地址 0x07c00 处,然后判断它是否有效
有效的主引导扇区,最后两字节为 0x55 + 0xAA ROM-BIOS程序先检测这两个标志,
如果主引导扇区有效,则以一个段间转移指令 jmp 0x0000:0x07c00 调到哪里继续执行
学习:
主要分为5部分: 1引导程序 446字节 (包含WINDOWS磁盘签名 保留位) 2分区表 3结束标志
512字节
1引导程序 占 440字节 0x1b8
WINDOWS磁盘签名 后面4字节为WINDOWS磁盘签名 它是WINDOWS系统在初始化时写入的,WINDOWS依靠 磁盘签名来识别磁盘 如果丢失则WINDOWS认为该磁盘没有被初始化
保留位紧接着是两个字节保留字节 暂时没有被MBR使用的位置
2分区表
在保留的两个字节后64字节 0x40 则保存分区表(DPT disk partition table) 用来管理磁盘分区的 如果丢失 磁盘分区就会丢失 每16字节描述一个分区项的数据
由于字节数的限制,一个磁盘最多可以4个主硬盘分区, 硬盘中的磁盘可以分为主磁盘分区+扩展分区
3 结束标志 55AA表示
以此类推 可以判断有几个硬盘································
- 调试之前先要了解windows系统启动过程
- 1、开机
- 2、BIOS加点自检(Power On Self Test,即POST),此时电源稳定后,CPU从内存地址0fff:0000处开始执行
- 3、将硬盘第一个扇区(0磁头0柱面1扇区)读取内存地址0000:7c00处
- 4、检测(WORD)0000:7dfe是否等于0xaa55,若不等于则转去尝试其他启动介质,如果没有其他启动介质则显示"No ROM BASIC"
- 5、跳转到0000:7c00处执行MBR中的程序
- 6、MBR首先将自己复制到0000:0600处,然后继续执行
- 7、在主分区表中搜索标志为活动的<span style="white-space:pre"> </span>分区。如果发现没有活动分区或有不止一个活动分区,则显示“Invalid partiton table”
- 8、将活动分区的第一个扇区读入内存地址0000:7c00处
- 9、检测(WORD)000:7dfe是否等于0xaa55,若不等于则显示"Miss Operating System",然后停止,或尝试软盘启动
- 10、跳转到0000:7c00处继续执行DBR
- 11、启动系统
- 以上步骤中2,3,4,5步由BIOS的引导程序完成,6、7、8、9、10步由MBR中的引导程序完成。
- 知道了过程,调试就简单多了,所以过程是分析一个很关键的步骤。
- ·
- 关于MBR的调试看willJ大大的文章吧~
调试MBR
这里用IDA 分析:
[cpp] view plain copy print?- IDA调试MBR比较简单,先配置下虚拟机的VMX文件,添加一下代码:
- debugStub.listen.guest32 = "TRUE"
- debugStub.hideBreakpoints = "TRUE"
- bios.bootDelay = "3000"
打开IDA--Debugger--Attach--Remote GDB debugger
在MBR载入内存的地方下断,也就是断在0x7c00
这个时候最好Alt+s下,选择16位的模式,因为这个时候还未进入32位模式!!!!要不然分析有错误
学习转载于 http://www.52pojie.cn/thread-173889-1-1.html
下面为几个MBR钟的代码片段:
学习转载于 http://www.52pojie.cn/thread-215498-1-1.html
访问显存,也需要使用逻辑地址 : 段地址:偏移地址
访问内U承诺使用DS,也可以使用ES
不能直接写 mov es,0xb800
要写成 mov es,ax
ASCII码: 0 - 9 A - Z a - z
0x30 - 0x39 0x41 0x5A 0x61 - 0x7A
字符显示属性:
0x7c 表示 无高亮 背景色 黑 前景色白
CLD REP MOVSB 解释:
[cpp] view plain copy print?- ;example:把当前数据段中偏移1000H开始
- ;的100个字节数据传送到偏移2000H开始的
- ;单元中
- cld ;指针增值
- push DS ;当前数据段,因此压入栈中保存
- pop ES ;使ES=DS
- mov SI,1000H ;源串指针初值
- mov DI,2000H ;目的串指针初值
- mov CX,100 ;循环次数
- Next:
- lodsb ;取一个字节 把SI指向的存储单元读入累加器
- stosb ;存一个字节 可以将累加器AL中的值传递到当前DI地址处
- loop Next ;循环CX次
- ;以下程序片段与上面的等价:
- cld ;地址指针增值
- ……
- mov CX,100 ;循环CX次
- Next:
- movsb ;每次传送一字节数据
- loop Next
- ;或者用更简单的写法:
- cld
- ……
- mov CX,100
- rep movsb
中断学习:
所有的严重事件都必须无条件地加以处理,这种类型的中断是不会被阻断和屏蔽的,称为非屏蔽中断(Non Maskable Interrupt,NMI)。
Intel处理器允许256个中断,中断号的范围是0~255,8259负责提供其中的15个,但中断号并不固定。之所以不固定,是因为当初设计的时候,允许软件根据自己的需要灵活设置中断号,以防止发生冲突。该中断控制器芯片有自己的端口号,可以像访问其他外部设备一样用in和out指令来改变它的状态,包括各引脚的中断号。正是因为这样,它又叫可编程中断控制器(Programmable Interrupt Controller,PIC)。
图`
内部中断
div / idiv 除数为0 或者除法溢出 产生中断0
当处理器遇到非法指令时,将产生 中断6
软中断
int 3 //断点中断指令 机器指令为CC 当处理器执行到int 3 即发生3号中断,专区执行相应的中断处理程序
int imm8
into
中断处理程序执行也要用到各个寄存器,会破坏它们的内容,但PUSH 指令不会,我们可以在该程序内先压栈 所有相关寄存器+内存单元
然后分别取出予以显示,它们就是中断前的现场内同,最后再恢复那条指令的第1 字节
int3 和 int 3 不一样的,前者为CC 后者为CD 03 这就是通常所说的 int n 操作吗为 0cCD
int 0x00 //引发0号中断
int 0x15 //引发0x15号中断
int 0x16 //引发0x16号中断 键盘服务
into 是溢出中断指令,机器码wie 0xCE 也是单字节指令。
最有名的的软中断 为 BIOS 中断。 在计算机加电后,BIOS程序 执行期间建立起来的,这些中断功能在加载+执行主引导扇区之前就已经可以使用了mo
mov ah,0x00 //从键盘读字符
int 0x16 //键盘服务,返回时,字符代码在寄存器AL中
执行后,中断服务例程会监视键盘动作,当它返回时,会在寄存器AL中存放按键的ASCII码
AH | 功能 | 调用参数 | 返回参数 |
00 | 程序终止(同INT 20H) | CS=程序段前缀 | |
01 | 键盘输入并回显 | AL=输入字符 | |
02 | 显示输出 | DL=输出字符 | |
03 | 异步通迅输入 | AL=输入数据 | |
04 | 异步通迅输出 | DL=输出数据 | |
05 | 打印机输出 | DL=输出字符 | |
06 | 直接控制台I/O |
DL=FF(输入) DL=字符(输出) |
AL=输入字符 |
07 | 键盘输入(无回显) | AL=输入字符 | |
08 |
键盘输入(无回显) 检测Ctrl-Break |
AL=输入字符 | |
09 | 显示字符串 |
DS:DX=串地址 "$"结束字符串 |
|
0A | 键盘输入到缓冲区 |
DS:DX=缓冲区首地址 (DS:DX)=缓冲区最大字符数 |
(DS:DX+1)=实际输入的字符数 |
0B | 检验键盘状态 |
AL=00 有输入 AL=FF 无输入 |
|
0C |
清除输入缓冲区并 请求指定的输入功能 |
AL=输入功能号 (1,6,7,8,A) |
|
0D | 磁盘复位 | 清除文件缓冲区 | |
0E | 指定当前缺省的磁盘驱动器 | DL=驱动器号 0=A,1=B,... | AL=驱动器数 |
0F | 打开文件 | DS:DX=FCB首地址 |
AL=00 文件找到 AL=FF 文件未找到 |
10 | 关闭文件 | DS:DX=FCB首地址 |
AL=00 目录修改成功 AL=FF 目录中未找到文件 |
11 | 查找第一个目录项 | DS:DX=FCB首地址 |
AL=00 找到 AL=FF 未找到 |
12 | 查找下一个目录项 |
DS:DX=FCB首地址 (文件中带有*或?) |
AL=00 找到 AL=FF 未找到 |
13 | 删除文件 | DS:DX=FCB首地址 |
AL=00 删除成功 AL=FF 未找到 |
14 |
顺序读 |
DS:DX=FCB首地址 |
AL=00 读成功 =01 文件结束,记录中无数据 =02 DTA空间不够 =03 文件结束,记录不完整 |
15 | 顺序写 | DS:DX=FCB首地址 |
AL=00 写成功 =01 盘满 =02 DTA空间不够 |
16 | 建文件 | DS:DX=FCB首地址 |
AL=00 建立成功 =FF 无磁盘空间 |
17 | 文件改名 |
DS:DX=FCB首地址 (DS:DX+1)=旧文件名 (DS:DX+17)=新文件名 |
AL=00 成功 AL=FF 未成功 |
19 | 取当前缺省磁盘驱动器 | AL=缺省的驱动器号 0=A,1=B,2=C,... | |
1A | 置DTA地址 | DS:DX=DTA地址 | |
1B |
取缺省驱动器FAT信息 |
AL=每簇的扇区数 DS:BX=FAT标识字节 CX=物理扇区大小 DX=缺省驱动器的簇数 |
|
1C | 取任一驱动器FAT信息 | DL=驱动器号 | 同上 |
21 |
随机读 |
DS:DX=FCB首地址 |
AL=00 读成功 =01 文件结束 =02 缓冲区溢出 =03 缓冲区不满 |
22 | 随机写 | DS:DX=FCB首地址 |
AL=00 写成功 =01 盘满 =02 缓冲区溢出 |
23 | 测定文件大小 | DS:DX=FCB首地址 |
AL=00 成功(文件长度填入FCB) AL=FF 未找到 |
24 | 设置随机记录号 | DS:DX=FCB首地址 | |
25 | 设置中断向量 |
DS:DX=中断向量 AL=中断类型号 |
|
26 | 建立程序段前缀 | DX=新的程序段前缀 | |
27 |
随机分块读 |
DS:DX=FCB首地址 CX=记录数 |
AL=00 读成功 =01 文件结束 =02 缓冲区太小,传输结束 =03 缓冲区不满 |
28 | 随机分块写 |
DS:DX=FCB首地址 CX=记录数 |
AL=00 写成功 =01 盘满 =02 缓冲区溢出 |
29 | 分析文件名 |
ES:DI=FCB首地址 DS:SI=ASCIIZ串 AL=控制分析标志 |
AL=00 标准文件 =01 多义文件 =02 非法盘符 |
2A | 取日期 |
CX=年 DH:DL=月:日(二进制) |
|
2B | 设置日期 | CX:DH:DL=年:月:日 |
AL=00 成功 =FF 无效 |
2C | 取时间 |
CH:CL=时:分 DH:DL=秒:1/100秒 |
|
2D | 设置时间 |
CH:CL=时:分 DH:DL=秒:1/100秒 |
AL=00 成功 =FF 无效 |
2E | 置磁盘自动读写标志 |
AL=00 关闭标志 AL=01 打开标志 |
|
2F | 取磁盘缓冲区的首址 | ES:BX=缓冲区首址 | |
30 | 取DOS版本号 | AH=发行号,AL=版本 | |
31 | 结束并驻留 |
AL=返回码 DX=驻留区大小 |
|
33 |
Ctrl-Break检测 |
AL=00 取状态 =01 置状态(DL) DL=00 关闭检测 =01 打开检测 |
DL=00 关闭Ctrl-Break检测 =01 打开Ctrl-Break检测 |
35 | 取中断向量 | AL=中断类型 | ES:BX=中断向量 |
36 |
取空闲磁盘空间 |
DL=驱动器号 0=缺省,1=A,2=B,... |
成功:AX=每簇扇区数 BX=有效簇数 CX=每扇区字节数 DX=总簇数 失败:AX=FFFF |
38 | 置/取国家信息 | DS:DX=信息区首地址 |
BX=国家码(国际电话前缀码) AX=错误码 |
39 | 建立子目录(MKDIR) | DS:DX=ASCIIZ串地址 | AX=错误码 |
3A | 删除子目录(RMDIR) | DS:DX=ASCIIZ串地址 | AX=错误码 |
3B | 改变当前目录(CHDIR) | DS:DX=ASCIIZ串地址 | AX=错误码 |
3C | 建立文件 |
DS:DX=ASCIIZ串地址 CX=文件属性 |
成功:AX=文件代号 错误:AX=错误码 |
3D |
打开文件 |
DS:DX=ASCIIZ串地址 AL=0 读 =1 写 =3 读/写 |
成功:AX=文件代号 错误:AX=错误码 |
3E | 关闭文件 | BX=文件代号 | 失败:AX=错误码 |
3F |
读文件或设备 |
DS:DX=数据缓冲区地址 BX=文件代号 CX=读取的字节数 |
读成功: AX=实际读入的字节数 AX=0 已到文件尾 读出错:AX=错误码 |
40 | 写文件或设备 |
DS:DX=数据缓冲区地址 BX=文件代号 CX=写入的字节数 |
写成功: AX=实际写入的字节数 写出错:AX=错误码 |
41 | 删除文件 | DS:DX=ASCIIZ串地址 |
成功:AX=00 出错:AX=错误码(2,5) |
42 |
移动文件指针 |
BX=文件代号 CX:DX=位移量 AL=移动方式(0:从文件头绝对位移,1:从当前位置相对移动,2:从文件尾绝对位移) |
成功:DX:AX=新文件指针位置 出错:AX=错误码 声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
copyright © 2008-2019 亿联网络 版权所有 备案号:粤ICP备14031511号-2
|