--==< An Introduction to Encryption, Part III >==--

                    Is an impenetrable encryption possible?.

                          By MidNyte, February 2000



   A short (and over-simplified) history of the virus
-----------------------------------------------------

   First of all came the un-encrypted virus.  Then came virus scanners,  which 
were basically just hex searchers looking  for  strings  of  hex only found in 
certain viruses. Viruses retaliated by coming up with encryption.  Most of the 
virus is encrypted,  and  a  small decryption engine at the start of the virus 
decrypts the virus body.   As  the  encryption changes each time,   the  virus 
scanner is limited to searching for a  much smaller section of code inside the 
constant decryptor.  This wasn't much of a  problem for virus scanners though. 
Viruses fought back again with polymorphism,  this is essentially a way that a 
virus can change it's decryptor every time it infects a new file.  That way no 
constant strings appear in the virus.  Virus scanners came up with two ways to 
combat this, heuristics and emulation.  Heuristics is  simply looking for code 
that looks 'virus-like' This can be something as simple as the string '*.exe'. 
Emulation is the controlled running  of the program instruction by instruction 
(not quite, but close enough for this article). A virus, under emulation, will 
be allowed to run just enough  to  decrypt itself  and  reveal  it's  code for 
either a straightforward scan or a generic (heuristic) scan. Anti-emulation is 
the viruses way of defeating this, it is a basically a way to detect emulation 
in progress and act accordingly.  Some anti-emulation systems are incorporated 
into the decryptor of a virus,  so that if the virus is being emulated it will 
not decrypt properly and hence not reveal it's code. Another defence the virus 
can use is anti-debugging, which is designed to hinder people who try to debug 
(in this case unencrypt) your code.  This  is  different  in  that it  doesn't 
defend the virus from antivirus programs,  it  defends  it  from the antivirus 
companies,  the people who will try and study the virus  and work out a way to 
detect it.  Anti-debugging can be very simple, like  turning  off the keyboard 
interrupts at the start of the code  and back on again at the end or it can be 
quite complicated, with the actual anti-debugging routine also being used as a 
key to decryption to protect against patching.  This  is  the  focus  of  this 
article.



   Anti-debugging: more detail
------------------------------

   Anti-debugging  tricks  are  basically little pieces  of  code that have no 
overall effect on the running of  a  virus when being run as normal,  but that 
cause the virus  to  malfunction,  crash  or  worse when they are run under  a 
debugging environment.  The simple example above was  to  turn of the keyboard 
interrupt at the start of the code,  and turn it on again  at  the  end of the 
virus before control  is  passed back  to  the host program.  This  is  simply 
achieved with:


   in  al, 020h	; \
   or  al, 002h	;  }Disable Keyboard interrupt
   out 020h, al	; /
    
   ...at the start, and:

   in  al, 020h	; \
   and al, 0FDh	;  }Enable keyboard interrupt (FDh = NOT 2)
   out 020h, al	; /

   ...at the end. When the virus is run under normal conditions,  the keyboard 
is only off for a very small time,  too  small  for  people to notice.  If the 
program is running under a debugger, as soon as the first few instructions are 
run the keyboard will no longer work,  leaving the person at the debugger with 
no choice but to reset (at least  it  used  to  be in the good old days :) The 
simple work around for the person debugging was too simply patch over the code 
that turned off the keyboard with NOPs or other do-nothing instructions.   Now 
the virus  would  work  as  normal under  a  debugger,  without  disabling the 
keyboard. To retaliate from this, the virus started to use it's anti-debugging 
routine as a key for decryption.  The hex string  to  turn off the keyboard is 
'E4 20 0C 02 E6 20'.  If this  was  one  of  the decryption keys,  the  person 
debugging could  not  just replace  the  instructions with NOPs  as this would 
change  the  key  to  '90 90 90 90 90 90'  and  cause  the  virus  to  decrypt 
incorrectly.  This seems like an ideal solution,  but unfortunately it is not. 
The whole point of this article  is  to  point  out  the  following fact:  Any 
decryption  routine   can  have  it's  basic functionality copied  by  someone 
determined  to  debug  it.    This  means  that  your  routine  that  uses  an 
antidebugging routine  and  also  uses  that  routine  as  a  key  for further 
decryption could be useless. Let's go through it with an example. The original 
virus looks like this:


