0% found this document useful (0 votes)
105 views12 pages

Advanced Polymorphic Techniques

The document discusses the evolution of computer virus protection techniques from simple signature-based detection to more advanced polymorphic and metamorphic techniques. It focuses on how early viruses used basic appending and entry point modification to evade detection. The document then examines how polymorphism and metamorphism emerged as antiviruses adapted by scanning decrypted code. It highlights the 2002 MetaPHOR virus as the most advanced metamorphic virus and provides context on the early theoretical study of computer viruses by F. Cohen in the 1980s.

Uploaded by

binaryglitch008
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
105 views12 pages

Advanced Polymorphic Techniques

The document discusses the evolution of computer virus protection techniques from simple signature-based detection to more advanced polymorphic and metamorphic techniques. It focuses on how early viruses used basic appending and entry point modification to evade detection. The document then examines how polymorphism and metamorphism emerged as antiviruses adapted by scanning decrypted code. It highlights the 2002 MetaPHOR virus as the most advanced metamorphic virus and provides context on the early theoretical study of computer viruses by F. Cohen in the 1980s.

Uploaded by

binaryglitch008
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

World Academy of Science, Engineering and Technology

International Journal of Computer and Information Engineering


Vol:1, No:10, 2007

Advanced Polymorphic Techniques


Philippe Beaucamps

Abstract—Nowadays viruses use polymorphic techniques to mu- other viruses. The most commonly used techniques consisted
tate their code on each replication, thus evading detection by an- in appending the viral code at the end of the executable
tiviruses. However detection by emulation can defeat simple poly- file, modifying the entry point to point at the virus and then
morphism: thus metamorphic techniques are used which thoroughly
change the viral code, even after decryption. We briefly detail this letting the virus spread among the system (Fig. 1). Thus, a
evolution of virus protection techniques against detection and then basic protection method is form analysis where each virus
study the M ETA PHOR virus, today’s most advanced metamorphic is identified by a specific signature: such a signature is a
virus. sequence of – not necessarily consecutive – bytes whose
Open Science Index, Computer and Information Engineering Vol:1, No:10, 2007 publications.waset.org/13630/pdf

Keywords—Computer virus, Viral mutation, Polymorphism, Meta- detection inside a program allows to identify as undeniably as
morphism, MetaPHOR, Virus history, Obfuscation, Viral genetic possible infection by the virus. This method has the advantage
techniques. of being non-greedy in its complexity as well as subject to a
tiny rate of false alarms.
I. I NTRODUCTION
HEN the first antiviral protections appeared in the late
W 80’s to answer the nascent viral threat, they consisted
of a mere binary scan of programs looking for known virus
signatures. Never mind, virus writers adapted their code so that
it would mutate its binary form on each replication: as early as
in 1988 a first virus protected itself using encryption, followed
in 1990 by the first polymorphic viruses which were able to
mutate their code as well as their decryption method. Their
ability to evade detection by the then antivirus software gave
them immediate “popularity”. Nevertheless antiviruses quickly
adapted to this protection by letting viruses decrypt themselves
and then only scanning the decrypted code looking for any
known signature. This led, as early as in 1997, to the first
metamorphic viruses which mutate their code in its decrypted Fig. 1 Basic virus infection
form.
This article will therefore study polymorphism and its mis- Back in time, as early as in 1984, F. Cohen had been the
cellaneous techniques and more particularly the most evolved first one to study viruses from a theoretical point of view,
ones, namely metamorphic techniques. In order to do so, we christening them and defining them as programs which are
will study most notably the 2002 M ETA PHOR virus. For more able to infect other programs with a possibly evolved copy of
details, the reader may consult Éric Filiol’s books [5], [6] as themselves. Thus, this definition already suggested the exis-
well as the VX Heavens website, which is crammed with tence of viruses which would alter their form when replicating.
malware resources. And indeed such viruses turned up quite quickly. Cohen also
showed that the problem of virus detection was undecidable,
II. P OLYMORPHISM – E ARLY STAGES
meaning in other words that no algorithm would ever be able
to determine with unquestionable certainty whether a given
This section shortly describes the evolution and techniques program is a virus or not [3].
of viruses from the most basic techniques to simple poly-
morphic techniques and finally to advanced metamorphic
B. Polymorphic Viruses
techniques. The reader may refer to [5], [6], [19], [1] for a
more exhaustive and detailed study. The first virus encrypting its code, C ASCADE, appeared in
1988. Yet its decryption method remained unchanged from one
replication to another and thus it was not really a polymorphic
A. First Viruses
virus per se. In 1990 however, the first family of polymorphic
The first virus outbreak broke out in 1981 with the E LK viruses appeared: the C HAMELEON viruses (or V2P) which
C LONER virus, followed by B RAIN in 1986, the first virus were developped by Mark Washburn, were based on the
to implement stealth techniques, and from then by numerous C ASCADE and V IENNA viruses and mutated the code of their
Philippe Beaucamps is with the Loria, Vandoeuvre-lès-Nancy, France,
decryption method (fig. 2). The shock they created shaked the
email: ph.beaucamps at gmail dot com, antiviral community, since detection techniques using a fixed
and also with the Virology and Cryptology Lab of the École Supérieure et signature had suddenly become obsolete for this new brand of
d’Application des Transmissions (Army Signals Academy), Rennes, France
viruses.
International Scholarly and Scientific Research & Innovation 1(10) 2007 3366 ISNI:0000000091950263
World Academy of Science, Engineering and Technology
International Journal of Computer and Information Engineering
Vol:1, No:10, 2007

• Inserting dead code that will loop long enough to have the
emulator give up on detection, relying on the prohibitive
cost of emulation (this technique is used by the B ISTRO
virus for instance).
• Random cancelling of decryption, thus running the viral
code only a random basis.
• Entry Point Obscuring (EPO) techniques, which consist
in avoiding executing the virus body at the very beginning
of the host’s execution, but rather executing it during the
host execution or even in the end.
• Using several encryption layers.
• Decrypting and running the code chunk by chunk, some
viruses decrypting and running only one instruction at a
time (like the DARK PARANOID virus, in 2004).
Open Science Index, Computer and Information Engineering Vol:1, No:10, 2007 publications.waset.org/13630/pdf

• Metamorphic techniques, which transform the encrypted


