     Uruguay family -- highly polymorphic research viruses.
     ======================================================
                                  
                                  
     Igor G. Muttik
     
     Low Temperature Physics Laboratory,
     Physics Department,
     Moscow State University, 117234, Russia
     
     Phones: +7 095 3396238
                    9391147
     Email: MIG@lt.phys.msu.su
     
     
     KEYWORDS
     --------
     Virus, IBM PC, polymorphic, resident.
     
     
     ABSTRACT
     --------
     Extremely polymorphic  viruses, representing "Uruguay"
series, are  discussed. At  present ten  virus versions are
known. They  are research  viruses and can only be found in
the collections  of virus  hunters. All Uruguay viruses are
resident fast  infectors. The  properties  being  discussed
are:  infection  conditions,  stealth  capabilities,  warm-
reboot feature  and the polymorphic engine properties. Much
interest has  arisen in  this virus  family  due  to  their
strong polymorphic  properties. The comparison of the virus
versions within  this family  presents a unique opportunity
to analyze the evolution of the polymorphic engine.
     
     
     PREFACE
     -------
     This  series   of  research  viruses  was  created  in
Montevideo (Uruguay)  in 1992-1994. The first appearance of
the Uruguay  virus was  in  March   1992.  At  present  ten
versions are available. The first being the most simple and
the last  ones are one of the most polymorphic viruses ever
created [1].  At present,  none of  these viruses have ever
been found  in the  wild. However,  Uruguay-#3 is available
from some  virus exchange BBS in the Western United States.
Fortunately it  still has  not been detected in the wild. A
report out  of Finland  states  that  Uruguay-#7  may  have
gotten out of one of the labs. So far this is unconfirmed.
     
     Uruguay virus  versions #7-#10  are  greater  than  6K
bytes making them one of the largest PC viruses.
     
     All Uruguay  viruses are  harmless. They  do not carry
any direct destructive payload.
     
     Uruguay-#1 was  a simple  resident fast  infector with