start:
   in  al, 020h ; \
   or  al, 002h	;  }Disable Keyboard interrupt
   out 020h, al	; /

   xor si,si

   lea bx, start_of_encrypted
   lea cx, end_of_encrypted
   sub cx, bx
   shr cx, 001h

decrypt:
   mov ax, word ptr [start+si]
   xor [bx],ax
   inc si
   cmp si, offset decrypt
   jne next_key_word
   xor si,si

next_key_word:
   loop decrypt

   The pointer  to  the relevant word of the decryption key is kept in si, and 
means that the key is all the code from 'start:' to 'decrypt:'. This works out 
as 'E4 20 0C 02 E6 20 33 F6 BB 19 01 B9 36 01 2B CB D1 E9'.  If  the  keyboard 
part was nopped out the key would change  to '90 90 90 90 90 90 33 F6 BB 19 01 
B9 36 01 2B CB D1 E9',  as  we've already seen.  What  the  person  doing  the 
debugging could do though, is simply take  the  encrypted portion of the virus 
and put it into his own program,  only  this  time the  key would be stored as 
data, not as an executable part of the program, like this:



start:
   xor si,si

   lea bx, start_of_encrypted
   lea cx, end_of_encrypted
   sub cx, bx
   shr cx, 001h

decrypt:
   mov ax, word ptr [key+si]
   xor [bx],ax
   inc si
   cmp si, offset key_end
   jne next_key_word
   xor si,si

next_key_word:
   loop decrypt

key:
   db 'E4 20 0C 02 E6 20 33 F6 BB 19 01 B9 36 01 2B CB D1 E9'

key_end:

   As you can see, the above will decrypt the encrypted section in exactly the 
same manner, only because the key is stored as data we can change  the code as 
much as we like. 


   
   Is an impenetrable encryption possible?
------------------------------------------

   So then, is it possible to include enough current techniques, or to come up 
with a  new technique  to  completely  eliminate  the  chance of the antivirus 
programmers being able to decode it?  Many people think that they have found a 
way to  ensure that their program  is  completely impenetrable  to  decryption 
unless it is running at the time.   This  is,  unfortunately,  unachievable in 
theory.   Because  of  the above demonstrated technique,   any  anti-debugging 
technique can  be  overcome by someone with enough time to debug  a program by 
hand. This means that *any* anti-debug  code  you  put into a virus can be got 
around eventually because the  person  debugging can always read what is going 
on in a hex editor and make a new routine  to  simulate it,  hence the routine 
you write will not always be used to decrypt the code.  They will only see one 
layer of decryption at  a  time,  however,  and this  is  the key to making in 
impenetrable encryption.




   Conclusion
-------------

   In the end then,  we can never make  it  *impossible* for  a  researcher to 
decrypt   a   virus  through  programming  tricks,  however  we  can  make  it 
*impractical* through the use of scale,  ie,  we can  use  so  many layers and 
different tricks that it is impractical to debug. If it takes  a  week  for  a 
programmer to decrypt a virus with hundreds of layers of encryption,  they may 
be able to justify it. If they have ten viruses of this kind it gets harder to 
justify, and with a hundred of them  it  starts to get impractical.  The  ball 
would be back in their court.




   Contact
----------

   Comments/questions/suggestions/bug reports/etc. are welcomed as always,  as 
long as it is kept reasonable.
                                                                     - MidNyte



  As always, I welcome ANY feedback, good or bad, as long as it is reasonable.

|  midnyte01@excite.com | www.coderz.org/midnyte | www.shadowvx.com/midnyte  |