Fig. 2 Polymorphic virus infection
code.
These techniques are detailed in the literature [5], [6], [1]:
some of these techniques are used by M ETA PHOR and we
The famous W HALE virus appeared the same year: it
shall come back on them in the next section.
included polymorphism, stealth and armouring techniques and
Finally, we state Spinellis’s recent result [18], which estab-
mutated in particular the code of its mutation function using
lishes the general complexity of the detection of such viruses.
obfuscation techniques (dead code, test repetition, redundant
He shows that the problem of detecting polymorphic viruses,
code, . . . ). Then “boards” appeared, where were shared viruses
of bounded length, is NP-complete, by reducing to it the well-
and e-zines, among which Phrack and 40Hex, and where
known SAT problem of satisfiability.
were worked out and shared new viral techniques. Then in
1992 the first polymorphic engines appeared, like M T E, TPE,
C. Metamorphic Viruses
NED and DAME1 , which could be linked to the virus to
produce a polymorphic variant. They were quickly followed Metamorphic viruses are in a sense advanced polymor-
by the first virus creation toolkits, like VCL, PS-MPC and phic viruses: on each replication, the code to be executed
G22 , some of which including polymorphism features. This completely mutates, without altering its functionality. Thus,
signalled the start of massive creation – in thousands – of encryption is not anymore necessary and, when used, the
simple and polymorphic viruses. decryption method as well as the decrypted code of the virus
are different for each new generation. Figure 3 presents a
On the antiviral community side, the answer came in 1992 basic example of infection by a metamorphic virus, on its
when Eugene Kaspersky worked out a technique now used by ieme mutation: in practice, the code is often encrypted and the
most antivirus products, namely detection by code emulation. decryption routine is sometimes scattered among the host’s
Since one could not anymore rely on the static version of code (ZM IST virus for instance).
a program’s code to detect a virus, the code was run in a
controlled (emulated or sandboxed) environment on a given
number of instructions, and periodically or in the end the
affected memory was analysed to detect the (possibly partially)
decrypted viral code. Indeed, and this is the base principle of
metamorphism, polymorphic codes had the major drawback of
always decrypting themselves into the memory into an invari-
ant and thus detectable form. However this detection technique
also has the disadvantage of being quite cpu-intensive.
Several techniques, called anti-emulation techniques, have
been developped as a result by virus writers to hinder this kind
of detection:
• Using unusual instructions which an emulator might not
support and interpret, or similar tricks that would prevent
the virus from decrypting itself correctly or that would Fig. 3 Metamorphic virus infection on generation i
betray the presence of an emulator.
The first metamorphic techniques made their appearance
1 M UTATION E NGINE (M T E) by Dark Avenger, T RIDEN T P OLYMORPHIC in 1997 with the T INY M UTATION C OMPILER (TMC), by
E NGINE (TPE), N U KE E NCRYPTION D EVICE (NED) and D ARK A NGEL’ S
M ULTIPLE E NCRYPTOR (DAME). Ender. This virus had a compiler embedded in its body as well
2 V IRUS C ONSTRUCTION L AB (VCL), P HALCON /S KISM M ASS -P RODU - as its own sources in encrypted pseudocode. On execution, the
CED C ODE G ENERATOR (PS-MPC) and P HALCON /S KISM ’ S G2 V IRUS virus decrypted its source code, inserted dead code, mixed up
G ENERATOR (G2).
its code and data, and recompiled everything.

International Scholarly and Scientific Research & Innovation 1(10) 2007 3367 ISNI:0000000091950263
World Academy of Science, Engineering and Technology
International Journal of Computer and Information Engineering
Vol:1, No:10, 2007

On the same year, Z0mbie developped his Z0 MBIE ’ S The virus is analysed, along with other polymorphic and
C ODE M UTATION E NGINE (ZCME), which did not use any metamorphic viruses, in [19].
encryption techniques but allocated a 16K buffer where it Finally, M ETA PHOR, by Mental Driller, appears in 2002
randomly copied out its instructions, linking them with each and is certainly the most advanced metamorphic virus until
other with JMP instructions and filling the remaining space today. It may infect both Elf (on Linux) and PE (on Win-
with dead code. dows) files, on the local file system and on mounted partitions
In 1998, Vecna implemented M ISS L EXOTAN, which dis- (in Linux) or shared folders (in Windows).
assembled itself, added some dead code and modified the
Let’s also mention the recent development of Java and
form of its instructions, in a computational way most par-
MSIL3 viruses, which are platform-independent. .NET assem-
ticularly (see later). To create dead code, it inserted most
blies infection is simplified by the presence of assembler li-
notably meta-instructions XOR ebp, imm, with no effect,
braries (System.Reflection.Emit namespace) and both
but which defined which registers were used and thus should
technologies enclose standard high level cryptography li-
not be modified. He also implemented R EGSWAP later, which
braries. Only one metamorphic MSIL virus is known as of
shuffled the registers. Here is an excerpt from L EXOTAN:
today, —Gastropod—, and there still are very few Java and
Open Science Index, Computer and Information Engineering Vol:1, No:10, 2007 publications.waset.org/13630/pdf

xor bp, __fill + __ax + __bx + __flag MSIL viruses. But given the ubiquity of both technologies,
; tells that registers ax, bx and
; the FLAGS are used by the code these viruses might well represent a threat in the near future
add ax, bx for any platform that supports them.
xor bp, __fill + __ax + __flag
add ax, 10h
push ax The rapid evolution of viral techniques towards first poly-
mov ax, 0 morphic and then metamorphic techniques motivated the
working out of new detection techniques, based on emulation
After transformation, this code may look like this, with no
and behaviour analysis allowing to identify suspect behaviours.
jumps:
However in the same time, they revealed two limitations that
xor bp, __fill + __ax + __bx + __flag
mov dx, bx
are inherent to antiviral defence and benefit virus writers.
xor cx, cx ; First, the efficiency of these methods relies on an often
push cx ; dead code prohibitive complexity when iterated on a high number of
add ax, dx
pop cx ;
files: defence cannot monopolize resources of the protected
xor bp, __fill + __ax + __flag system whereas attack has a priori no cost nor time limits.
mov bx, 34h Moreover a delay of a few hours or of a day is long enough
push bx
mov bx, ffCCh
for a well-implemented virus to spread on a very large scale,
pop ax hence the interest for virus writers to complicate as much as
add ax, bx possible analysis of their viruses. Although these weaknesses,
xor bx, bx
push ax
combined with advanced metamorphic techniques, are not
mov bx, 10h used yet in a lot of viruses (or these very viruses are often
sub ax, ax buggy and easily detected and stopped), they define a new
In 2000, the BAD B OY, ZM ORPH, E VOL, ZP ERM, B ISTRO age of viral detection, in which current protection methods
and ZM IST viruses enter the growing list of metamorphic will be thoroughly obsolete.
viruses, using more or less complex techniques. ZP ERM
most notably introduces the R EAL P ERMUTATION E NGINE III. S TUDY OF A METAMORPHIC VIRUS : M ETA PHOR
(RPME), which can be linked to other viruses, and enables The cross-platform metamorphic virus M ETA PHOR4 was
random permutation of the virus code, with insertion of dead written in 2002 by The Mental Driller and was the second
code and branching using JMP instructions. highly advanced metamorphic virus (with ZM IST), and the
ZM IST, by Z0mbie, is more particularly one of the most first ever polymorphic, and metamorphic, Linux virus. It was
evolved (and most stable) metamorphic viruses until now. It published in 29A’s magazine [14]: its sources can be found
uses the following techniques: on VX Heavens [11]. It uses highly advanced metamorphic
• Entry Point Obscuring (EPO). techniques which combine the majority of the techniques used
• Metamorphism: by its predecessors. They’re used along with anti-heuristic and
– (Random) encryption with two keys. anti-emulation techniques.
– Code integration: it’s the first virus to use this
method which consists in scattering the decryptor’s A. Overview of the techniques used by M ETA PHOR
code directly among the host’s code, which makes Here are the main polymorphic techniques used by M ETA -
the virus hard to detect and hard to disinfect. The PHOR:
M ISTFALL engine is used for this technique.
• XOR / SUB / ADD encryption, with random key, or no
– Permutations (it uses ZP ERM’s RPME engine).
encryption at all;
– Dead code, generated by the E XECUTABLE T RASH
G ENERATOR (ETG). 3 i.e. targetting .NET assemblies.
– Syntaxic modification of instructions. 4 M ETA PHOR is also known as S IMILE or E TAP .

International Scholarly and Scientific Research & Innovation 1(10) 2007 3368 ISNI:0000000091950263
World Academy of Science, Engineering and Technology
International Journal of Computer and Information Engineering
Vol:1, No:10, 2007

• Branching technique; d) Encryption with permutation: The input data is simply


