VX Heaven

Library Collection Sources Engines Constructors Simulators Utilities Links Forum

Anti Virus Detection Strategies and how to overcome them

Tiberio Degano
Decepticons #1
December 2009

[Back to index] [Comments]

1. Introduction

Hi everyone I'm Tiberio Degano. This article will talk about Avers Techniques which they use to detect your virus.

Many Viruses have been written with many features polymorphic, epo and maybe metamorphic and become an easy task for Avers to detect it. Some virus writers create new ideas and spend most of their time and brain try to make it real and these ideas never harden their virus against avers. Do you know why? Because they don't understand Antivirus very well and they don't understand Anti Virus Detection Strategies that's what make their virus an easy task for the avers.

This article will talk about Avers in depth. How they think and what ideas they will use and the most important thing is how to overcome these defenses and put your brain in the straightway.

We will begin from zero to make understand my Thinking and my brain. To make you create a plan against Avers techniques and strategies and to bypass their defenses and at least create the most complex virus ever seen.

This Article is from my little knowledge. It could contain some missed parts or some bad analyzing. If you see any problem please mail me fast. I'm waiting for your feedback.

2. Wildcards

Let's begin the journey in the avers' brains. We will now begin with wildcards. Wildcards is one of the most famous detection techniques and there's many antivirus companies based only on it and I think one of them is ClamAV. ClamAV is based on pattern to search for it and it include some code for detecting some famous polymorphic engines.

Overcome Wildcards

You can easily overcome wildcards and bypass it by any obfuscated polymorphic engine like MtE or Marburg.

We will not talk many about wildcards let's jump to the next.

3. Emulation

Emulation is the most powerful technique ever in Antivirus technology. You can say without emula on the An virus will never detect most of 29A viruses and will not detect any complex virus ever.

Many anti-emulation tricks appeared and no one of them stop emulation forever. Most of them delay the antivirus for their viruses for a while (only if there is a new trick) and nothing more than that. That's why I don't prefer anti-emulation tricks like SEH or anything like that.

I think the EPO is the only way to stop emulation forever. Emulation needs an entrypoint to begin and EPO is based on hiding this thing from the emulator to make it impossible to emulate.

I describe some ideas in EPO field I hope you read them in "Easy to Infect Hard to Detect" so I'll not go into the details here I will jump into the next topic.

4. Dynamic Analysis VS Static Analysis

What's the Analyzer? Many people don't ask this question even it's the most important question you should ask to understand how Antivirus work. I think the bad understanding of the detection techniques comes from here. Many people think that the emulator or any analyzer can do a magic to detect your virus and most of ideas against Analyzers is how to make them away from our virus.

Analyzer is an automated tool try to extract the functionality of the code – or your virus – regardless of the shape of the instructions that the virus written by them. The concept make the analyzer like a ghost and can't be bypassed even it's just a computer not a brain and could be bypassed.

Dynamic Analysis is simply run a program in a virtual machine and traces its functionality. Understand the functionality is by monitoring any memory changes and tracing the registers' values to understand the behavior of the code:

        cmp     eax,edx         ;eax-->'ZM' edx-->'ZM'
        cmp     ebx,ecx         ;ebx-->'EP' ecx-->'EP'

As you can see the emulator can easily detect that you want to test the beginning of an exe file. Maybe the infected file or maybe searching for the kernel base or something like that:

        mov     [00401560],20h
        add     [00401560],11h  ;in [00401560]-->31 -->'1'

Here also the emulator will monitor the Memory changes and detect what you want to write. That's the way that emulator detect your virus. It's not a magic it's a normal technique and could be bypassed by a creative brain.

In my virus Skipo I don't face these problems (and I'll tell you why) so I'm not the creative brain that you search for but I can tell you something:

If you could change the source and the destination of everything the emulator will face a big problem against you like that

        xor     eax,056h
        xor     edx,056h
        cmp     eax,edx         ;eax-->'ZM'Xored by 56h edx-->'ZM'Xored by 56h

At this time when the emulator stop at cmp eax,edx it will not see cmp ZM and will not detect your behavior.