little polymorphicity. The main difference between Uruguay-
#2 and its precursor was the usage of trace capabilities of
the processor to determine the original entry points to DOS
interrupt (21h)  and to  the BIOS  disk  service  interrupt
(13h). Most  later virus  versions  (#2-#9)  use  the  same
technique.  Uruguay-#3  was  the  first  to  intercept  DOS
interrupt 21h  rewriting  the  start  of  the  DOS  service
routine with FAR JMP to viral code. Most later versions use
this technique  too, except Uruguay-#10, which does not use
tunneling at  all. Major  improvements to  the  polymorphic
engine took  place in  Uruguay-#4,  which  unveiled  nested
encryption (see  later). Uruguay-#5,  #6 and  #7 have  some
stealth  features   and  use  in-memory  encryption.  Later
versions (#5  and up)  are characterized  with the constant
improvement of the polymorphic engines capabilities.
     
     A  very  interesting  story  is  associated  with  the
Uruguay-#9 version. Fridrik Skulason from Iceland and Frans
Veldman from  the Netherlands, both members of the Computer
Antivirus Research  Organization (CARO)  were the  first to
receive the  virus from  the author. Frans Veldman received
the virus  in the  following way.  The virus  author logged
into  the   BBS  system  (at  2400  bps),  downloaded  TBAV
(Thunderbyte Anti-virus)  and sent the Uruguay-#9 file. The
BBS database  shows the  author lives in Montevideo and his
birthday is  03-30-73. Somehow the copy sent to Fridrik was
lost (probably deleted). The Uruguay-#9 virus is considered
to be  non-existent  because  CARO  decided  not  to  allow
Veldman's copy  of the  virus  to  be  distributed.  I  had
planned on  getting a  copy of Uruguay-#9 for analysis from
Fridrik, but after the mentioned events this research virus
was temporarily  inaccessible. The fact that the Uruguay-#9
virus is  unavailable even  to the  researchers is a unique
case. This  emphasizes the  strict policies  that CARO  has
about the distribution of viruses.
     
     The last  version -  Uruguay-#10 is fresh, it appeared
in May  1994. In  this version  most efforts  of the author
focused on the polymorphism.
     
     Comparison of the whole family (date of creation, code
size,  memory   requirement,  growth   of  infected   file,
condition of  infection, armoring technique, etc.) is given
in Fig.1.
     
     
     LIFE CYCLE
     ----------
     The life  cycle of  all the  viruses  of  the  Uruguay
family is  almost  identical.  When  an  infected  file  is
executed the  virus receives  control and  starts the virus
decryptor. This  decryptor is a creation of the polymorphic
engine of  the virus. It should decode the virus body using
a program,  organized as a loop. At first glance it is hard
to  understand  the  algorithm  because  the  decryptor  is
partially filled  with do-nothing  commands. Moreover, this
decryptor uses different methods to load the initial values
into the loop counter and into the pointer of the decrypted
position. The  decryptor converts  the virus body to an un-
encrypted state and starts the virus itself.
     
     First, the  virus peeks  into the  BIOS timer  byte at
[0:46Ch]. If  that byte  is zero it will show the copyright
string. It  then restores the start of the infected file (3
bytes for versions #1-#5,  99 bytes for versions #6-#9  and
200 bytes for last #10). The virus  checks to  see if it is
already  resident  in  memory.  All  versions  use the same
method  to  check  for  residency.  They call DOS interrupt
(21h) with registers AX=3032h, DX=1234h  and a  response of
AX=5678h means that the virus  is active.  If the  virus is
already  active,  control is simply transferred to the host
file.  If  the file was of type EXE, the virus performs all
needed relocations, shifts the  image of  the host  file to
a  lower  address (because  the  EXE  header  is  no longer
needed)  and  then transfers control to the host program.
     
     When not  active in  memory the virus scans the memory
control block  (MCB) chain, shrinks the last MCB (marked as
'Z') and  copies its  body  to  the  very  top  address  of
conventional memory (see memory size in Fig.1). Most memory
control block  checkers (MEM,  TDMEM, CHKDSK) do not report
that memory  available for  DOS is  less than  640K. If the
computer has  640K of  conventional memory,  you can easily
calculate exact  value of  virus  code  segment  using  the
MEMORY_SIZE data  from Fig.1  For example -- Uruguay-#7 has
MEMORY_SIZE=252h paragraphs and CS=0A000h-252h=9CF8h (Note:
you will  have 9CF7h  if  UMB  is  used,  because  the  top
paragraph will be 09FFFh, not 0A000h).
     
     Finally,  the  virus  intercepts  the  BIOS  disk  I/O
interrupt (13h) and DOS services interrupt (21h). The virus
finds the  original entry points for these interrupts using
the processor  tracing regime  (only versions #1 and #10 do
not use  tracing). At  this point  the virus  takes control
(DOS functions  to execute,  open  and  create  files)  and
infects the  executable files.  Virus versions supporting a
warm reboot  (#5-#8)  will  also  hook  into  the  keyboard
interrupt 09h  (to intercept  [Ctrl]+[Alt]+[Del]  request).
Then the virus transfers control to the host program in the
same way as mentioned above.
     
     
     STRUCTURE AND PROPERTIES
     ------------------------
     All the  viruses have  virtually  the  same  copyright
string inside.  All internal  copyright  strings  from  the
virus bodies  are presented  in Fig.2.  These messages  are
stored in  encrypted form  (XORed). Therefore  they are not
visible even after decryption of the virus body. Obviously,
dumping of the memory copy of the virus will not show these
strings too.
     
     The virus  copyright  message  is  displayed  when  an
infected file  is executed (probability is equal to 1/256).
The versions  #1-#4 use DOS service INT_21h/AH=2, while #5-
#10 use  BIOS INT_10h/AH=0Eh. Printout is delayed, it takes
a few seconds. It is accompanied by "random" musical tones,
which are  calculated from  the ASCII  codes of the printed
characters (therefore,  these tones are not really random).
The copyright  string is  always printed during warm reboot
in versions  #6-#8. Versions #7 and #8 also have a separate
message --  "Uruguay-#7 installed (seg=9CF8)" and "Uruguay-
#8 installed  (seg=9CDF)". This message is always displayed
when the  virus goes  resident (screen  output is performed
through call  of INT_10h/AH=0Eh). The number in the message
represents a  real segment,  where the  virus is located in
memory. The  virus code  has a  special procedure to update
this hexadecimal number. The virus layout is shown in Fig.3
(Uruguay-#7  was   selected  as  a  typical  example).  The
polymorphic engine  (including its tables and random number
generator) accounts for almost one half of the virus size.
     
     The  versions   #5-#8  have  three  different  tracing
routines (interrupt  01 handlers).  The first  detects  the
original entry  points into the system interrupts 13h (disk
I/O) and 21h (DOS services). The second traces and restores
the original  entry points  of the  BIOS interrupts  (8, 9,
10h, 13h,  15h, 16h, 17h, 1Ah, 1Ch) before warm reboot. The
third traces  interrupt 19h  individually to  find its BIOS
entry point.  This entry point is called at the very end of
processing the  warm-reboot request.  Figure 3  shows  that
these tracing routines occupy nearly 10% of the virus code.
Versions #2-#8  use INT_2Fh/AX=1203h  to determine  the DOS
code segment location.
     
     Uruguay  viruses   hook  the   following   interrupts:
21h/4Bh, 21h/3Dh,  21h/4Ch, 21h/6Ch (versions #3-#10), 13h,
08h, 09h,  24h and  2Ah (#3-#8, to restore control over DOS
interrupt 21h).  Interrupt 19h  is called  to perform  warm
reboot (versions  #5-#8). Interrupt  handlers (13h, 21h and
the infection  routine) occupy  approximately  20%  of  the
virus code (Fig.3).
     
     Only versions #5-#7 are semi-stealth viruses. They can
be considered  semi-stealth, because  some of  the  stealth
properties are  lacking from  these viruses. They disfigure
the file  size (and  file time  stamp) definition. Only DOS
functions 11h, 12h, 4Eh, 4Fh and 4202h are monitored by the
virus. Any  integrity checker will easily detect changes in
the contents of the infected file (checksum and/or CRC will
obviously change).  The infected files have 100 years added
to the  date of  file creation.  The author  of the Uruguay
series  discontinued   support  of   the  stealth  feature.
Versions #8-#10 lack any of the stealth properties.
     
     The versions  #5-#8 will  survive a warm reboot. After
detection of a warm reboot request ([Ctrl]+[Alt]+[Del]) the
virus performs the following steps: it frees the top memory
addresses (decreasing  word at  [0:413h]), using  the trace
processor mode  it determines the original BIOS entries for
many interrupts  (19h, 8,  9, 10h, 13h, 15h, 16h, 17h, 1Ah,
1Ch), intercepts  only interrupts 8 and 9, switches off the
A20 line  (using function  call 4  of the XMS driver), sets
the initial  videomode (as defined by [0:410h]), prints the
copyright message,  resets  the  interrupt  controller  and
keyboard chip  (8042) and,  finally, issues  interrupt  19h
(reboot). Reliability  of the  warm-reboot feature seems to
be low. I have tested Uruguay-#7 on four different types of
computers   and    it   always    hangs   after    pressing
[Ctrl]+[Alt]+[Del].  Further  testing  revealed,  that  the
virus author  does  not  take  into  account  the  possible
existence of  DOS  in  the  HMA  (the  virus  regarded  all
CS>0F000h and  CS<0FFFFh as  being part  of the  BIOS  code
segment, but  it may  belong to DOS if it was loaded high).
When this  bug was fixed the computer still would not fully
reboot. It  would hang  on execution  of MOUSE.COM  in  the
AUTOEXEC.BAT file.  If MOUSE.COM  was removed  the computer
would boot  to the  DOS  prompt.  The  computer  seemed  to
function normally  until entering into DEBUG where it would
hang. Finally,  I stopped  testing  the  buggy  warm-reboot
subroutine. The  virus author  discontinued support  of the
warm-reboot feature in the versions #9-#10.
     
     The versions  #5 and  higher use  a memory  encryption
mechanism  that   creates   an   obstacle   for   potential
researchers. The  mechanism works in the following way. The
virus has a few rarely called procedures that can be stored
in encrypted form. They will be decoded in memory only when
needed and  encrypted back  when the  work is  done.  These
encrypted subroutines  may be  located all  over the  viral
body. Uruguay-#5 uses 8 such subroutines, while Uruguay-#10
uses 14. By the way, these encrypted procedures include the
whole polymorphic  engine of the virus, all trace handlers,
file name  analyzer, file extension analyzer and some other
subroutines. These  encrypted slices,  if taken  in  total,
occupy at least 50% of the viral code. If just one of these
short  encrypted   subroutines  remains   unencrypted,  the
results of disassembly will be unreliable (the disassembler
will  produce   huge  amount   of  unresolved  references).
Reconstructing the  sources for  these strains was grueling
and time  consuming work.  The number  of  these  encrypted
slices (subroutines)  grows with  the version  number  (see
Fig.1). In-memory  encryption is  the  simplest  method  of
encoding --  the  procedure  adds  a  random  byte  to  all
locations in  the slice.  The decoding  procedure subtracts
the same  value to restore the original code. This variable
byte is stored separately for each memory slice. Its random
value is  taken from  the BIOS  timer byte  at [0:46Ch] for
each instance  of in-memory  encoding (only  #10  uses  the
internal random number generator instead).
     
     
     INFECTION CONDITIONS
     --------------------
     All viruses  of Uruguay  family  infect  COM  and  EXE
files. All  versions cannot  infect files  larger than 64K.
EXE files  (starting with  a "MZ"  or "ZM"  signature)  are
turned into  COM. Infection  occurs during  the execute  or
open function  (versions later than #3 also use open&create
function). Files  that are  too short  or too  long are not
infected (exact limits are given in Fig.1). Uruguay viruses
never infect the COMMAND.COM file (except #2, which carries
a special  routine for  the command  interpreter  infection
which  can   probably  infect   COMMAND.COM).  The   string
"COMMAND.COM" can  be found  in  the  memory  copy  of  any
Uruguay virus.
     
     The versions  #5-#9 do  not infect  any file  starting
with "SC",  "F-" or  any file  having the letter "V" in the
filename. These  checks  probably  mean  "SCAN",  "F-PROT",
"VIRUSCAN", "FINDVIRU", "-V" or other antivirus software. A
check for "AIDSTEST" is also present, but it does not work,
because there  is a bug in the virus code. All these checks
seem to  be very  odd, because  all  present-day  antivirus
programs are far beyond the 64k limit.
     
     All versions,  except #1 and #2, append the virus body
to the  end of  the victim  file. Versions #1 and #2 insert
the viral  code in  a random  place unless  the size of the
victim file  is too small then an appending method is used.
The reason  for this  behavior is  obvious. When the victim
file is shorter than the virus, it is not possible to place
the virus  inside the file. Consequently, version #1 places
itself inside  the host  file if  its size  is greater than
2380 (94Ch), and #2 -- if greater than 2333 (91Dh) bytes.
     
     The  versions   #1-#4  use   file  size   to  indicate
infection. Files  infected with  version #1  always have  a
size divisible by 19, versions #2-#4 -- are divisible by 23
(numbers are  decimal). The  file will remain uninfected if
it already  has the  appropriate size.  In such  a case the
virus assumes that it is already infected.
     
     The versions  #5-#7 mark  infected files  by modifying
the  time   stamp  (INT_21h/57h).   This  method   is  more
convenient for  use in stealth viruses. Year of creation is
changed to  orig_file_year+100. Condition  of infection  is
file_year<2000.
     
     The versions  #8-#10 mark  infected files by modifying
the seconds  field of the time stamp (INT_21h/57h, CX&&1F).
The  new  seconds  value  is  random  and  machine-specific
(calculated from  the BIOS contents of the computer). Files
having this number in the seconds field are never infected.
Infected file  from  different  computers  (with  different
BIOS) may  be infected  for the second time and such a file
should run correctly.
     
     The files,  infected with version #8 usually have many
0FFh bytes at the end of the infected file (this is part of
videomemory at  address [A000:0]),  because the virus write
operation overlaps  from the virus memory block (located at
the top  of conventional  memory) into  videomemory. If the
write operation  was done  in any  graphic  mode,  infected
files will carry a snapshot of videomemory (partial) at the
very end.
     
     
     POLYMORPHIC ENGINE
     ------------------
     Due to  its large  size and flexibility, investigating
the  principles  and  structure  of  Uruguay's  polymorphic
generator was  very interesting.  The size  of this virus's
polymorphic engine  (>3K bytes  for #8-#10)  is larger than
the size of most known viruses.
     
      There  are many  levels of  polymorphism  [2].  Later
Uruguay viruses belong to the upper level [1]. On the other
hand, the first versions (#1, #2) are not very polymorphic.
They can  easily be  detected using  multiple scan strings.
The one  interesting thing  about the first two versions is
that program which decodes the virus code (virus decryptor)
not only  decodes below  the decryption  loop but  it  also
affects the  loop instruction  itself (Fig.4a,b). All later
versions use  the idea  of decryption  of LOOP  instruction
too. When  looking on  the code  of virus decryptor for the
first time  we have  an impression  that after execution of
some  reasonable   operators,  processor   goes  into  code
garbage. But  mentioned reasonable  operators turn  garbage
into LOOP  instruction and  all goes fine. The exception to
this is  that the  author did  not take  into  account  the
internal processor  queue which  can fetch  undecoded  LOOP
instruction beforehand  and decryption will take place only
in memory.  In other  words, the virus modifies the program
code too close to the current instruction pointer, ignoring
the pre-fetched  instructions in  the processor queue. That
seems to  be the  reason why infected files (in the earlier
versions) often  hang after  invocation (especially  on 286
and later  processors). Some  countermeasures seem  to have
been taken  in the later versions -- the polymorphic engine
adds do-nothing  operators (four in #7, five in #8) between
the last  decryption instruction  and  the  encrypted  LOOP
command.
     
     Discussion of the more complex versions of the Uruguay
family follows.
     
     The polymorphic  generator of  versions #6-#10 use the
same approach  to hide  the entry  point of the viral code.
Typically, when  a virus decide to infect an executable COM
file, it operates in the following way. The virus overwrite
the very  beginning of the victim COM file with a jump into
the viral  code, which  is appended  to the end of the file
(Fig.5a). This  jump usually takes only three bytes (opcode
is E9). The original contents of these three bytes is saved
somewhere in the virus body. Thus, virus itself consists of
two parts  - virus  head (3-byte  jump, located at the very
beginning of  the infected  file) and virus tail (the virus
body at  the very end of the infected file). Therefore, the
simplest case  of the  virus head  is a 3-byte jump. Such a
jump in  the very  beginning  of  an  executable  COM  file
typically alerts  most antivirus  programs. The solution is
simple --  virus may  add some  dummy code  before the jump
(this may  be NOPs  or other  do-nothing commands) and make
the jump  itself slightly variable (use direct jump or jump
via register  contents, or use PUSH/RET command sequence to
simulate  a   jump,  etc.).   Obviously,  this   "jump"  in
conjunction with  all the  do-nothing  code  (I  called  it
"extended virus  head") will  take more space (comparing to
the mentioned  three bytes) and the virus will have to save
more information  from the beginning of file. An example of
extended virus  head is presented in Fig.5b. This specially
constructed (by  the polymorphic  engine) virus head solves
two things  -- it  transfers control  to the virus tail and
fools heuristic  scanners. The  virus tail,  which receives
control from  the virus head, consists of a virus decryptor
(created by  the polymorphic engine) and an encrypted virus
body, both attached to the end of the victim file. The size
of the  virus head  located at  the beginning of the victim
file  is  constant for  Uruguay versions  #6-#9.  The  head
takes 99  (63h) bytes.  For the last version (#10) it takes
200  bytes.  Control  passes  from the head to the tail  in
three  different  ways:  1.JMP  offset;  2.PUSH offset,RET;
3.MOV  reg,offset,   JMP  reg   (I  wrote  here  "MOV"  for
simplicity.   In   reality   it   may   be   any  register-
modification instruction, resulting in the desired contents
of the  used  register,  see  detailed  discussion  later).
Currently there  are  no  antivirus  utilities,  which  can
detect such  tricks even  in heuristics  mode.  Uruguay-#10
improved this  technology --  it uses 12 additional ways to
pass control to the decryptor!
     
     The  polymorphic  engine  of  the  later  versions  of
Uruguay family  performs two  main tasks.  It generates the
virus head  and the  decryptor of  the  virus  body.  After
invocation of the infected program (i.e., immediately after
DOS EXEC call) the virus head gains control and passes that
control to  the virus  tail. These  virus parts are tightly
linked, because  the contents  of the  processor  registers
after execution  of the  virus head  is the contents of the
processor  registers   before  execution   of   the   virus
decryptor. Therefore,  these two  variable sections  of the
virus are  generated by one program - Uruguay's polymorphic
engine.
     
     The  polymorphic   engine  of  later  Uruguay  viruses
functions like  a compiler.  It has  an internal  table  of
registers (AX,  CX, DX,  BP, BX, SI, DI) as well as a table
of their  contents. The  register management  mechanism  is
flexible enough  that if  one processor  register is in use
the compiler  selects  another.  If  the  engine  needs  to
generate  an   instruction  to  loads  some  value  into  a
register, it  fetches the current contents of this register
from the  table  and  performs  the  needed  modifications,
simultaneously mirroring  it  in  the  table  of  contents.
Registers DX  and BP are not used in the decryption routine
of Uruguays  (all versions),  but their  contents are  also
mirrored in the table, because some instructions (register-
modification, such as XCHG AX,BP or ADD SI,DX) affect other
usable (AX, CX, BX, SI, DI) registers.
     
     The polymorphic  engine uses  the initial  contents of
the processor  register as  set by  the DOS  EXEC call. The
virus knows  all these  values  (given  for  COM  files  in
hexadecimal: AX=0000,  BX=0000, CX=00FF,  DI=FFFE,  SI=100)
and places  it in  the table  of register  contents as  the
initial values.  These settings are compatible with MS-DOS,
but they  may not  be 100% compatible with DOS-like shells,
because these  settings are  not documented.  For  example,
Concurrent DOS  6.0 (from  Digital Research)  sets CX=0000,
BP=0000, DI=0000, SI=0000. Therefore, usage of the register
contents after  EXEC calls  may not be reliable, but it can
be regarded  as additional protection against investigation
into the  virus. Why? This technology cancels direct use of
the DEBUG  utility (and other debugging programs), which do
not initialize  registers in  the same manner as MS DOS. To
start the  virus correctly  under DEBUG  you  need  to  set
CX=00FF, DI=FFFE  and SI=0100 after loading of the infected
file, otherwise  the virus decryption routine will not work
properly.
     
     The  polymorphic   engine,  produces  three  types  of
instructions:    do-nothing     instructions,     register-
modification instructions  and do-work  instructions.  When
the polymorphic  engine creates the virus head, the do-work
instructions  are   "JMP",  "PUSH/RET"   or  "MOV/JMP  reg"
commands. Later,  when creating  the decryptor of the virus
body,  the  do-work  instructions  compose  the  decrypting
routine. The  complete listing  of do-nothing  commands  is
given  in  Fig.6  (for  #7,  #8).  The  entire  listing  of
register-modification instructions  is given  in Fig.7 (for
#7, #8).
     
     When  generating  register-modification  instructions,
the polymorphic  engine uses code synonyms (i.e., processor
opcodes, that  are different,  but performs the same task).
For  example,   you  can  use  the  following  opcodes  for
instruction "ADD  AX,word" --  05h and  81h, 0C0h.  It also
works for SUB (2Dh and 81h, 0E8h), XOR (35h and 81h, 0F0h),
OR (0Dh and 81h, 0C8h), AND (25h and 81h, 0E0h), etc.
     
     Do-work instructions perform the following tasks: load
initial value  into the  pointer register (it may be BX, SI
or DI),  load initial  value into  counter (always  CX) and
decrypt the  word at  the location indicated by the pointer
register.  The   order  of   do-work  instructions  in  the
decryption routine is not fixed. The polymorphic engine may
first generate a load counter instruction (always CX), then
set the  pointer (BX,  SI or  DI), but  it can also produce
these instructions in the reversed order.
     
     There are  many variations  to the  encryption method.
For example  #7 and  #8 can  use as  much as  16  different
encryption methods (#1-#6 used only three simple methods --
XOR, SUB  and ADD).  All methods  are presented  in  Fig.8.
Nesting of  up to  five encryption algorithms is allowed in
versions #4-#6  (see Fig.9a,b).  For additional reliability
the virus  tests if  the virus  body is  really  encrypted,
i.e., if  two nested  algorithms do  not cancel each other.
For example, methods 2 and 3 (Fig.8), if sequentially used,
will produce  an unencrypted  virus body.  You should  take
into account  that Uruguays  can use  any usable  processor
register as  a pointer  with equal  probability (BX,  SI or
DI). Moreover,  the  virus  uses  6  different  methods  to
perform the  simple task  of increasing (add 2) the pointer
register.  An  example  is  given  in  Fig.10  (taken  from
version #7).  Uruguay-#8  allow even more complex sequences
in order  to modify pointer registers (like: INC, DEC, ADD-
signed, ADD-word, SUB-signed, SUB-word).
     
     The versions  #3-#10 have  an internal  random  number
generator, which  is extensively  used in  its  polymorphic
engine. It accepts one parameter -- AL and returns BH=0 and
BL greater  than zero  and less  than or  equal to given AL
(i.e., BX=[1;AL]).  The random  number generator  uses  the
computer BIOS  and the  current timer  contents [0:46Ch] to
calculate output  (several XOR,  SUB and ADD instructions).
It uses  static variables  to operate. In all versions (#3-
#8) the random number generator is located in the uppermost
addresses of the viral code.
     
     The difference  between Uruguay-#7 and Uruguay-#8 is a
slightly   enhanced    subroutine,   for   generating   the
instructions to  load a  constant into a given register. In
#8 it  is more  flexible (i.e.,  #8 is  a more  polymorphic
virus). Some  other places  were also  rewritten,  but  the
algorithms were  not changed, so these modifications may be
regarded as cosmetic.
     
     The main  enhancements made  in  Uruguay-#10  are  the
following: the  decryptor is  two-level (and  it  asks  DOS
version between  two decryption  passes to  complicate  the
determination of the moment of decryption termination), the
head uses  12 ways  to pass  control to  the decryptor and,
finally, the  flexibility of  the  polymorphic  engine  was
improved much  (for  example,  it  now  uses  now  multiple
command prefixes and the interrupts 01 and 03 as do-nothing
commands, etc.).
     
     The polymorphic engine of the Uruguay viruses (#5-#10)
can  be  called  "table  driven"  because  of  the  typical
sequence of actions. It usually generates the random number
in the defined limits (for example [1;16]), gets the offset
of the  appropriate subroutine  from  the  table  (example:
table of  encryption subroutines,  Fig.8), and  calls  this
subroutine. Sometimes this sequence is complicated with the
additional (and  table driven  too)  loading  of  a  random
parameter to the called subroutine. Disassembled listing of
Uruguay viruses  has many  tables. Uruguay-#7 has 17 tables
of parameters  and 6  tables of  subroutines (64 entries in
total). Uruguay-#8 has 18 tables of parameters and 9 tables
of subroutines (with 73 entries)!
     
     Some   Uruguay    viruses   (versions    #5-#7)    are
simultaneously polymorphic  and stealth.  By  the  way,  at
present, very  few polymorphic  stealth viruses  are known.
Besides Uruguay #5-#7, only Tremor virus can be regarded to
belong to  this class  [3]. The polymorphic stealth viruses
face a  serious problem.  When they  create the  virus tail
they must guarantee its fixed size in order to simplify the
stealth routine. Typically, a stealth routine subtracts the
virus tail  size (always  the same value in a resident part
of a  virus) from  the real  file size  to make an illusion
that the size remained unchanged. Therefore, the virus tail
should  have  a  constant  size.  That  requirement  is  in
contradiction   with   random   behavior   of   polymorphic
generator. The same problem appears when versions #6-#8 are
creating the  virus head.  Its size  is also  fixed and the
polymorphic engine  should place  its code  exactly in  the
predefined  space (99 or 200 bytes).  Since the polymorphic
engine  uses a  random  approach  and can exceed this fixed
size, the virus will  cancel its creation of the virus head
or tail and attempt it again if the limit is exceeded.
     
     There are  no antivirus  scanners currently  available
which  will  reliably  detect  later  versions  of  Uruguay
viruses.  Reliable  identification  of  highly  polymorphic
viruses  is   a  very  complex  task.  We  should  have  an
algorithmic scanner for each polymorphic virus. Creation of
such a  scanner is  impossible without detailed analysis of
the virus  source code,  otherwise it cannot be regarded as
reliable. If  you can  imagine  a  polymorphic  virus  that
changes its  encryption method once a month, you will begin
to see  that creation  of a  100%-hit scanner  can only  be
possible after extensive research into the virus internals.
     
     I have  tested several  virus scanners  and found that
Scan v.113  detects only  versions #3,  #4, #5,  #6 (pretty
reliably) and calls virus [Uruguvau]. ThunderByte AntiVirus
6.20 reliably detects #1, #2, #3, #4, #5 and #8.
     
     
     CONCLUSION
     ----------
     We see  that the  Uruguay virus  family introduced  an
interesting,  table-driven   polymorphic  engine.   It   is
definitely more  complex and  "more polymorphic"  than  the
well-known "Dark  Avenger's Mutating  Engine" (called  also
MtE). Rare  comparison  of  the  two  families  shows  that
Uruguay (later versions) has far more variations than MtE.
     
     The polymorphicity  of the  later versions  of Uruguay
family is  one of  the highest,  putting it  close  to  the
theoretical limit.  The Uruguay  virus  decryptor  utilizes
almost all  of the processor registers and virtually all of
the processor  opcodes in  conjunction with many encryption
methods.
     
     
     ACKNOWLEDGMENTS
     ---------------
     I have benefited from discussions with Dmitry Gryaznov
and Vesselin Bontchev.
     I wish  to thank  Patricia Noack  (Noack Systems,  CA,
USA), who assisted in the preparation of this document.
     
     
     REFERENCES
     ----------
     1.  V.Bontchev  "Known  Polymorphic  Viruses".  Secure
computing., January 1994, pp.60-64 (The files are available
from    FTP    site    ftp.informatik.uni-hamburg.de,    in
/pub/virus/texts/viruses/plymrphs.zip and poly9403.zip)
     
     2. A.Solomon  "Mechanisms of  Stealth", Proc. 5th Int.
Comp. Virus  and Sec.  Conf., New York, March 1992, pp.232-
238
     
     3. V.Bontchev, private communication, April 1994.
     
     
     FIGURES
     -------



Fig.1. The comparison of Uruguay viruses.

Ŀ
VirusDate Code sizeMEMORY_   Infectable File  HeadStea-Warm  MemoryTunne-
          ,bytes   SIZE, parafile size  growthsizelth  rebootslicesling  
Ĵ
 #1  03/92   938      129    >200,<=F400 ~94F   3   -    -     0     -   
 #2  04/92   8F6      120    >200,<=EC00 ~91E   3   -    -     0     +   
 #3  06/92   996      140    >200,<=F400 <A5E   3   -    -     0     +   
 #4  07/92   A3D      155    >200,<=F400 <B05   3   -    -     0     +   
 #5  08/92   FE5      20A    >200,<=EC00 10AD   3   +    +     8     +   
 #6  11/92  120F      252    >200,<=E000 130F  63h  +    +     8     +   
 #7  02/93  17B0      308    >200,<=E000 18C8  63h  +    +     9     +   
 #8  03/93  1876      321    >200,<=D800 <1C78 63h  -    +    10     +   
 #9  12/93  132A      27F    >200,<=D800 <172C 63h  -    -     7     +   
#10  05/94  1812      35F    >200,<=D000 <2240 63h  -    -    14     -   




Fig.2. Virus copyright messages for versions #1-#8.

Ŀ
 The BEATLEMANIA is alive!                                           
 THE BEATLES, for ever, the best.                                    
 John, Paul, George and Ringo, ladies and gentlemen, here they are!  
 PLEASE, PLEASE ME. WITH THE BEATLES. A HARD DAY'S NIGHT.            
 BEATLES FOR SALE. HELP. RUBBER SOUL. REVOLVER.                      
 SGT.PEEPERS LONELY HEARTS CLUB BAND. THE BEATLES. YELLOW SUBMARINE. 
 ABBEY ROAD. LET IT BE. MAGICAL MISTERY TOUR.                        
 Other LP and singles available...                                   
                                                                     
 Virus 'Uruguay-#1'                                                  
 Programmed in Montevideo (URUGUAY) by F3161. 03/92.                 
 This is a research virus - DO NOT DISTRIBUTE.                       
 Uruguay-#1 Ĵ
                                                                     
 I love ROXETTE !!!                                                  
                                                                     
 Virus 'Uruguay-#2'                                                  
 Programmed in Montevideo (URUGUAY) by F3161. 04/92.                 
 This is a research virus - DO NOT DISTRIBUTE.                       
 Uruguay-#2 Ĵ
                                                                     
 'Uruguay-#3' Virus                                                  
 Programmed in Montevideo (URUGUAY) by F3161. 06/92.                 
 This is a research virus - DO NOT DISTRIBUTE.                       
 Uruguay-#3 Ĵ
                                                                     
 'Uruguay-#4' Virus                                                  
 Programmed in Montevideo (URUGUAY) by F3161. 07/92.                 
 This is a research virus - DO NOT DISTRIBUTE.                       
 Uruguay-#4 Ĵ
                                                                     
 'Uruguay-#5' Virus                                                  
 Programmed in Montevideo (URUGUAY) by F3161. 08/92.                 
 This is a research virus - DO NOT DISTRIBUTE.                       
 Uruguay-#5 Ĵ
                                                                     
 'Uruguay-#6' Virus                                                  
 Programmed in Montevideo (URUGUAY) by F3161. 11/92.                 
 This is a research virus - DO NOT DISTRIBUTE.                       
 Uruguay-#6 Ĵ
                                                                     
 Uruguay-#7 Virus                                                    
 Programmed in Montevideo (URUGUAY). 02/93.                          
 This is a research virus - DO NOT DISTRIBUTE.                       
 Uruguay-#7 Ĵ
                                                                     
 Uruguay-#8 Virus                                                    
 Programmed in Montevideo (URUGUAY). 03/93.                          
 This is a research virus - DO NOT DISTRIBUTE.                       
 Uruguay-#8 Ĵ
                                                                     
 Uruguay-#9 Virus                                                    
 Programmed in Montevideo (URUGUAY). 12/93.                          
 This is a research virus - DO NOT DISTRIBUTE.                       
 Uruguay-#9 Ĵ
                                                                     
 Uruguay-#10 Virus                                                   
 Programmed in Montevideo (URUGUAY). 05/94.                          
 This is a research virus - DO NOT DISTRIBUTE.                       
 Uruguay-#10 





Fig.3. Layout of Uruguay-#7 virus (was selected as a typical example).

Ŀ
                                   Relative  Absolute    Address  
    Virus routines and data          size     size        zone    
                                      (%)    (bytes)      (hex)   
Ĵ
 Data buffer & victim file start       3        176       0....B0 
 Startup code                          8        459      B1...27C 
 Copyright string                      2        115     27D...2F0 
 Tunneling trace routines              9        548     2F1...515 
 Warm reboot routines (Int 8,9)        9        518     516...71B 
 Interrupt (13h,21h) handlers         14        874     71C...A86 
 Infection routines                    6        374     A87...BFD 
 EXE header relocator routine          2        132     BFE...C82 
 Memory decode/encode routines         2        127     C83...D02 
 Polymorphic engine data & tables      5        330     D03...E4D 
 Polymorphic engine code              38       2295     E4E..1745 
 Random number generator               2        106    1746..17AF 
Ĵ
 Total:                              100       6064       17B0    




Fig.4. Simple decryption routine before and after first decryption
       step (process of decoding encrypted viral code starts from
       the LOOP instruction itself). Dots represent the do-nothing
       instructions.
Ŀ
           ...                                  ...                       
 IP >  MOV DI,POINTER                       MOV DI,POINTER            
           ...                                  ...                       
           MOV CX,COUNTER                       MOV CX,COUNTER            
           ...                                  ...                       
 DECRYPT:  XOR word ptr [DI],MASK Ŀ  DECRYPT:  XOR word ptr [DI],MASK Ŀ
           ...                                 ...                      
           ADD DI,2                            ADD DI,2                 
           ...                       IP >  ...                      
 POINTER:  xxxx <  POINTER:  LOOP DECRYPT             
           xxxx                                 xxxx <ٳ
           xxxx                                 xxxx                      
           ...                                  ...                       
                                                                          
 a) simple case (before running)      b) simple case (after running)      




Fig.5. Virus head and tail.

Ŀ
      Ŀ                                         
                                   V                                         
 Ŀ 
  JMP      victim file body       virus decryptor  encrypted virus body  
  
                             
  virus                                                virus                  
  head                                                 tail                   
 (3-bytes)                                                                    
                                                                              
                a) simple 3-byte head (JMP=E9 offset)                         
Ŀ
                Ŀ                                         
                                             V                                         
 Ŀ 
  ...PUSH...RET      victim file body       virus decryptor  encrypted virus body  
  
                             
      virus                                                virus                        
      head                                                 tail                         
   (99-bytes)                                                                           
                                                                                        
  b) extended virus head uses 3 types of control transfer to the virus                  
     tail: 1. JMP offset; 2. MOV reg, offset/JMP reg; 3. PUSH offset/RET.               
     Dots denote do-nothing and register modification commands commands.                



Fig.6. Do-nothing instructions of Uruguay polymorphic engine (#7, #8),
       used in the decryptor of virus body.

Ŀ
  clc            adc   dx,ax        neg   dx       inc   dl             
  cld            adc   dx,bx        neg   bp       inc   dh             
  cmc            adc   dx,cx        neg   dl       dec   dl             
  stc            adc   dx,dx        neg   dh       dec   dh             
  sti            adc   dx,si        not   dl       xor   dh,dh          
  nop            adc   dx,bp        not   dh       xor   dl,dl          
  inc     dx     adc   bp,dx        rcl   dx,1     xchg  bp,dx          
  inc     bp     jmp   short $+2    rcl   bp,1     xchg  dh,dl          
  dec     dx     jc    $+2          rcr   dx,1     xchg  dl,dh          
  dec     bp     jz    $+2          rcr   bp,1     push  bp / pop  dx   
                 jnz   $+2          shl   dl,1     push  dx / pop  bp   
                 jbe   $+2          shl   dh,1                          
                 jl    $+2          shr   dl,1                          
                                    shr   dh,1                          
  a)one-byte                                                            
    commands                   b)two-byte commands                      



Fig.7. Register-modification instructions of Uruguay polymorphic
        engine (#7, #8), used in the decryptor of virus body.

Ŀ
 ADD REG, word         INC REG         MOV REG, REG 
 SUB REG, word         DEC REG         AND REG, REG 
 XOR REG, word         NOT REG         XOR REG, REG 
 MOV REG, word         SHR REG,1       OR REG, REG  
 OR REG, word          SHL REG,1       ADD REG, REG 
 AND REG, word         ROR REG,1       SUB REG, REG 
                       ROL REG,1                    
                                                    
           REG=AX/CX/DX/BP/BX/SI/DI                 



Fig.8. Encryption methods used by Uruguay-#7 and #8.

Ŀ
  #   Method sequence        Comment                       
Ĵ
  1  XOR [word],CONSTANT     CONSTANT is global            
  2  SUB [word],CONSTANT     CONSTANT is global            
  3  ADD [word],CONSTANT     CONSTANT is global            
  4  ROR [word],1                                          
  5  ROL [word],1                                          
  6  NOT [word]                                            
  7  NEG [word]                                            
  8  XOR [word],CX           LOOP counter is used as MASK  
                             (CX is modified by LOOP)      
  9  SUB [word],CX           LOOP counter is used as MASK  
                             (CX is modified by LOOP)      
 10  ADD [word],CX           LOOP counter is used as MASK  
                             (CX is modified by LOOP)      
 11  XOR [word],DI           POINTER is used as mask       
     ADD DI,2                (DI is modified as in Fig.9)  
 12  SUB [word],DI           POINTER is used as mask       
     ADD DI,2                (DI is modified as in Fig.9)  
 13  ADD [word],DI           POINTER is used as mask       
     ADD DI,2                (DI is modified as in Fig.9)  
 14  XOR [word],MASK         MASK is for this method only  
 15  SUB [word],MASK         MASK is for this method only  
 16  ADD [word],MASK         MASK is for this method only  


Fig.9. Nested decryption routine before and after first decryption
       step (process of decoding encrypted viral code starts from
       the LOOP instruction itself). Dots represent the do-nothing
       instructions.

Ŀ
           ...                                    ...                         
 IP >  MOV DI,POINTER                         MOV DI,POINTER              
           ...                                    ...                         
           MOV CX,COUNTER                         MOV CX,COUNTER              
           ...                                    ...                         
 DECRYPT:  XOR word ptr [DI],MASK1 Ŀ  DECRYPT:  XOR word ptr [DI],MASK1 Ŀ 
           ...                                   ...                        
           SUB word ptr [DI],MASK2 Ĵ            SUB word ptr [DI],MASK2 Ĵ 
           ...                                   ...                        
           ADD word ptr [DI],MASK3 Ĵ            ADD word ptr [DI],MASK3 Ĵ 
           ...                                   ...                        
           ADD DI,2                              ADD DI,2                   
           ...                         IP >  ...                        
 POINTER:  xxxx <  POINTER:  LOOP DECRYPT               
           xxxx                                   xxxx < 
           xxxx                                   xxxx                        
           ...                                    ...                         
                                                                              
    a) nested case (before running)         b) nested case (after running)    



Fig.10. Code synonyms used to modify pointer -- DI=DI+2
        (modification of BX and SI is the same). RND
        denotes any random word.

Ŀ
 #     Modification method          Processor opcodes     
   Ĵ
       First        Second        First        Second   
    instruction   instruction  instruction  instruction 
Ĵ
 1  INC DI       INC DI             47           47     
 2  ADD DI,+2                   83,C7,02                
 3  SUB DI,FFFE                81,EF,FE,FF              
 4  SUB DI,-2                   83,EF,FE                
 5  ADD DI,2                   81,C7,02,00              
 6  ADD DI,RND   SUB DI,RND-2  81,C7,xx,yy  81,EF,zz,yy 


                                        