• Pseudo-Random Index Decryption (PRIDE); permutated. Permutation can occur on the scale of the whole
• Metamorphic techniques: data, of chunks of bytes (of fixed or variable length), or even
– Dead code insertion; of each byte (with the ROR instruction for instance).
– Instruction modification; e) Multiple encryption: Several encryption techniques
– Random modification and permutation of registers; are sequentially applied.
– Code permutation; f) Random key encryption: The data is encrypted with a
– Mutation of the memory access profile. random key which is not stored for future decryption. Upon
execution, the key (as well as the encryption technique) can
only be recovered by brute force attack or cryptanalysis. This
B. Polymorphism in M ETA PHOR
technique disables any code emulation analysis. The size of
1) Encryption techniques: First let’s describe the miscel- the key space (and possibly its properties) allows to control
laneous encryption techniques which are commonly used in over the decryption time. This technique was introduced by
polymorphic viruses (see [15] for some more details and for DarkMan in 1999 in his R ANDOM D ECODING A LGORITHM
examples).
Open Science Index, Computer and Information Engineering Vol:1, No:10, 2007 publications.waset.org/13630/pdf

E NGINE (RDAE), which implemented several encryption


a) Basic encryption: The most simple ones, as well techniques without storing the key: only the code’s CRC32
as the most common ones, use a mere XOR (as shown in checksum was stored. These techniques are detailed in [2],
the example), ADD or SUB encryption, with a key which is [7].
randomly generated on each replication and which is stored g) Code-dependent encryption: The binary code itself is
inside the virus data or directly inside the decryption method. used as the encryption key, or a combination of the code and
The following code is a basic example of such an encryption: a random key. This technique was usually used to ensure
mov esi, offset enc_code_start that the code had not been modified – during an antiviral
; start of encrypted code analysis (where the code could be patched to disable some
mov edi, esi ; start of decrypted code
mov ecx, (offset enc_code_end - anti-debugging techniques).
offset enc_code_start) / 4 ; size in dwords
mov ebx, 6B3C728Ah ; encryption key Upon decryption, the virus needs access to the decryption
start:
lodsd ; load a dword in eax key(s). This key is usually directly stored in the program:
xor eax, ebx ; decrypt it inside the decryption procedure, inside the virus data or simply
stosd ; save it related to the host program (for instance the key can be the
loop start
end: host’s filename). The case of RDA is different since the key
jmp enc_code_start is retrieved by brute force. However other scenarios exist
where the key isn’t stored in the code but is inferred from
b) Sliding key encryption: One drawback of the previous
technique is that, once the key has been chosen, each character the environment. This technique is called environmental key
generation [16]. Here are some examples:
is encrypted in a unique way. Thus the sliding key encryption
updates the key as the decryption progresses, either in a fixed • The key is forged from the local environment. For in-

way or for instance with the last encrypted character. For stance, the key is the hard disk serial number, combined
instance, the previous code could be modified in the following with some random value stored in the code, etc.
way: • The key depends on activation factors. For instance, it
depends on the current date and will only be valid during
...
xor eax, ebx some predetermined period. In consequence, the virus
add ebx, eax itself will be disabled outside the valid periods.
... • The key is stored on a web server, a news server, etc.

c) Flow encryption: This method uses a key to generate a The most advanced implementation of this technique is the
keystream of the same size as the data to encrypt. For instance proof of concept B RADLEY virus [4]. It uses several encryp-
the generation of this pseudo-random keystream might use tion layers, whose keys are retrieved from the environment.
one or several linear feedback shift registers (LFSR, see The interest of such viruses from their writer’s point of view,
section III-D1). Some basic implementations simply duplicate is that they can restrict the activity of their virus geographically
as much as needed the input key. The previous code can be as well as temporally. Filiol also shows in [4] that, if the key
easily adapted to this technique, in the case of a single register is unknown during the analysis, the cryptanalysis’s complexity
(lfsr_init initializes the register, and lfsr_next shifts is exponential (in B RADLEY’s case).
the 32bits register, thus generating a new key):
As for M ETA PHOR, it encrypts its code with an initial
... probability of 15/16 and uses an encryption method (with
mov ebx, 6B3C728Ah
call lfsr_init ; init the register from the key random key) of type XOR, ADD or SUB.
start:
lodsd However, M ETA PHOR’s decryption method is much more
call lfsr_next ; ebx := 4 new bytes from keystream
xor eax, ebx interesting. It uses techniques that The Mental Driller had al-
... ready implemented into the T UAREG engine (TAMELESS U N -

International Scholarly and Scientific Research & Innovation 1(10) 2007 3369 ISNI:0000000091950263
World Academy of Science, Engineering and Technology
International Journal of Computer and Information Engineering
Vol:1, No:10, 2007

PREDICTABLE A NARCHIC R ELENTLESS E NCRYPTION G EN - int jmp;


ERATOR) and that he describes in another issue of 29A’s
magazine [13], [12]. This engine combined most notably two if (recLevel >= maxLevel) { // maximum depth?
insert_code (); // decryption code
novel techniques, with an anti-heuristic purpose, which also build_instr (OP_CMP, REG_ECX, code_len);
took part in the mutation of the decryption routine. Both // CMP ecx, code_len
techniques, the branching technique and the PRIDE technique, jmp = insert_partial_jump (OP_JNZ); // JNZ <?>
partial_jumps [cnt_partial_jumps ++] = jmp;
are used in M ETA PHOR. Finally, an EPO technique is used to // update the target in the end
give control to the decryption routine: M ETA PHOR changes ... // call the decrypted code
all calls to the exit function into calls to this routine. return;
}
Thus, the virus only gains control after execution of the
program, which contributes to its stealth and protects it from recLevel ++;
the detection by emulation. add_node (insert_label ()); // save the new branch
2) Branching technique: A basic decryption method has a if (random_boolean ()) { // test CMP or TEST?
structure that often follows a common template which will int reg, val, op;
Open Science Index, Computer and Information Engineering Vol:1, No:10, 2007 publications.waset.org/13630/pdf

trigger an alarm in any heuristic engine, as one can see with reg = get_random_register ();
val = 0x80000000 | (random () & 0x3fffffff);
the examples from last section. Thus the branching technique // 0x8XYYYYYY (X < 4)
allows to simulate as much as possible the behaviour of an build_instr (OP_CMP, reg, val); // CMP reg, val
innocuous program. Such programs will usually sequentially op = OP_JB + (random () & 0x5); // JB/JA/JBE/JAE
jmp = build_partial_jump (op); // partial jump
test several conditions and, depending on the result, finally } else {
branch on distinct paths. This technique therefore creates int reg, val, op;
several random tests, until a given recursivity level, that will reg = get_random_register ();
val = 0x1 << (random () & 0x1f); // 2ˆX (X < 32)
define an execution tree with leaves representing distinct ways build_instr (OP_TEST, reg, val); // TEST reg,val
to decrypt the code. Figure 4 describes the execution tree for a op = OP_JZ + (random () & 0x1); // JZ or JNZ
maximum depth of recursivity equal to 2: each terminal branch jmp = build_partial_jump (op); // partial jump
}
has its own decryption code, though the final result is the same,
whatever branch is taken. Thus for a depth of recursivity equal /* first branch: */
to n, 2n decryption branches are generated. make_branch ();
complete_partial_jump (jmp, insert_label ());

/* alternative branch: */
make_branch ();

recLevel --;
}

And here is an example code it could yield, for a recursivity


depth of 2:

