Malware is code written with the intent to cause annoyance, to retrieve sensitive information about individuals, to cause data loss, or for other similar purposes. Antivirus companies are constantly trying to detect malware and to lessen or stop these damaging effects. This causes an ongoing struggle between antivirus companies and virus writers. Anti-debugging and anti-emulation techniques have been devised by virus writers to counteract the efforts of antivirus companies to detect and remove malicious code. To further detect and stop malware, these techniques must be understood. This paper attempts to identify current anti-debugging and anti-emulation techniques and to provide code samples to allow for the identification of malicious code.
1. Introduction
To
deter or slow down analysts from reverse-engineering malware, virus writers
employ anti-debugging and anti-emulation techniques. These techniques slow down the
reverse-engineering process by attempting to avoid detection when a virus is
being run in an emulator or debugger. Several
different methods are employed by malware to fool dynamic detection and other analysis
mechanisms such as emulators and debuggers.
Each virus usually employs one to many of these techniques.
This
paper discusses those methods virus writers employ to slow down
reverse-engineering of their viruses. It
also provides examples of these methods.
This paper is intends to provide an overview of the various
anti-debugging and anti-emulation techniques for those that want to protect
against these defenses.
The
paper is split into several sections. Section
2 addresses anti-emulation techniques, followed by anti-debugging techniques in
section 3, and other anti-detection techniques that do not fall into the first
two categories are discussed in section 4.
Examples of viruses that combine all of the techniques are discussed in section
5, while section 6 is the conclusion.
2. Anti-emulation
An emulator provides a restricted environment (an
image of an operating system that is installed on top of a host operating
system) in which one can dynamically analyze a program. For example, a machine running Linux can have
a virtual machine installed on it running Windows XP. An emulator will also include CPU and memory
emulation, hardware emulation, and an emulation controller [1]. This provides a safe way to dynamically
analyze programs without the possibility of causing damage to the underlying
operating system.
There are also drawbacks to this system. First, the more time spent emulating, the
longer the user has to wait to get any analysis back on the program. Second, emulation is slow due to the overhead
required to monitor the program and to emulate the operating system and
hardware. QEMU, a hardware and operating
system emulator, has between a factor of 4 to 10 slowdown in hardware emulation
and a factor of 2 slowdown on emulation of the software memory management unit
[2]. QEMU does not have any dynamic
monitoring, which would further increase the slowdown. A final drawback is that malware employs
different anti-emulation techniques to fool the emulator. These techniques fall into three categories:
Outlasting, outsmarting, or overextending the emulator.
2.1
Outlasting the emulator
Since emulation is expensive, emulators only run a
couple hundred instructions of code to detect malware before terminating. On an Intel x86 system, it is believed that
running around 1000 instructions is enough to detect malicious code while
maintaining a short runtime [1]. If the
code does nothing considered malicious during that time, the emulator will not
detect the code as malware. Outlasting
the emulator can be done by replicating based on a specific probability, by
running benign code for a specific time frame before running the malicious code,
or by entry point obfuscation.
2.1.1
Probabilistic Replication
Some malware will only replicate a certain percentage
of the time. This means that an emulator
would have to run the code several times in order to accurately detect the malicious
code. An example of this is a virus that
runs benign code 90% of executions and malicious code only 10%.
2.1.2
Running Benign Code
Other malware will run benign code every time on
startup for a specific time frame and then run the malicious code. The purpose of this is to allow the emulator
to run for the given number of instructions and pretend that the code does
nothing malicious in this time frame. It
then goes on to replicate and cause damage to a system.
2.1.3
Entry Point Obfuscation
Entry
point obfuscation (EPO) is a method that includes attaching malicious code to a
specific section of a file. Instead of the malicious code executing first, the
code can look for calls to the ExitProcess() API function and overwrite those
calls with a jump to the malicious code.
This way the code runs on exit, not entry of an executable. It can also look for a specific sequence of
code to overwrite with the malicious code itself, or with a jump to the
malicious code. Entry point obfuscation,
therefore, has the added advantage of giving the virus the ability to run the
code later by copying the code to a new location before actually overwriting it
[1].
2.2
Outsmarting the emulator
To outsmart the emulator some malware uses time based
triggers, or other conditionals, or it uses different decryption techniques if
it is encrypted malware. Time based
triggers can be anything as simple as running the malicious code only on 3 pm
or only on a specific day. The malware
can also check conditions such as checking to see if it is being debugged or
emulated. If it is, it executes benign
code.
Decryption techniques that can be used include
spreading the decryption loop throughout the code or having multiple decryption
passes [1]. Multiple decryption layers
are used by W32/Harrier, W32/Coke and W32/Zelly where the first decryptor will
decrypt the second, the second will decrypt the third, etc [9]. Malware can also only decrypt blocks of code
as needed in order to outsmart the emulator [1].
The
RDA.Fighter virus uses brute force decryption.
This means that the virus does not store the decryption key so it must
try all possible decryption keys in order to decrypt itself. This is useful because it is then difficult
for anti-virus companies to decrypt the virus without using the same brute
force method, which takes a large amount of emulation instructions. It is likely, then, that the virus will not
decrypt itself while the emulator is running.
Below is the code for the decryption code of the RDA Fighter virus [6].
setup:
xor ebx,ebx
iterate:
mov esi,[ebp + hostOffset]
mov edi,esi
mov ecx,[ebp + host_size]
inc ebx
decrypt:
lodsb
xor al,bl
stosb
loop decrypt
check:
mov esi,[ebp + hostOffset]
push esi
mov ecx,[ebp + host_size]
push ecx
mov eax,[ebp + __ADDR_CheckSum] ; whatever this happens to be
call eax
test eax,eax
jnz iterate
mov esi,[ebp + hostOffset]
jmp esi
In
the above example we see that the setup block sets ebx to zero and is only run
once. Iterate then sets esi and edi to
the beginning of the encrypted code, sets ecx to the size of the encrypted
code, and also increments ebx by one.
The decrypt basic block goes through the ecrypted code byte by byte and
xors the byte with the key in ebx. This
loop terminates when ecx becomes zero.
The check basic block then checks to see if the current code matches a
predetermined checksum. If it does, then
the code has been decrypted. If it
hasn’t been, it goes back to the iterative loop and tries again with the next
largest key. If it has been decrypted then it jumps to the newly decrypted
code.
W95/Fono
uses a nonlinear decryption algorithm, meaning that the encrypted portion of
the virus is not decrypted linearly as expected. Since the virus body is not decrypted one
byte after the other, it can confuse emulators.
W95/Fono uses a key table and the decryptor performs substitutions based
on this table. Each symbol in the
plaintext alphabet corresponds to another symbol in the ciphertext. For example: A corresponds with L, Z corresponds with F,
etc. Therefore, by using this encryption method, each piece of the virus is
decrypted in semi-random order and every position is only hit once. W95/Drill and {W32, Linux}/Simile.D use
nonlinear decryption as well.
W95/Silcer
and W95/Resure force the Windows Loader to relocate the infected program images
when they are loaded to memory.
Relocating the images is responsible for decrypting the virus body
because the virus puts in special relocations for the decryption [9]. W95/Resurrel is a virus written after
W95/Resure. This virus sets the base
address of the newly infected file to a value of 0xBFxxxxxx (the xxxxxx is a random value
returned by the GetTickCount() API call).
Then it adds a relocation entry for each DWORD value of its own code
section and encrypts each DWORD by adding the base address value to the DWORD
of the code section and then subtracting 0x400000. When the application is executed the image of
the program cannot be loaded into memory as is because the base address is wrong
or an address in KERNEL32.DLL.
Therefore, the system loader will relocate the code to a valid address,
decrypting the virus as it does so. The difficulty in decrypting the virus makes it hard to
detect [10].
2.3
Overextending the emulator
Overextending the emulator is defined as executing a
set of instructions that will cause the emulator to crash or that may indicate
that an emulator is running. Calling
undocumented instructions that an emulator may not support is one way to cause
the emulator to throw an exception and stop running. One such example is the
undocumented CPU Instruction SALC that is used in W95/Vulcano [9]. Another way to detect emulation or to crash
the emulator currently running, if there is one, is to try to access large portions
of memory at once [1]. This is usually
not effective though because most operating systems, as well as emulators, will
impede the program.
A way to detect whether an emulator is running is to
call a function twice that should return two different values. An example of this would be calling any of
the time functions twice, and verifying that there is a difference between two
return values. In Windows this can be
achieved through kernel32!QueryPerformanceCounter which wraps
ZwQueryPerformaceCounter, kernel32!GetTickCounter, or by querying the current
number of CPU cycles executed since the machine started using the RDTSC (read
time stamp counter) instruction. An
example of the latter is below [15].
push
offset handler
push dword ptr fs:[0]
mov fs:[0],esp
rdtsc
push eax
xor eax, eax
div eax ;trigger exception
rdtsc
sub eax, [esp] ;ticks delta
add esp, 4
pop fs:[0]
add esp, 4
cmp eax, 10000h ;threshold
jb @not_debugged
@debugged:
...
@not_debugged:
...
handler:
mov ecx, [esp+0Ch]
add dword ptr [ecx+0B8h], 2 ;skip div
xor eax, eax
ret
The
example above shows how the RDTSC instruction can be used to detect whether a
debugger is present. In this case, RDTSC
is called twice and the difference of the two values returned is found. This difference is then compared to a
threshold (in this example it is 10000h).
If the difference is greater, than a debugger is present and a jump away
from the malicious code is executed.
Importing
obscure libraries may not actually cause the emulator to stop running, but if
the library is not imported, the malware code itself may not run.
Malware can also look for webpages to see if it has
access to the internet. This is
something that can also cause the virus code to not execute on a machine that is
not currently connected to the internet, but also stops execution when an
emulator is running since most emulators do not allow internet access [1].
Using coprocessor FPU instructions is another way to
overextend the emulator because most emulators do not emulate the FPU
instructions. Prizzy polymorphic engine
(PPE) can generate 43 different coprocessor instructions for the use of its
polymorphic decryptor. If these FPU instructions
are not provided, the decryption on Prizzy does not execute.
Along the same lines, malware can use MMX
instructions. This instruction set adds
8 new registers to the architecture. The malware will check to see if MMX
support exists by using the CPUID instruction.
Examples of malware that use this technique are W32/Legacy and
W32/Thorin.
Malware
will also setup an exception handler, execute a garbage block of code, and then
indirectly execute its own handler to transfer control to another part of the
polymorphic decryptor. This is done in
hopes that the emulator cannot handle the exception [9]. An example that is similar to this technique
is shown in section 3.7.
3. Anti-debugging
Anti-debugging techniques are usually any attempt of
the malware to monitor its own code to detect debugging. To do this, the malware can examine its own
code for breakpoints or check for a debugger directly through system calls.
3.1
Breakpoints
To examine its code for breakpoints, the malware can
look for the 0xcc opcode instruction, which raises a SIGTRAP. This is the instruction the debugger will use
to gain control from the malware at a breakpoint. The malware can also set false breakpoints if
the malware code itself has a signal handler.
This way it can continue to execute instructions after the breakpoint
that it set.
Malware
can also try to overwrite the breakpoints.
W95/Marburg virus uses a backwards decryption loop for the virus to overwrite
the breakpoint. The viruses in the Yankee_doodle family, on the other hand, use
hamming code to self correct their code. Hamming code allows programs to detect and
correct errors, but in this case allows the virus to detect and remove
breakpoints in its code [9].
3.2
Calculating the checksum
Malware can also checksum its own code. If the checksum has changed, then the virus
can assume that it is being debugged and there have been breakpoints placed
within the code [3]. VAMPiRE is an
anti-anti debugging tool that gets around the detection of breakpoints [12]. VaMPiRE accomplishes this by keeping a table
of breakpoints in memory to maintain a list of the breakpoints that have been
set. The program consists of a
page-fault handler (PFH), a general protection fault handler (GPFH), a
single-step handler and a framework API.
When a breakpoint is triggered either the PFH (handles breakpoints set
on code, data, or memory mapped I/O) or the GPFH (handles legacy I/O
breakpoints) receives control. The
single-step handler is used for breakpoint persistence, allowing breakpoints to
be used more than once.
3.3
Detecting the debugger
A very simple way of detecting a debugger on a Linux
system is to simply call Ptrace, since Ptrace can’t be called in succession
more than once for a specific process [3].
In Windows, the system call isDebuggerPresent will return 1 if the
program is being debugged and 0 otherwise.
This system call simply checks a flag that has been set by the debugger
if it is running. This check can be done
directly by checking the second byte in the Process Environment Block. The following code is an example of this
technique.
mov
eax, fs:[30h]
move
eax, byte [eax+2]
test
eax, eax
jne
@DdebuggerDetected
As the above example shows, eax is set to the PEB
(Process Environment Block) and the second byte of that block is then accessed
and the contents moved into eax. A check
is done to see whether eax is zero. If
it is, then there is no debugger present, if not, then there is a
debugger.
When
a process is created with a debugger already running, the system sets certain
flags for the heap manipulation routines in the Windows dll ntdll.dll. These flags are FLG_HEAP_ENABLE_TAIL_CHECK,
FLG_HEAP_ENABLE_FREE_CHECK, and FLG_HEAP_VALIDATE_PARAMETERS. These flags can be checked using the
following code:
mov
eax, fs:[30h]
mov eax, [eax+68h]
and eax, 0x70
test eax, eax
jne @DebuggerDetected
In
the above example, we again access the PEB and then get the start of the flags
for the heap manipulation routine by adding 68h as an offset to the address of
the PEB. The flags are then checked to
see if a debugger is present.
Checking
flags within heap headers such as the ForceFlags is another way to detect
whether a debugger is running or not.
Here is an example [15]:
mov
eax, fs:[30h]
mov eax, [eax+18h] ;process heap
mov eax, [eax+10h] ;heap flags
test eax, eax
jne @DebuggerDetected
The above example shows how the
process heap and the heap flags can be accessed from the offset of the
PEB. These are then tested to see if
the Force Flags were previously set by a debugger currently running.
Another
possible way to detect the debugger is through the use of the
NtQueryInformationProcess syscall. This
function can be called with ProcessInformationClass set to 7, which refers to
the ProcessDebugPort, and the function will return -1 if the process is being
debugged. Below is an example [15].
push 0
push 4
push offset isdebugged
push 7 ;ProcessDebugPort
push -1
call
NtQueryInformationProcess
test eax, eax
jne @ExitError
cmp isdebugged, 0
jne @DebuggerDetected
In
this example, the parameters for the
NtQueryInformationProcess syscall are first pushed onto the stack. These parameters are as follows: the first is
the handle (in this case 0), the second is the process information length (4
bytes in this example), the following is
the process information class (in this case 7, specifying the
ProcessDebugPort), the next is the variable used to return whether or not there
is a debugger present. If this value is
non-zero then the process is being run under a debugger. If not, then all is well. The last parameter is the return length. NtQueryInformationProcess is then called with
these parameters and a return value is placed in isdebugged. This is later tested to see if it equals zero,
or not.
Other
simple ways of detecting the debugger is by checking to see if the device list
contains the name of a debugger, by checking the registry keys for a debugger,
or by scanning memory to detect the debugger’s code in memory [9].
Another
method, similar to the EPO method, is to instruct the PE loader that the entry
point of the program is referenced in the Thread Local Storage (TLS) entry in
the PE header. This has the effect of
causing the code in the TLS to execute first instead of the read entry point of
the program. Therefore, the TLS can
perform anti-debugging checks before the program even starts [15]. Starting on the TLS also allows the virus to
begin execution before the debugger starts, since some debuggers break on the
main entry point of the program [9].
3.4
Checking for single stepping
Other ways that the malware can detect a debugger is
to check for single stepping. Checking
for single stepping can be done by adding a value above the stack pointer and
then checking to see if the value is still there. If the value is there, this means that the
code is being single stepped. When a
debugger is single stepping a process, it will push instructions onto the stack
when it takes control and pop them back off the stack before it executes the
next instruction. So if the value is
still there that means that something other than the running process has been
using the stack [1]. Below is a code
example of how malware can detect single stepping by using the stack state [9]:
mov
bp, sp ; pick stack pointer
push
ax ; store any ax mark on the stack
pop
ax ; pick the value from the stack
cmp
word ptr [bp-2], ax ; compare against stack
jne
debug ; if different, debugger detected.
As
the comments in this example show, a value is pushed onto the stack then popped
off the stack. If the debugger is
present, then the value at the top of the stack pointer – 2 will be different
than the value that was just popped off the stack and the appropriate action
can be taken.
3.5
Checking for slowdown in runtime
By looking for slowdown in the runtime of the
program, malicious code can also detect a debugger. A significant slowdown in runtime likely
means that the code is being single stepped.
So if the difference in the timestamp for 2 different calls is too
great, the malware can act accordingly [1].
LTTng/LTTV Linux Trace Toolkit
gets around the slowdown problem to trace a virus. This is because LTTng/LTTV is a modular tool
that traces the program without adding breakpoints or performing any analysis
at the time of execution. It also uses a
lockless re-entry mechanism, meaning that it does not lock any portions of the
Linux kernel code that the program being traced might need to use, and
therefore does not cause the traced program to slow down and wait [4].
3.6
Instruction prefetching
If the malicious code modifies the next instruction
in a sequence and the new instruction is executed, then a debugger is running. This is due to instruction prefetching; if
the new instruction is prefetched, this means there was a break in the
execution of the process. Otherwise the
original instruction would have been prefetched and executed [1].
3.7
Self modifying code
The malware can also self-modify other code. One example of this is HDSpoof. This malware starts out with exception
handlers and then removes them during execution. That way, if anything goes wrong and an
exception is thrown by the process during execution, the virus will
terminate. It also modifies the
exception handlers at other times during execution by either removing or adding
exception handlers. Below is an example
of HDSpoof removing all exception handlers except for the default one [7].
exception handlers before:
0x77f79bb8 ntdll.dll:executehandler2@20 + 0x003a
0x0041adc9 hdspoof.exe+0x0001adc9
0x77e94809 __except_handler3
exception handlers after:
0x77e94809 __except_handler3
0x41b770: 8b44240c mov eax,dword ptr [esp+0xc]
0x41b774: 33c9 xor ecx,ecx
0x41b776: 334804 xor ecx,dword ptr [eax+0x4]
0x41b779: 334808 xor ecx,dword ptr [eax+0x8]
0x41b77c: 33480c xor ecx,dword ptr [eax+0xc]
0x41b77f: 334810 xor ecx,dword ptr [eax+0x10]
0x41b782: 8b642408 mov esp,dword ptr [esp+0x8]
0x41b786: 648f0500000000 pop dword ptr fs:[0x0]
Below
is code in which HDSpoof creates a new exception handler [7].
0x41f52b: add dword ptr [esp],0x9ca
0x41f532: push dword ptr [dword ptr fs:[0x0]
0x41f539: mov dword ptr fs:[0x0],esp
3.8
Overwriting debugger information
Some malware uses techniques that can override
debugger information and therefore cause either the debugger or the virus
itself to function improperly.
By hooking the INT 1 and INT 3 ( INT3 is the 0xCC
opcode byte that debuggers use) interrupts, malware can cause the debugger to
lose its context. This is harmless
during normal execution of the virus.
Another option is to hook the interrupts and call another interrupt to
run the virus code indirectly. Below is
the code to the Tequila virus that hooks INT 1.
new_interrupt_one:
push bp
mov bp,sp
cs cmp b[0a],1 ;masm mod. needed
je 0506 ;masm mod. needed
cmp w[bp+4],09b4
ja 050b ;masm mod. needed
push ax
push es
les ax,[bp+2]
cs mov w[09a0],ax ;masm mod. needed
cs mov w[09a2],es ;masm mod. needed
cs mov b[0a],1
pop es
pop ax
and w[bp+6],0feff
pop bp
iret
Normally
the hook routine is set to IRET, as it is without a debugger installed. V2Px uses hooks to decrypt its body with INT
1 and INT 3. The INT 1 and INT 3 vectors
are used continuously during execution of the code and calculations are done in
the interrupt vector table.
Some
viruses also clear the contents of the debug registers (DRn) [9]. This can be done in one of two ways. One way is to use the NtGetContextThread and
NtSetContextThread syscalls. Another way
is to generate an exception, modify the thread context and then resume normal
execution with the new context. An
example of this is below [15].
push
offset handler
push dword ptr fs:[0]
mov fs:[0],esp
xor eax, eax
div eax ;generate exception
pop fs:[0]
add esp, 4
;continue execution
;...
handler:
mov ecx, [esp+0Ch] ;skip div
add dword ptr [ecx+0B8h], 2 ;skip div
mov dword ptr [ecx+04h], 0 ;clean dr0
mov dword ptr [ecx+08h], 0 ;clean dr1
mov dword ptr [ecx+0Ch], 0 ;clean dr2
mov dword ptr [ecx+10h], 0 ;clean dr3
mov dword ptr [ecx+14h], 0 ;clean dr6
mov dword ptr [ecx+18h], 0 ;clean dr7
xor eax, eax
ret
The first line of the above example pushes the offset
of the handler onto the stack to make sure that its own handler will get
control when the exception is thrown.
Then setup is done in for control to transfer to the handler, including
setting eax to zero by XORing it with itself.
The div eax instruction
generates and exception because eax is zero, so AX is being divided by
zero. The handler then skips the divide
instruction, cleans dr0-dr7, sets eax to zero again, indicating that the
exception was handled, and execution is resumed.
3.9
Detaching the debugger thread
Detaching the
thread from the debugger can be done with the NtSetInformationThread syscall. Calling this function with
ThreadInformationClass set to 0x11 (ThreadHideFromDebugger), will detach the
program’s thread from the debugger if there is a debugger present. The
following code is an example [15]:
push 0
push 0
push 11h ;ThreadHideFromDebugger
push -2
call NtSetInformationThread
In this example, the parameters
for the NtSetInformationThread are first pushed onto the stack and then the
function is called removing the program’s thread from the debugger. This is done because 0 is passed in for the
thread information length and thread information, -2 is passed on for the
thread handle, and 11h is passed in for the thread information class which is
the ThreadHideFromDebugger value.
3.10
Decryption
Decryption
can be done in several different ways that also protect against debugging. Some decryption depends upon a specific
execution path. If this execution path
is not followed, due to a debugger being started at a specific point in the
program, the value that the decryption algorithm uses may be incorrect. Therefore, the program will not decrypt
itself correctly. HDSpoof uses this
technique [7].
Some viruses use the stack to decrypt their
code. Using a debugger on such a virus
causes the decryption to fail, because the stack is used by INT 1 during
debugging. One example is the W95/SK
virus that decrypts and builds its code on the stack. Another example of this is the Cascade virus
that uses the stack pointer register for one of the decryption keys. Below is the code:
lea si, Start
; position to decrypt
mov sp, 0682
; length of encrypted body
Decrypt:
xor [si], si
; decryption key/counter 1
xor [si], sp
; decryption key/counter 2
inc si ;
increment one counter
dec sp ;
decrement the other
jnz Decrypt
; loop until all bytes are decrypted
Start: ; Virus body
The comments on the above example explain fairly well
how the Cascade virus uses the stack pointer to decrypt the virus body. The Cryptor virus, on the other hand, stores
its encryption keys in the keyboard buffer, which is also destroyed by a
debugger. Tequila uses the decryptor’s
code as the decryption key, so if the decryptor is modified with a debugger the
virus will not be decrypted [9]. Below
is the Tequila decryption code [13]:
perform_encryption_decryption:
mov bx,0
mov si,0960
mov cx,0960
mov dl,b[si]
xor b[bx],dl
inc si
inc bx
cmp si,09a0
jb 0a61 ;masm mod. needed
mov si,0960
loop 0a52 ;masm mod. needed
ret
the_file_decrypting_routine:
push cs
pop ds
mov bx,4
mov si,0964
mov cx,0960
mov dl,b[si]
add b[bx],dl
inc si
inc bx
cmp si,09a4
jb 0a7e ;masm mod. needed
mov si,0964
loop 0a6f ;masm mod. needed
jmp 0390 ;masm mod. needed
Research
is being done on new anti-debugging methods that may be used in the
future. One such project works on a
multiprocessor computer in which one processor is unused while debugging. This new technique uses parallel processing
of the decryption code [11].
4. Other Anti-detection Techniques
4.1 Retroviruses
Retroviruses try to disable the anti-virus
software. They do this by carrying a
list of process names and killing the processes the program finds running. Many retroviruses also take the process off
of the startup list so the process no longer starts when the computer boots. This type of malware may also try to starve
the anti-virus software of CPU time or prevent the anti-virus software from
connecting to the company’s servers to update its database [1].
5. Combining Techniques
The W32.Gobi
virus is a polymorphic retrovirus that uses EPO and several anti-debugging
techniques. This virus opens a backdoor
on TCP port 666 [8]
Simile
(also known as Metaphor) is a very well known and complex virus that is
approximately 14,000 lines of assembly [9].
This virus uses EPO by looking for the ExitProcess() API call. It is also a metamorphic virus that uses
polymorphic decryption [1]. About 90% of
its code is spent on the polymorphic decryption. The virus body and polymorphic decryptor are
placed in a semi-random place in a newly infected file each time. The first payload of Simile only activates
during March, June, September or December.
Variants A and B display their message on the 17th of these
months. Variant C displays its message
on the 18th. The second
payload activates on the 14th of May in variants A and B and on the
14th of July in variant C [9].
Ganda
is a retrovirus that uses EPO. It
examines the list of startup processes and replaces the first instruction of
each startup process with a return. This
renders any antivirus programs useless [1].
6. Conclusion
References
1.
Aycock, John.
Computer Viruses and Malware. New York,
NY: Springer, 2006.
2.
Bellard,
Fabrice. “QEMU, a Fast and Portable Dynamic Translator.“
2005 USENIX Annual
Technical Conference, pp. 41-46, 2005
<http://www.usenix.org/event/usenix05/tech/freenix/full_papers/bellard/bellard_html/>.
3.
Cesare,
Silvo. “Linux anti-debugging techniques
(fooling the debugger)”. January
1999. <http://vx.netlux.org/lib/vsc04.html>.
4.
Desnoyers, Mathieu, Michel R. Dagenais. “The
LTTng tracer: A low impact performance and behavior monitor for GNU/Linux” Ottawa Linux Symposium, 2006. <http://www.kernel.org/doc/ols/2006/ols2006v1-pages-209-224.pdf>.
5.
Detecting Complex Viruses.
Ferrie, Peter, Frederic Perriot. Security Focus.
25 January 2007. <http://www.securityfocus.com/infocus/1813>.
6.
Exploring
RDA. .aware eZine Alpha - Overground
Hacking. 6 December 2007. <http://www.awarenetwork.org/etc/alpha/?x=3>.
7.
Reversing HDSpoof
- A Tutorial. 8 February 2007. < http://www.openrce.org/articles/full_view/14
>.
8.
Symantec
Corp. 24 January 2007 <http://www.symantec.com/index.htm>.
9.
Szor, Peter. The
Art of Computer Virus Research and Defense.
Maryland: Addison-Phoenix BookTech, 2005.
10. Ször,
Péter. “Tricky Relocations.” Virus
Bulletin, 2001.
11.
Torrubia, Andres,
Francisco J. Mora. “Information Security in Multiprocessor Systems
Based on the X86 Architecture.” Computers & Security Vol.19, No.6,
pp.559-563, 2000.
12.
Vasudevan, Amit,
Ramesh Yerraballi, "Stealth Breakpoints," acsac,
pp. 381-392,
21st Annual Computer Security Applications Conference (ACSAC'05),
2005. <http://doi.ieeecomputersociety.org/10.1109/CSAC.2005.52>.
13.
Virus Source Code Database :: VSCDB. 25
March 2007.
<http://www.totallygeek.com/vscdb/index.php>.
14.
VX Heavens. 7 February 2007. <http://vx.netlux.org/>.
15. Windows Anti-Debug Reference. Nicolas Falliere.
Security Focus. 27 September 2007 <http://www.securityfocus.com/infocus/1893>.
|