And as I said before the emulator is not a brain. It only scans the code while running searching for patterns of malicious behavior or famous patterns in your virus. If it found them in the same order (that can't be permutated) it will say that a virus and if not it will pass your virus as a normal file.

These patterns could be memory patterns (data in memory) or could be instructions with specific values in the registers used or memory variables in the instruction.

Is there a way to bypass this technique? Surely yes but need a good understanding and a creative brain to bypass it.

Most of virus writers bypass the whole emulation by a trick (like EPO) and avoid this painful challenge against the dynamic analysis and one of them is me in my virus Skipo. So what will they do? They will jump into the Static Analysis.

So what's the Static Analysis? This is the topic that I write the whole article for it. Many virus writers didn't jump into finding tricks to bypass static analysis even it's not widely used. Yeah it's not widely used but in complex virus like zmist this idea could be used and something like SK or enfish this idea also will be used.

Static Analysis contain two types the First is code Disassembling and the second is Static Analysis for Executables (as the article of it was written with the same name). We will explain each one and tricks to overcome them in the next two parts.

4.1 Static Analysis for Executables

This type you can simply name it "Tracing the Registers Behavior". This Analysis work by trace the registers and search for a register that should be in the decryptor the counter or the pointer and test if there are all the decryptor's registers' behavior. If there are so this code is decrypting the virus so we should emulate this code and test if the virus appeared in the memory. If not so the file is not infected.

        mov     edi,0040XXXX    ;put a pointer in edi
        xxx                     ;code
        mov     eax,[edi]       ;read from edi
        mov     [edi],eax       ;write in edi
        add     edi,4           ;add 4 in edi

As you can see in this code the analyzer trace what happen to edi and try to detect if it work as a register in the decryptor. If it see code on another register do like the counter and so on (surely without any modification in junk code) it will detect that's the counter.

This technique has two problems. The first problem is the performance. It's very slow so I think negative pattern comes in handy for it. The second problem is it is based on the registers behavior so any play with the registers will make this idea useless. So we will build our ideas on these problems to overcome this technique. Let's start the first.

4.1.1. Dynamic Register Swapping

As we say in the beginning any play with the registers will make it useless and that's it. I think this is the first new idea (really new) in the article. This technique is simply swapping the registers in the middle of the code like that:

        xchg    eax,ecx

This code will swap the registers in the middle of the decryptor code. The values will be exchanged and the eax will have the value if ecx and will act as the counter in the next instructions of the decryptor. Don't forget that before the loop jump you should swap the registers again and again until reach the initial registers that you begin the loop with them.

That's also another shape:

        mov     eax,ecx
        ;eax-->counter or ecx-->counter

This shape will make the value of eax deleted but you will have two registers have the same value and also can any one of them act like the counter. Who will detect what you choose as a counter? No reply.

There's the fake dynamic register swapping it's simply write mov exx,exx without real swapping and if ecx is the counter it will continue the counter like nothing happen. This trick will force the analyzer to detect if there's a real swapping or fake and if it can't detect it should brute force. This idea will become useless against this small trick.

For better explain read this code carefully and try to detect what's happen?

        mov     ecx,Virus_size          ;ECX-->counter
        mov     edi,Virus_Place         ;edi-->virus pointer
        mov     edx,edi                 ;register swapping
        mov     eax,dword ptr [edx]     ;act like edi
        xor     eax,12345678h
        mov     ebx,edx                 ;fake register swapping
        mov     edi,eax                 ;edi become free to use
        mov     dword ptr[edx],edi      ;edx not ebx because it's fake and edi
                                        ;not eax because there's register swapping

I hope you understand my idea. It's really hard to analyze and hard to detect who is the real and who is the fake.

Now let's jump to the negative pattern. Hey let's go…

4.1.2. Anti-NegativePattern

This trick try to write some code that the polymorphic engine can't write but it could be found in the real program like many APIs calls and so on. This trick can make negative pattern filtering more hard even they will see in the polymeric decryptor all instructions could be found so they can't filter the host code to search for the virus even the virus contain everything.

The idea is simply copy some instructions from the host to the decryptor and put them between if & endif to make them never executed. To make it you should have a disassembler for your virus and that's the steps to use this idea:

  1. search for push ebp/mov ebp,esp
  2. disassemble the code and save the size of every instruction
  3. now begin from a random instruction and take a random number of instructions
  4. write in your decryptor
            xor     eax,eax
            cmp     eax,50                  ;will not happen
            jnz     Size_of_all_instructions


            cmp     ecx,Virus_Size+1000     ;ecx-->counter
            jnz     XXX                     ;ecx will never exceed the virus size
  5. copy the instructions into your decryptor
  6. voilà you now have instructions you can't write and this code will never executed

They will need an analyzer before using negative pattern and that's impossible. Imagine we merge this idea with register swapping I think the static analyzing will become impossible or too hard to use.

Let's jump to the next type of static analyzing.

4.2. Code Disassembling

Code disassembling is faster and better than the previous type. This idea is based on the shape of the instructions and the imm32 that used in the instructions. This idea is searching for interested instructions that could be an instruction of a metamorphic code and the emulator comes in handy in this type of analysis. The benefit of this idea that it doesn't need the entrypoint only any pointer in the middle so it could be used a key validation for XRay.

This trick can deobfuscate a weak polymorphic or a metamorphic code but I think it's very weak against highly-obfuscated polymorphic code.

So overcoming this trick could be done by a multi-layer poly that you can't XRay the whole layers in the same time (like all layers use xor so the XRay will make all of them as one layer).

This trick is used (as I think) in Zmist as the encryption algorithm of Zmist is just a sliding key and the code is metamorphic under this layer. So the detection will be with XRay with code disassembling as a key validation and we will become away from this polymorphic engine and this code integration technique.

We will now talk about the last detection technique XRAY.


I think XRay is very famous and it doesn't need any describe so I'll jump into its weaknesses directly. The first problem is the performance of XRay. I think it's the last choice for any Aver to use because of performance and you can see the performance of XRay is based on the luck. As they build their detection algorithm on the worst case so XRay in most cases is a painful choice.

You can avoid it by using a multi-layer multi-algorithm polymorphic engine with different keys (sliding key is preferred and don't use xor in the slide key) or also you can use this new idea as a new key for you. I think it's impossible to be Xrayed especially with multi-algorithm decryptor. Its name is Host Key.

5.1. Host Key

Host key is a simple key and easy to use away from using a hardcoded algorithm that become so hard to be obfuscated by your polymorphic engine. This idea is simply taking a part from the host equal to the size of your virus as a key to encrypt your virus. Analyze this decryptor carefully to understand my idea.

        ;Virus_Place-->pointer to the place of the virus
        ;host_Place--->pointer to a place in the host its size==virus_size
        mov     ecx,Virus_size          ;ECX-->the size of virus
        mov     eax,dword ptr [ecx+Virus_Place]
        mov     ebx,dword ptr [ecx+host_Place]
        xor     eax,ebx                 ;we encrypt the virus by a place in the host
        mov     dword ptr[ecx+Virus_Place],eax

This trick could be used without any limits if you make the virus run at the beginning of the application (before the host) but if you use an EPO you should take a read-only part from the host equal to the size of the virus and all decryptor except the first (if you use a multi-layer poly).

The second restriction you will face is you should take the whole place in the same section in the host. If you see two read-only sections don't use them as the host place because the virtual size of every section is different from the size of raw data. When they mapped in the memory (as a process) you will see there's new bytes added to each section at the end make the decryption key different from the encryption key. The last restriction in this idea is the multi-infection will become impossible if you don't add your virus at the end.

If XRay failed how they will think. I think they will use decryptor parsing and that's the next.

6. Decryptor Parsing

Decryptor parsing is a helpful tool for xray. It search for the decryptor and try to get the pointers and the important data from your decryptor. Any much explain I don't have but I think you could name it a simple static analyzer try only to get the pointers and the keys.

Highly obfuscated code could defeat Decryptor parsing. Decryptor parsing can get some pointers or some imm32 but can't analyze the code and that's we will build our next idea.

6.1. Switching Branches

This idea is a huge idea. It's very powerful against any type of analysis, decryptor parsing and xray. This idea can only be used with a multi-algorithm poly with huge size for the decryptor.

Imagine if we have 4 algorithms in our decryptor. We will not make them run every me but we will make some switches before each algorithm make it ON/OFF or work/not work. These switches will be cmp/jcc and the switch will be based on (mainly) the counter. When the switch become ON the algorithm will run and when become off the jcc will jump to the next algorithm.

All of these switches will be written in the encryptor so will make all the algorithms the same type (like all of them xor or add) but you can use sliding keys or host keys. This restriction is for not writing the algorithms in the encryptor from the last to the first. If you are using the same algorithm you can order them in the encryptor exactly like the decryptor and that's will be easier to write in the encryptor.

This Idea can bypass the decryptor parsing because the decryptor parsing can get some pointers or imm32 but it can't get the switches because it needs a good analyzer to get them. Also the xray will become impossible because it can brute force the key but can't predict the switches that used. Also it need a great analyzer to understand that that's a loop not some if/endif or switches. But this idea also is hard to write and hard to obfuscate need a great programmer and much time to convert it into real.

Now let's take an example. I will give you an example of a normal decryptor with multi-algorithm and how we will convert it into switching branches:

        xor     ecx,ecx
        ;the first algorithm Xor eax,50000
        mov     eax,dword ptr [ecx+Virus_place]
        xor     eax,50000
        mov     dword ptr [ecx+Virus_place],eax
        ;the second algorithm Xor eax,ebx (host key)
        mov     eax,dword ptr [ecx+Virus_place]
        mov     ebx,dword ptr [ecx+host_place]
        xor     eax,ebx
        mov     dword ptr [ecx+Virus_place],eax
        ;the third algorithm Xor eax,70000
        mov     eax,dword ptr [ecx+Virus_place]
        xor     eax,70000
        mov     dword ptr [ecx+Virus_place],eax
        add     ecx,4
        cmp     ecx,Virus_Size
        jb      _@1

Let's see the switching branches:

        xor     ecx,ecx
        ;the first algorithm Xor eax,50000
        ;the first switch ecx/2=1 (last bit=1)
        test    ecx,1
        jz      _@2             ;oFF
        mov     eax,dword ptr [ecx+Virus_place]
        xor     eax,50000
        mov     dword ptr [ecx+Virus_place],eax
        ;the second algorithm Xor eax,ebx (host key)
        ;the secnd switch ecx/8=1 (last 3 bit=100)
        test    ecx,100
        jz      _@3             ;oFF
        mov     eax,dword ptr [ecx+Virus_place]
        mov     ebx,dword ptr [ecx+host_place]
        xor     eax,ebx
        mov     dword ptr [ecx+Virus_place],eax
        ;the third algorithm Xor eax,70000
        ;the secnd switch ecx != 50
        cmp     ecx,50
        jz      _@1             ;oFF
        mov     eax,dword ptr [ecx+Virus_place]
        xor     eax,70000
        mov     dword ptr [ecx+Virus_place],eax
        add     ecx,4
        cmp     ecx,Virus_Size
        jb      _@1

I hope this example make you understand my idea. I hope to see a virus writer use this idea.

7. What we should do?

At the end I shall say we should make ourselves like an aver and try to predict how the aver will write a detection algorithm and how he will think and finding ways to bypass the detection that we predict.

In my little point of view the Aver will follow these steps in detecting our viruses:

  1. Use wildcards
  2. If it's polymorphic so let's emulate and then wildcards
  3. If it epo let's reverse the epo and then emulate
  4. If it SK epo or Mistfall and simple poly they will jump into decryptor parsing
  5. If it sk epo or Mistfall and highly-obfuscated poly and weak algorithm so Xray is good
  6. If these epos and this poly and the same algorithm but metamorphic under the encryption so they will jump into XRAY and code disassembling with emulator in handy (that's zmist)
  7. If a powerful algorithm like fpu or host key so they will think about static analysis
  8. If dynamic register swapping and anti-negative pattern what will they do???… To be continued.

That's my opinion and this what I want to reach from the beginning of the article and that's why I begin from the first line in virusing. You should make a plan for yourself and have your own point of view very organized like that before jumping on writing any virus that if you want really to bypass the antivirus and write a complex virus.

This point of view that I write is the plan and the first step when writing my second virus win32.skipo I don't know now if it really become complex or not but if it become a very complex virus so my plan is right. But if not (and that's will be sad) try to write your own plan or correct the missed parts in my plan.

I hope you enjoyed. Bye

Tiberio Degano

[Back to index] [Comments]
By accessing, viewing, downloading or otherwise using this content you agree to be bound by the Terms of Use! aka