br0:
cmp reg1, val1 ; reg1, random register
; val1 = 8XYYYYYYh (X < 4)
jcc alt0 ; jcc = jb / ja / jbe / jae
br1:
Fig. 4 Execution tree with and without branching technique test reg2, val2 ; reg2, random register
; val2 = 2ˆX (X < 32)
jcc alt1 ; jcc = jz / jnz
Furthermore, to reduce the risk of an heuristic alert upon <Decryption code 1>
execution of a branch, terminal branches do not contain a cmp ecx, code_len
jnz br1’
decryption loop but only its body: once the body is executed, ...
a jump is made to any one of the previous nodes in order alt1:
to carry on decryption. Thus, upon execution, each branch <Decryption code 2>
cmp ecx, code_len
makes the same computation and all branches are shared and jnz br1
alternatively used to implement the decryption loop. Here is ...
the C algorithm used in M ETA PHOR (ll. 15750 – 16075): alt0:
br1’:
void do_branching () { cmp reg3, val3
int i; jcc alt1’
<Decryption code 3>
make_branch (); cmp ecx, code_len
for (i = 0; i < cnt_partial_jumps; i++) jnz br0
// redirect each jump at a random node ...
complete_partial_jump (partial_jumps[i], alt1’:
get_random_node ()); <Decryption code 4>
} cmp ecx, code_len
jnz br0
void make_branch () { ...

International Scholarly and Scientific Research & Innovation 1(10) 2007 3370 ISNI:0000000091950263
World Academy of Science, Engineering and Technology
International Journal of Computer and Information Engineering
Vol:1, No:10, 2007

As this will be detailed in section III-C about metamorphic AND CR, val’ ; val’ = ((random() &
techniques, this code is actually an intermediate representation ; ˜size_of_data) | (size_of_data-4)) & -4
; (-> CR := (CR % size_of_code) & FFFFFFFCh)
of the final code: once the code has been created, M ETA PHOR ADD IR, pride_step
generates the final x86 code by rewriting each instruction AND IR, val’’ ; val’’ = ((random() &
into an equivalent sequence of instructions and by randomly ; ˜size_of_data) | (size_of_data-1)) & -1
; (-> IR := IR % size_of_code)
inserting dead code. CMP CR, pride_start
3) PRIDE technique (Pseudo-Random Index DEcryption): JNZ <?> ; jump at a random branch
The purpose of this technique is also to protect the virus from
Furthermore, the last instructions which update registers
a heuristic detection. Indeed, even with the modification of
CR and IR (ADD CR, val and AND CR, val’ for the
the execution tree of the decryption procedure, it follows the
CR register) are permutated with each other, with the obvi-
following common mechanism (for a basic encryption):
ous requirement that the AND instruction is executed before
1) data := address of a buffer inside the data section of its ADD counterpart. Also, as we can see, pride_step
the virus. determines the “order” of decryption: when equal to 0, it
2) Sequentially read data and create a new buffer, which simply corresponds to a sequential decryption (starting at
Open Science Index, Computer and Information Engineering Vol:1, No:10, 2007 publications.waset.org/13630/pdf

will contain the decrypted data. index (IR ˆ pride_start)).


3) Give control to the new decrypted code.
This ends the study of polymorphic techniques in M ETA -
The second stage of this procedure, which consists in
PHOR. Both techniques we described mainly aim to impede
sequentially reading a sequence of 1000 bytes or more in
any detection by emulation: however, in a sense, they also have
memory, presents a high risk of heuristic alert. Therefore, the
a mutation role, not anymore in the form but in the behaviour.
PRIDE technique consists in decrypting data in a pseudo-
This proximity between signatures used for form analysis and
random order and not anymore in a sequential order. Byte
signatures used for behaviour analysis is studied into more
10 will be decrypted, then byte 23, then byte 7, then byte
details in [6].
48, and so on. This memory access profile is much closer
to an innocuous application’s memory access profile. In the
same time, this technique reinforces the polymorphism of the C. Metamorphism in M ETA PHOR
decryption code. M ETA PHOR’s metamorphic engine takes up 70% of the
Here is the algorithm used for the PRIDE technique (ll. source code (11000 lines in all), the remaining 30% accounting
15570 – 15652 and 15827 – 15984). size_of_data is the for the infection routines (20%) and the decryptor’s creation
size of the data to be encrypted, rounded up to a power of 2. routine (10%). This proportion isn’t uncommon: some meta-
First the algorithm initializes its variables: morphic viruses devote up to 90% of their code to their
pride_start = (size_of_data - 4) & random (); metamorphic engine. The engine is used to mutate the virus
// aligned on a dword boundary body (more precisely the part to be encrypted) as well as the
pride_step = (size_of_data - 8) & random (); decryptor itself.
// aligned on a qword boundary
pride_key = get_random_key (); The engine works according to the following template,
which The Mental Driller calls humorously accordion model:
Then it initializes the registers to be used by the decryption 1) Disassembly / Depermutation
routine: CR, IR and BR. CR is the counter register and contains 2) Compression
the sequential decryption index, IR is the index register 3) Permutation
and contains the pseudo-random decryption index (XOR’ed 4) Expansion
actually with CR), BR is the buffer register used as temporary 5) Reassembly
storage for encrypted data. Compared to the decryption routine
One particularity of this engine, which conceptually differ-
in section III-B1, we have: CR ≡ ecx, IR ≡ esi ≡ edi and
entiates it from its predecessors, is the use of an intermediate
BR ≡ eax. The following code is written at the beginning of
representation which allows to dissociate from the complexity
the decryption routine:
of the underlying processor’s instruction set and to simplify the
MOV CR, pride_start miscellaneous transformations and the code manipulation and
MOV IR, val ; val = (size_of_data - 4) & random()
MOV BR, val’ ; val’ = random() creation. For instance, equivalences between x86 instructions
are deferred until the reassembly stage, jumps at other code
Finally, when the decryption routine’s body must be gen- instructions are translated into a pointer perspective (that are
erated (call to insert_code inside the make_branch much easier to manipulate, compared to offsets), etc.
method), the algorithm writes: 1) Description of the pseudo-instruction set: M ETA PHOR
PUSH IR uses a limited instruction set. It only considers instructions
XOR IR, CR that are actually used by the code. Since this intermediate
MOV BR, [IR + source]
XOR BR, key ; or ADD BR, +/- key
representation isn’t used when modifying the host code, this
; or nothing (no decryption) restriction is natural. This instruction set is organized as
ADD IR, dest follows:
MOV [IR], BR ; write the decrypted dword
POP IR • Base instructions with 2 operands: ADD, OR, AND, SUB,
ADD CR, val ; CR += [4;7] XOR, CMP, MOV and TEST.

International Scholarly and Scientific Research & Innovation 1(10) 2007 3371 ISNI:0000000091950263
World Academy of Science, Engineering and Technology
International Journal of Computer and Information Engineering
Vol:1, No:10, 2007

• Base instructions with 1 operand: PUSH, POP, Jcc, NOT, target of a branching instruction. In the end, the computed
NEG, CALL and JMP. intermediate code has been depermutated and the inaccessible
• Other instructions: SHIFT, MOVZX, LEA, RET and NOT. code (dead code) removed: this is actually a direct conse-
• Macro-instructions: quence from the routine’s algorithm.
– APICALL_BEGIN, APICALL_END, APICALL_STORE, The x86 code is disassembled by following the execution
which represent the instruction sequences which are flow. The algorithm uses an array, FutureLabelTable,
used when calling a Windows API (in the case of a which contains instructions which are waiting for their dis-
PE infection): since the registers to be used by these assembly (namely these are the targets of conditional jumps
calls are predefined, these macro-instructions ensure and direct calls). Here is the algorithm:
their protection from register swapping transforma- • If the current instruction was already disassembled, sim-
tions. ply add a JMP instruction which points at the disas-
– SET_WEIGHT which is used for “genetic” evolution sembled instruction. Then carry on disassembly with
(see section III-D2). an instruction from FutureLabelTable (if any) or
– LINUX_GETPARAMS, which is similar to APICALL_ terminate.
Open Science Index, Computer and Information Engineering Vol:1, No:10, 2007 publications.waset.org/13630/pdf

