反汇编Bios中断例程的方法求教
反汇编Bios中断例程的方法求教思路:
1 电脑启动后,会进入实模式,从0000:0000处创建中断向量表;
2 BIOS中断程序被加载到了内存中;
3 CPU跳至0000:7c00处执行引导程序。
因此,我用汇编写好引导程序,加入写软盘功能,将0000:0000~FFFF:FFFF的内存全部写入到软盘,然后利用反汇编工具对其反汇编以得到BIOS中断程序的汇编代码。
行动步骤:
1 用虚拟机(VirtualBox)创建一台电脑;
2 虚拟两个软驱;
3 在linux下利用nasm编译引导程序(boot),生成.bin文件,然后使用linux的dd命令(如dd if=boot.bin of=boot.img)将其虚拟成软盘镜像。
4 继续使用dd命令创建一个空白软盘镜像(dd if=/dev/zero of=blank.img bs=1474560 count=1)。bs的作用是限制大小,1474560=1.44m软盘(不知道对不对)
5 分别将两个镜像装进软驱,从0号软盘启动虚拟电脑。出现问候后按回车执行写软盘程序。
6 将0000:0000~FFFF:FFFF的内存全部写入到1号软盘。
进行到这里,问题来了:
1 内存中的数据有一部分成功写入到了空白软盘,内存F000:0000以后应该有数据的,可是软盘里没有,连0000:FC00的数据都没有写入软盘,应该是我的 写软盘代码 有问题。
2 上述思路和步骤是否存在问题,大神们能否指点一下。
3 读软盘的程序也有问题,本想把软盘内容读到0000:7e00处,可直接将es=0000h,bx=7e00h的话程序会卡死,将es=07e0h,bp=0的话可以读,但是读到的内存位置变成了07e0:000a
3 代码附后,因为是刚刚从MASM转入学习NASM,代码可能不太好读,请大神包涵。
org 07c00h
mov ax,cs ;显示问候
mov es,ax
mov ax,BootMessage
mov bp,ax
mov cx,6
mov dx,0
call showgreen
mov ch,00000000b ;设置光标形状
mov cl,00010000b
mov ah,01h ;中断入口
int 10h
call newline ;换行
r16h:
mov ah,0 ;等待键盘输入
int 16h
mov ah,0eh ;将输入输出至屏幕
mov bx,00001010b
mov cx,1
int 10h
cmp al,0dh ;回车键结束输入
je COPY
jne r16h
COPY: ;写软盘程序,第一段写一个柱面
push es
mov si,0 ;计数器
mov ax,0h
mov es,ax ;内存基地址
mov bx,0h ;内存偏移地址
mov ah,03h ;int13h 写扇区入口
mov al,18 ;写扇区的数量
mov ch,0 ;柱面 或者说 磁道
mov cl,1 ;第一个扇区开始
mov dh,0 ;驱动号 或者说 盘面号
mov dl,1 ;驱动器号 0~7f h 软盘
int 13h
go: push ax ;储存参数,以便开始写第二个柱面
mov ax,es
add ax,240h ;下一个内存基地址
mov es,ax
mov bx,0
pop ax
inc ch ;下一个柱面或者说磁道
inc si ;计数器加1
cmp si,80 ;如果写够了80个磁道,就需要换盘面了
je C_1
int 13h
jmp go
C_1: ;写软盘第二盘面
mov si,0 ;计数器重新清零
push ax
mov ax,es
add ax,240h
mov es,ax ;内存基地址
mov bx,0 ;内存偏移地址
pop ax
mov ch,0 ;柱面 或者说 磁道
mov cl,1 ;第一个扇区开始
mov dh,1 ;驱动号 或者说 盘面号
mov dl,1 ;驱动器号 0~7f h 软盘
int 13h
go1:
push ax ;储存参数
mov ax,es
add ax,240h ;下一个内存基地址
mov es,ax
mov bx,0
pop ax
inc ch ;下一个磁道
inc si ;计数器加1
cmp si,33 ;如果写够了113个磁道,就写了FE400个数据了
;如果直接写114个磁道,es=FE40 + 240 =10080将产生溢出
je C_end
int 13h
jmp go1
C_end:
mov bx,2400h ;继续多写入一个磁道,写够100800 h个数据
inc ch
int 13h
mov al,'o' ;显示一个o,表示程序可以执行到这一步
mov ah,0eh
mov bx,00001010b
mov cx,1
int 10h
pop es
jmp r16h ;跳回等待输入
showgreen: ;以绿色显示指定位置的字符串,需要设置es,bp,cx,dx
mov ax,01301h
mov bx,00001010b
int 10h
ret
loadf: ;读软盘子程序
;读取软盘1至7e00 可软盘内容是复制到了7e0a 前9个位置留空了,为什么?
push es
mov ax,07e0h
mov es,ax
mov bp,0h
mov ah,2 ;int13 入口参数
mov al,2 ;读取两个扇区
mov cx,0001h ;从第一扇区开始
mov dx,0001h ;1号驱动器(0~80为软驱
int 13h
pop es
ret
newline:
mov ah,03h ;获取光标位置
int 10h
inc dh ;设置光标位置,换行
mov dl,0 ;行首
mov ah,02h ;
int 10h
ret
BootMessage: db "Hello!" ; 6byte
Smessage: db "Well come to Buu" ; 16byte
Load: db "Load successfully..."
db 0ah
db "Do you want to continue? " ; System-Load byte
db "Press ENTER"
System: dw 0h,07e1h ; 系统入口地址
times 510-($-$) db 0
dw 0xaa55
这个问题有意思,我感兴趣,我找个时间给你试一下
^_^ 人造人 发表于 2017-6-1 20:59
这个问题有意思,我感兴趣,我找个时间给你试一下
^_^
又麻烦你了哈哈~!
我已经解决了大部分问题了。原代码的COPY~C_end段代码有问题。
1、linux生成的软盘镜像不是18个扇区每道,而是36扇区每道。
2、我原来忽略了第一次写软盘后的ah、al返回值,导致第二次写软盘入口错误。
正确的代码如下:
COPY: ;写入磁盘程序
push es
mov si,0 ;计数器
mov ax,0
mov es,ax ;内存基地址
mov bx,0 ;内存偏移地址
mov ah,03h ;int13h 写扇区入口
mov al,36 ;写扇区的数量 *** 这里必须星标一下 软盘镜像 居然不是18个扇区每道的。。。
mov ch,0 ;柱面 或者说 磁道
mov cl,1 ;第一个扇区开始
mov dh,0 ;驱动号 或者说 盘面号
mov dl,0 ;驱动器号 0~7f h 软盘
int 13h
go:
mov ax,es
add ax,480h ;下一个内存基地址
mov es,ax
mov ah,03h
mov al,36
inc ch ;下一个磁道
inc si ;计数器加1
cmp si,56 ;如果写够了56个磁道,就需要换盘面了 ,但这里不需要换面,镜像也好像没有第二面
je C_end
int 13h
jmp go
C_end:
mov bx,4800h ;因为此时es=fc00,不能再加480h了,加了=10080h 会溢出 所以直接修改偏移地址
inc ch
mov ah,03h
mov al,18 ;暂定写18个扇区 此时已经超过1m数据了
int 13h
mov al,'o'
mov ah,0eh
mov bx,00001010b
mov cx,1
int 10h
pop es
jmp r16h 自己解答一下,附虚拟机的1M内存数据,里边包含了中断向量表以及应该包含了BIOS中断例程,如果有兴趣的朋友了自己反汇编看看。我如果弄懂了也会把每个中断的学习情况慢慢发上来。 人造人 发表于 2017-6-1 20:59
这个问题有意思,我感兴趣,我找个时间给你试一下
^_^
有没有好用的反汇编工具? 能够输入地址如 f000:efee 直接定位到该地址的? 我现在在用W32dsm 好像不是很方便,因为他的地址是1.ffff 这样的 不是基地址加偏移 ,而是一个10进制数 加后边一个16进制地址 bin2yx 发表于 2017-6-2 21:22
有没有好用的反汇编工具? 能够输入地址如 f000:efee 直接定位到该地址的? 我现在在用W32dsm 好像不是很 ...
ndisasm
这是nasm 文件夹下的一个小工具
http://www.nasm.us/
人造人 发表于 2017-6-3 18:26
谢谢你的文件,我自己也能弄出来了。
还有个问题,我写的将内存0000:0000~FFFF:FFFF全部拷入软盘的代码还是有问题,虽然能拷贝大部分内存,但是每完成拷贝两个或者三个磁道后就会出一次错误,int13h的 ah返回值是 09H — DMA超过64K界限,出错以后的下几次循环又能成功,这就导致了小部分内存没有拷入软盘。我目前正在试着解决,可是很难。 bin2yx 发表于 2017-6-4 22:23
谢谢你的文件,我自己也能弄出来了。
还有个问题,我写的将内存0000:0000~FFFF:FFFF全部拷入软盘的代码 ...
我正在从另一个角度解决这个问题,你的程序中是使用BIOS中断写软盘,BIOS中断的程序也在0000:0000~FFFF:FFFF
会不会是拿它本身拷贝它,出了问题?
因为我并不清楚BIOS中断是如何写的软盘,如果要用它来复制它本身,是否可以?
页:
[1]