--==< 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.

|  [email protected] | www.coderz.org/midnyte | www.shadowvx.com/midnyte  |