BEGIN, and represents the loading of parameters into • Otherwise:


general purpose registers. 1) If previous instructions did point at the current
– LINUX_SYSCALL which represents a syscall (int instruction, update them in order to point at the new
80h – used to call a system function); and LINUX_ disassembled instruction.
SYSCALL_STORE which represents a syscall fol- 2) Create the new pseudo-instruction. The following
lowed by the result’s saving. cases are more specifically distinguished:
• Instruction used only by internal operations: Mov Mem,
– INC and DEC instructions are replaced by their
Mem, used during the compression stage, and INC and ADD and SUB counterparts: during the reassem-
LITERAL_BYTE (unencoded byte to be inserted as it is) bly stage, the opposite transformation will be
which are used during the reassembly stage. applied (or not).
The opcode choices are motivated by the equivalent x86 – If this is a JMP instruction: either its target
opcode organization and by the sake of simplifying the ma- was already disassembled and we simply insert
nipulation of instructions and the coding of transformations. In a JMP instruction pointing at that instruction
particular, for the first type of opcodes, the opcode itself (for (by creating a label), or the target has not been
instance ADD) is encoded into bits 6..3, and the operand disassembled yet and we insert a mere NOP.
types into bits 2..0 and 7: bit 7 specifies whether the – If the instruction is a conditional jump or a direct
operands are 8 bits (for instance mov al, 12h) or 32 bits call: if the target has been disassembled yet, add
(for instance mov eax, 12h) whereas bits 2..0 specify it to the wait array FutureLabelTable. Then
the type of operands (Reg, Imm, etc.). insert the corresponding branching instruction
Finally, a pseudo-instruction is encoded in 16 bytes: (pointing at the disassembled target, if it exists,
XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX or at the x86 target instruction).
OP *--------- operands --------* LM *- instr -*
3) Finally, if this was a JMP instruction whose target
OP contains the instruction opcode, on one byte. Then had not been disassembled yet, continue with this
the operands are encoded (register index, memory address or target. If the target was already disassembled, or the
immediate value) on the following 10 bytes. Then LM (“Label instruction is a RET, continue with an instruction
Mark”) is a flag on 1 byte telling whether this instruction is from FutureLabelTable (if any). Otherwise
the target of a branching instruction: when this is the case, continue with the next instruction.
the instruction can neither be deleted nor compressed with Code permutation is carried out, as we will see, using
instructions preceding it. The last 4 bytes contain a pointer unconditional jumps (no “opaque predicates” or similar tricks):
which has miscellaneous significations along the execution: during the disassembly, the JMP instruction used to join two
during the disassembly, it contains the address of the initial permutated blocks is replaced by a NOP instruction and the
x86 instruction, during the permutation, it contains the in- disassembly continues with the new block. Given that the
struction’s address inside the non-permutated code, etc. pseudo-code is built in a linear way, its final shape will be
Once the virus decrypted its code, it gives control to it. After that of the depermutated code. Similarly, inaccessible code
initialization of the variables and possible payload activation, that was inserted will never be disassembled.
it defines the form of next generation (internal organization of 3) Compression: After disassembly and depermutation, the
the code – where to put code, where to put data, etc.). Then generated pseudocode is compressed. This cancels the expan-
it starts the code transformation process. sion effects of the previous generations, since the compression
2) Disassembly: The x86 code is first disassembled into an rules are exactly the inverse of the expansion rules. There are
intermediate representation which uses the previous instruction five kinds of rules:
set. This procedure loads the intermediate code into the buffer 1) Instr -> Instr rules:
pointed by variable InstructionTable. It also creates an • XOR Reg, -1 -> NOT Reg
array of labels which contains all instructions which are the • SUB Reg, Imm -> ADD Reg, -Imm

International Scholarly and Scientific Research & Innovation 1(10) 2007 3372 ISNI:0000000091950263
World Academy of Science, Engineering and Technology
International Journal of Computer and Information Engineering
Vol:1, No:10, 2007

• OR Reg, 0 -> NOP The algorithm also allows to reduce sequences of operations
• AND Reg, Reg -> CMP Reg, 0 into a unique operation. For instance, ADD Reg, X / SUB
• ... Reg, Y will be reduced into ADD Reg, (X - Y): these
2) Instr / Instr -> Instr rules: decompositions are created during the expansion. Finally,
• PUSH Imm / POP Reg when a Jcc instruction is replaced by a JMP instruction,
-> MOV Reg, Imm
• MOV Mem, Imm / PUSH Mem the following code is deleted (NOPed) until reaching a label
-> PUSH Imm (instruction with LM = 1).
• OP Mem, Imm / OP Mem, Imm2 Here is an example of compression (this code represents a
-> OP Mem, (Imm OP Imm2) basic decryption routine):
• NOT Reg / NEG Reg
-> ADD Reg, 1 test esi, val1 | nop
• TEST X, Y / !=Jcc mov [Mem], val2 | mov esi, (val2 + val3)
-> NOP add [Mem], val3 | nop
• Jcc @xxx / !Jcc @xxx push [Mem] | nop
-> JMP @xxx pop esi | nop
mov [Mem2], esi | mov edi, esi
Open Science Index, Computer and Information Engineering Vol:1, No:10, 2007 publications.waset.org/13630/pdf

• ... and esi, -1 | nop


3) Instr / Instr / Instr -> Instr rules: push [Mem2] | nop

MOV Mem, Reg / OP Mem, Reg2 / pop edi | nop
Mov Reg, Mem -> OP Reg, Reg2 push val4 | mov ecx, val4
pop [Mem3] | nop
• ...
or [Mem3], 0 | nop
4) Instr / Instr / Instr -> Instr / Instr rules: mov ecx, [Mem3] | nop
• MOV Mem, Reg / TEST Mem, Reg2 / mov ebx, val5 | mov ebx, val5 XOR val6
Jcc @xxx -> TEST Reg, Reg2 / Jcc @xxx xor ebx, val6 | nop
• ...
label: |
push [esi] | mov eax, [esi]
5) Macro-operations identification rules: or esi, 0 | nop
• PUSH eax / PUSH ecx / PUSH edx pop eax | nop
-> APICALL_BEGIN mov [Mem4], eax |==> xor eax, ebx
• POP edx / POP ecx / POP eax push [Mem4] | nop
pop [Mem5] | nop
-> APICALL_END
xor [Mem5], ebx | nop
• POP edx / POP ecx / POP ebx / POP eax mov eax, [Mem5] | nop
-> LINUX_GETPARAMS mov [Mem6], eax | mov [edi], eax
• CALL Mem / MOV Mem2, eax push [Mem6] | nop
-> CALL Mem / APICALL_STORE Mem2 pop [edi] | nop
• INT 80h not esi | add esi, 4
-> LINUX_SYSCALL neg esi | nop
• INT 80h / MOV Mem, eax add esi, 3 | nop
-> LINUX_SYSCALL_STORE sub edi, 0 | nop
add edi, 4 | add edi, 4
• PUSH Reg1 / MOV Reg1, Imm1 / MOV Reg2,
mov [Mem10], 4 | sub ecx, 4
Imm2 / MOV Mem, Reg2 / POP Reg1 and [Mem10], -1 | nop
-> SET_WEIGHT Mem, Imm1, Reg1, Reg2 add ecx, [Mem10] | nop
Notation !=Jcc denotes “any opcode that is not a condi- mov [Mem11], ecx | cmp ecx, 0
sub [Mem11], 5 | jnz label
tional jump” and the notation !Jcc denotes the inverse of the add [Mem11], 5 | nop
last Jcc (for instance, JA and JBE). Furthermore, some of jnz label | nop
these rules might not be verified in the general case, but they
are in the case of M ETA PHOR’s code. 4) Variable reorganization: M ETA PHOR aims to mutate
The algorithm is simple. It compresses the code as much as at the semantic level (instructions expansion / compression)
possible. When it looks up the next instruction, it skips any and at the code level (permutation) as well as at the code
NOP instruction that is not the target of jump or a call (flag behaviour level. We already mentionned previously that it was
LM is set). As long as it did not reach the end of the code, mutating the internal organization of the viral code. When
it tries to compress chunks of one, two or three instructions the virus gains control, it allocates into memory a space of
starting from the current instruction: if a compression occurs, (340000h + X) bytes, where X is a random value between
it makes a three instructions step-back and continues. This 0h and 01F000h. This space is then organized into 5 sections
allows to take into account any new reduction opportunity (see figure 5):
that might have appeared with an instruction created by • Section Code contains the decrypted x86 code.
the last reduction. For the sake of simplicity, instructions • Section Buffers contains the miscellaneous arrays and
that are deleted are simply replaced by NOP instructions. buffers used by the virus.
In the end, the algorithm identifies all sequences of instruc- • Section Data contains the virus global variables.
tions that correspond to macro-instructions (APICALL_*, • Section Disasm contains the disassembled code and
LINUX_SYSCALL*, LINUX_GETPARAMS, SET_WEIGHT) then the result of the expansion of the permutated code.
and replaces them accordingly. Also note that, for a reduction When creating the decryption routine, it will contain its
– of any type – to occur, no instruction, except the first one, pseudocode as well as the reassembled code.
shall be the target of a jump (flag LM). • La section Disasm2 is first used as a buffer, then it

International Scholarly and Scientific Research & Innovation 1(10) 2007 3373 ISNI:0000000091950263
World Academy of Science, Engineering and Technology
International Journal of Computer and Information Engineering
Vol:1, No:10, 2007

contains the result of the permutation of the compressed Mental Driller could have taken memory access profile muta-
pseudocode, and finally it contains the reassembled code. tion to extremes by modifying this very internal organization
of pseudo-instructions. Given the massive use of instructions
accessing the contents of these pseudo-instructions, impact
would have been even stronger, even though the mutation of
the organization of pseudo-instructions is quite limited (might
we add a few padding bytes to increase mutation possibilities).
Let’s note that, in this transformation’s implementation,
variables are aligned on 8 bytes boundaries so that they can be
randomly positionned on any one of the first 4 bytes: finally,
only 4 bytes are used by a variable.
5) Permutation: Once the compression is over, the engine
permutates the code by splitting it into blocks of random
sizes, between F0h and 1E0h. When doing the splitting, the
Open Science Index, Computer and Information Engineering Vol:1, No:10, 2007 publications.waset.org/13630/pdf

following breaks are avoided:


• between a CALL instruction and the associated APICALL_

Fig. 5 M ETA PHOR’s memory organization (generation 0) STORE instruction;


• before a JMP or a RET instruction, to avoid two consec-

Before starting the mutation and replication process, sec- utive jumps;
• before a JMP or a Jcc instruction, in order for the com-
tions are randomly permutated and each section is shifted
by a random value between 0h and 7FFFh. In the end, the pression process to correctly compress any Jcc + JMP
maximum required size (into memory) is: 300000h + 5 or CMP/TEST + Jcc instructions.
* 7FFFh = 340000h. Thus, upon execution, M ETA PHOR Once the code blocks have been computed and shuffled,
never has a unique memory access profile. the new code is built (and its address saved into variable
The virus contains about 200 global variables, each of these PermutationResult). A jump at the first code block is
variables being allocated 8 bytes inside the Data section. inserted at the very beginning of the code and the code blocks
These variables are accessed by their offset in that section. A are linked with each other using JMP instructions, except in
register is specifically assigned, which isn’t modified during the following cases:
the virus execution, and which contains that section’s address. • The target block directly follows the current block.
During generation 0, this base register is ebp. Thus, to access • The block’s last instruction is an unconditional jump or
to the contents of variable InstructionTable, which is a return instruction.
at offset 10h of the Data section, one uses: The final result shall look like:
mov eax, [ebp + 10h] jmp @block1
@block4:
Given that this register (ebp) is strictly reserved to data ;-------------;
access, it is sufficient to spot all instructions that use it to ; block 4 ;
;-------------; (ends with a ret)
identify read and write accesses to a variable and to list @block2:
these very variables. Method IdentifyVariables does ;-------------;
this job and replaces in each one of those instructions the offset ; block 2 ;
;-------------;
by the index of the associated variable. Then the variables @block3:
are shuffled: their organization inside the Data section is ;-------------;
thus completely modified. Then, during reassembly, when ; block 3 ;
;-------------;
an instruction uses one of these variables, the instruction is jmp @block4
updated to contain the new base register (initially ebp) and @block1:
the new offset of the referenced variable. ;-------------;
; block 1 ;
Thus the memory access profile is modified. This kind of ;-------------;
transformation isn’t however taken to extremes. For instance, jmp @block2
the code often reads the contents of pseudo-instructions, as
6) Expansion: The expansion stage consists in applying
in the following code excerpt (where esi and edi contain
the inverse rules from the compression stage. This method
pseudo-instructions addresses):
is called on the virus compressed pseudocode and, later, on
mov ecx, [esi+1] ; Get the value in ECX the decryption routine’s code.
mov eax, [esi]
add esi, 5
The first step consists in randomly modifying the used
and eax, 7 ; Get the register in EAX registers. A bijective transformation is applied, which takes
mov [edi+1], eax ; Set the register into account the following requirements:
mov [edi+7], ecx ; Set the value
• No register should of course be transformed in ESP.
This kind of access can be profiled, since the internal • The base register (initially EBP) used to store the Data
organization of an instruction does not mutate. However The section’s address (see section III-C4) should not be any

International Scholarly and Scientific Research & Innovation 1(10) 2007 3374 ISNI:0000000091950263
World Academy of Science, Engineering and Technology
International Journal of Computer and Information Engineering
Vol:1, No:10, 2007

of EAX, ECX or EDX (which are used by system calls). ...


• The 8 bits register used by 8 bits operations in the code NOP
must be related to a general purpose register (EAX, EBX, • Tests that always fail, like:
CMP Reg, Reg / JNZ [RandomLabel]
ECX or EDX).
Then, the expansion can start: it will update registers as • Useless x86 instructions: STC, CLC.
well as accesses to the virus’ global variables. The expansion’s 7) Reassembly: The last stage consists in assembling the
result is stored in variable ExpansionResult. To control pseudo-code into valid x86 code. When several translations
the size of expansion, a maximum level of recursivity is first are possible, the algorithm chooses one at random. Also, short
chosen: it cannot be larger than 3. Then, for each instruction, jumps and long jumps are randomly used (when a short jump
we increment the recursivity level and we randomly trans- is possible), and jumps at subsequent addresses are stored in
form it, by using the inverse compression rules. Intermediate array JmpRelocationTable, in order to be updated in
instructions which are generated are also transformed. NOP the end. After completion of this stage, the code is ready for
instructions are ignored in the compressed code (to avoid an encryption and copy out in the host.
uncontrolled increase of size, after several generations).
Open Science Index, Computer and Information Engineering Vol:1, No:10, 2007 publications.waset.org/13630/pdf

When an instruction is generated, which uses a temporary D. Randomness Techniques


memory address, this memory address points at the Data 1) Pseudo-Random Numbers Generator (PRNG): M ETA -
section and should not have been allocated for the virus PHOR makes a heavy use of random numbers. It uses its own
global variables nor by any previous instruction in the current pseudo-random numbers generator, with two seeds, seed1
expansion chain. The VarMarksTable array is used to mark and seed2, which are initialized depending on the UNIX date
which addresses have been allocated. As for global variables, for seed1 and on the code’s first bytes for seed2. Then
the allocated address is randomly aligned on one of the first 4 a random value is generated using the following algorithm
bytes. However, this is different in the case of the decryption (ror_X denotes right rotation by X bits):
routine since the memory has not been allocated yet (with int random () {
a call to malloc): the space to be used by intermediate seed1 ˆ= (seed2 + ror_13 (seed1 + seed2));
operations is then the data section that was allocated inside seed2 = (seed1 + ror_17(seed2)) ˆ (seed1 + seed2);
return seed1 + ror_17 (seed1 ˆ seed2);
the host file for the decryption operations. }
When an instruction uses an immediate value, this value Though this may not be obvious at first sight, the second
is computationally decomposed into a sequence of operations seed is very weak, given furthermore that it is initialized
that finally yield the expected immediate value. This expan- depending on the code’s first bytes which have a low ran-
sion is managed by method Xp_MakeComposedOPImm. It domness: thus we get, in the worst case, a cyclic generator
uses operators ADD, AND, OR and XOR (the SUB opera- of 32 pseudo-random numbers (as soon as seed2 reaches
tor is randomly generated when transforming ADD instruc- value 0x00000000 or value 0xFFFFFFFF). For a random
tions). Here is for instance the algorithm used to generate a seed2, a few tests allow to compute the PRNG’s period
MOV Dest, Imm instruction: about 40000, which is barely better that the glibc’s gener-
int v1 = random (), v2 = random (); ator (random () function), whose statistical properties are
particularly weak and whose period is in the order of 30000.
choose randomly among:
* MOV Dest, v1 Polymorphic viruses usually have their own pseudo-random
ADD Dest, Imm - v1 generator, often of poor quality, which protects them at least
from a heuristic alert due to a strong utilization of a system’s
* MOV Dest, v1 & Imm
OR Dest, ((v2 & Imm) ˆ (v1 & Imm)) | (v2 & Imm) PRNG. Yet, some generators exist that are quite powerful and
have a small cost, but their use in polymorphic viruses is
* MOV Dest, (v2 & ˜v1) | Imm scarce. Here are some of them:
AND Dest, v1 | Imm
• Linear Congruential Generator (LCG), of which the
* MOV Dest, ˜v1 | Imm following code is an implementation:
AND Dest, v1 | Imm
unsigned int lcg_next (void) {
seed *= 1664525u;
* MOV Dest, v1 seed += 1013904223u;
XOR Dest, v1 ˆ Imm
return seed;
}
* MOV Dest, Imm
• Registers generaztors, like Xorshift generators (the fol-
In addition, dead code is inserted, with probability 1/16, lowing example code comes from [10]) and generators
after each expansion of an instruction of the compressed code with linear feedback shift registers (LFSR):
(if this instruction’s opcode was a CMP, TEST, CALL or /* Galois’ LFSR, with taps 32 31 29 1 */
unsigned int lfsrg_next (void) {
APICALL_STORE, a mere NOP is inserted): static unsigned int seed = time (NULL);
• Instructions that do nothing, like: int i;
MOV Reg, Reg for (i = 0; i < 32; i++) // shift 32 times
ADD Reg, 0 seed = (seed >> 1) ˆ
AND Reg, -1 (-(signed int)(seed & 1) & 0xd0000001u);

International Scholarly and Scientific Research & Innovation 1(10) 2007 3375 ISNI:0000000091950263
World Academy of Science, Engineering and Technology
International Journal of Computer and Information Engineering
Vol:1, No:10, 2007

return seed; ues cannot exceed a minimal and a maximal threshold (thus
} the associated probability never reaches 1 or 0).
unsigned int xorshift128_next (void) {
/* initialization with random values */ /*
static unsigned int Returns 1 or 0, depending on the gene’s contents.
x = 123456789, y = 362436069, */
z = 521288629, w = 88675123; int query_gene (int gene) {
unsigned int t; int val = get_gene (gene);
t = x ˆ (x << 11);
x = y; y = z; z = w; if ((random () & 0xFF) >= val) {
return w = (w ˆ (w >> 19)) ˆ (t ˆ (t >> 8)); // return 1 and increase propension to 1
} do {
// minimal threshold reached?
2) “Genetic” techniques: M ETA PHOR combines genetic if (val < 0x08) return 1;
characteristics to its generator. Here is the principle. The virus if ((random () & 0x0F) > 0)
contains some sort of genetic material which will have a // increase propension to 1:
set_gene (gene, -- val);
tendency to favour some behaviours rather than others. On } while ((random () & 0x0F) == 0);
each replication, this genetic material is updated with a small // repeat with probability 1/16
Open Science Index, Computer and Information Engineering Vol:1, No:10, 2007 publications.waset.org/13630/pdf

random variation from the preceding material. return 1;


} else {
For instance, a gene contains the current propension of the do {
virus to encrypt its code or not: the virus initially encrypts // maximal threshold reached?
its code with probability 1/16. Depending on its decision, the if (val >= 0xF8) return 0;
if ((random () & 0x0F) > 0)
gene will be altered in favour or in disfavour of encryption: if // increase propension to 0
the virus encrypts its body, it will have next time a higher prob- set_gene (gene, ++ val);
ability to encrypt again its body, and conversely. Thus after a } while ((random () & 0x0F) == 0);
// repeat with probability 1/16
few generations, either the code will have a strong propension return 0;
to encryption, or a strong propension to absence of encryption. }
The propension strengh is related to the survival time (and to }
the number of replications) of the virus. Thus, if the virus has For a more detailled analysis of genetic viruses, one may
a strong propension to encryption, this means that most of the refer to M. Ludwig’s books [9], [8].
previous generations chose encryption and survived: this is
kind of an implementation of natural selection, where viruses
are preys and antiviruses are predators. Thus, let’s imagine E. Detection of M ETA PHOR
that the antivirus easily detects encrypted replications of the Analysis of M ETA PHOR comes to an end. As we saw,
virus (using statistical entropy analysis for instance) but not several advanced techniques of polymorphism and of anti-
unencrypted replications. In this case, encrypted replications emulation / anti-heuristic protection are implemented in this
will be detected before being able to replicate and increase virus. Nevertheless they’re not taken to their extremes and thus
their propension to encryption, and in the end, most of the this mutation model is still detectable, mainly because of the
survivors will come from unencrypted ancestors, with a high following “weaknesses”:
propension to no encryption.
• The viral code’s encryption can always be identified by
M ETA PHOR contains a genetic material of 24 genes. In
a stastical analysis of the code [6]. Indeed, a program
other words, 24 of its choices depend on its genetic history
usually has a predefined entropy profile, which shows
and its survival abilities. These genes are used for instance
few variations when comparing miscellaneous executable
for:
files. Encrypted data, however, have a specific entropy
• Number of files to infect: initially, only 50% are infected. profile which is much more uniform, depending on the
• Choice of the method of infection: position of the viral underlying encryption system, and thus is characteristic
code, EPO type, type of the system calls, etc. of an encrypted content. Same goes for compressed data.
• Encryption of the viral code, or no encryption: initially, Any antivirus using this kind of analysis will most likely
the code is encrypted with probability 1/16. consider as suspect a program that contains a lot of en-
• Encryption method (ADD, XOR, SUB): initially, all meth- crypted content. However, several legitimate applications
ods have the same probability of being chosen. use encrypted data, for the purpose of intellectual prop-
• Decryption routine’s code: form of the instructions, ob- erty protection. This is the case of “packed” applications
fuscation type, use of anti-heuristic methods, etc. (even though malware also uses packers on a regular
Given that the virus does not store any information in its basis), and this is also the case of Skype for instance.
host other than its code, it must still be able to update its • When the virus is executed, it compresses its code into
genetic material, from one generation to another. This is where a form that is roughly the same from one generation
SET_WEIGHT macro-instructions come into play: they’re lo- to another, by conception: M ETA PHOR is therefore
cated on disassembly and, on reassembly, the “evolved” gene vulnerable to any form analysis that monitors memory. As
is used. we might have expected, this weakness can be corrected
Here is the algorithm used to update the genes (function to some extent, using miscellaneous techniques that are
CheckForBooleanWeight). We notice that the genes val- preferably not described here but easy to find out. Another

International Scholarly and Scientific Research & Innovation 1(10) 2007 3376 ISNI:0000000091950263
World Academy of Science, Engineering and Technology
International Journal of Computer and Information Engineering
Vol:1, No:10, 2007

weakness is also the immutability of M ETA PHOR’s easy). In the same time, development of rootkit techniques
mutation grammar. draws away attention. Yet, both threats are real, with different
• M ETA PHOR’s mutation grammar is globally simple and maturities, but none of them should be overlooked. Even
does not use any sophihsticated obfuscation tricks – this though the second one is mostly implemented in worms, which
is by conception given that the virus wants to be able currently represent the most important infectious threat, and
to revert effects of mutation. In other words, using more even though it is more technical than the first one, and thus
advanced obfuscation techniques, possibly along with the within the means of more hackers.
addition of metadata into the code (as is the case with All in all, if virus writers were a bit less “in a hurry”
M ISS L EXOTAN – see section II-C), would lead to a virus, and refined their techniques, the antiviral community could be
which would be much harder to detect (speaking of its quickly overtaken. An advanced use of syntactic and functional
mere detectability as well as of the complexity of its polymorphism techniques, combined with advanced stealth
detectability). techniques, would theoretically make the complexity of the
• Except during decryption, M ETA PHOR does not protect detection problem prohibitive or even undecidable [6] (POC
itself from behaviour analysis. virus PBMOT).
Open Science Index, Computer and Information Engineering Vol:1, No:10, 2007 publications.waset.org/13630/pdf

É. Filiol studies into more details some aspects of M ETA -


PHOR in [6], from a theoretical point of view, and most R EFERENCES
notably regarding the detection barrier on which M ETA PHOR [1] John Aycock. Computer Viruses and Malware. Springer, 2006.
sits astride: if it mostly inclines towards detectability, some [2] Philippe Beaucamps and Éric Filiol. On the possibility of practically
modifications would be sufficient to have it incline towards obfuscating programs – towards a unified perspective of code protection.
Journal in Computer Virology, 3(1), April 2007.
the other side (see the POC virus PBMOT). To sum up, [3] Fred Cohen. Computer viruses - theory and experiments, 1984.
M ETA PHOR is a highly advanced virus, which could be really [4] Éric Filiol. Strong cryptography armoured computer viruses forbidding
dangerous with a few improvements (PBMOT certainly is code analysis: the B RADLEY virus. In Proceedings of the 14th EICAR
conference, May 2004.
the most appropriate proof). Other advances, as on the field [5] Éric Filiol. Computer viruses: from theory to applications. Springer
of functional polymorphism, would also give metamorphic Verlag, 2005.
viruses more sophisticated means of defence against detection. [6] Éric Filiol. Advanced viral techniques. Springer Verlag France, 2007.
An english translation is pending, due mid 2007.
[7] Kharn. Exploring RDA. .aware eZine, 1, January 2007.
IV. C ONCLUSION [8] Mark Ludwig. Computer Viruses, Artificial Life and Evolution. Ameri-
can Eagle Publications, Inc., 1993.
If polymorphic and above all metamorphic techniques de- [9] Mark Ludwig. The Giant Black Book of Computer Viruses. American
scribed in this document enable viruses to protect themselves Eagle Publications, Inc., 1995.
[10] George Marsaglia. Xorshift RNGs. Journal of Statistical Software,
in a more efficient way against detection, their sophistication 8(14), 2003.
mostly stems from antiviral protection. For antiviral protection [11] The Mental Driller. M ETA PHOR source code. Version 1D available at:
is in fact eternally submitted to two paradoxes: http://vx.netlux.org/src view.php?file=metaphor1d.zip.
[12] The Mental Driller. T UAREG details and source code. Available in
• The more it develops, the more viruses, worms and other 29A#5: http://vx.org.ua/29a/29A-5.html.
malwares use advanced protection techniques which get [13] The Mental Driller. Advanced polymorphic engine construction. 29A,
5, December 2000. Available at: http://vx.netlux.org/lib/vmd03.html.
harder and harder to bypass. In a sense, it sentences [14] The Mental Driller. Metamorphism in practice or ”how i made M ETA -
itself indirectly to its own impotence (wrt these advanced PHOR and what i’ve learnt”. 29A, 6, February 2002. Available at:
techniques). Yet currently it still remains efficient, thanks http://vx.netlux.org/lib/vmd01.html.
[15] MidNyte. An introduction to encryption, April 1999. Available at:
to the mediocre quality of most malwares or to the com- http://vx.netlux.org/lib/vmn{04,05,06}.html.
plexity of the mentionned protection techniques, which [16] James Riordan and Bruce Schneier. Environmental key generation
discourages most malware writers. towards clueless agents. In Lecture Notes In Computer Science, volume
1419, pages 15 – 24, 1998.
• And secondly, if on one side the increase of RAM size [17] Alisa Shevchenko. The evolution of self-defense technologies in
and CPU speed, as well as the upcoming of multi-core malware. Available at: http://www.net-security.org/article.php?id=1028,
processors, seem to be in favour of antiviral protection, July 2007.
[18] Diomidis Spinellis. Reliable identification of bounded-length viruses is
it also enables malwares to use more and more complex NP-complete. IEEE Transactions on Information Theory, 49(1):280 –
techniques, without having to worry about their cost. 284, January 2003.
And this is all the more true as, as we told previously, [19] Peter Szor. The Art of Computer Virus Research and Defense. Addison
Wesley Professional, 2005.
antiviruses will always be limited in time and CPU cost,
unlike malwares.
Also, it should be noted that the state of the art of current
metamorphic techniques (with viral protection purpose) is
not representative of the threat they represent. Some antiviral
experts sweep blatantly away – recently again [17] – this threat Philippe Beaucamps is a PhD student at the CNRS / LORIA in Nancy,
on the pretext that it never actually proved itself except for France. He works on the modelization of viral infections, and on formal and
practical malware detection and protection.
proving its own uselessness. And as a matter of fact, the history Contact address: Loria, Équipe Carte, B.P. 239, 54506 Vandoeuvre-lès-
of metamorphic viruses tends to corroborate this: there are few Nancy Cédex, France
of them, most of which are poorly accomplished and contain
critical flaws (bugs or conception flaws which make detection

International Scholarly and Scientific Research & Innovation 1(10) 2007 3377 ISNI:0000000091950263

You might also like