Anti-Disassembly techniques used by malware (a primer)
There are chances that malware authors implement some kind of trolling so that a malware analyst has a hard time figuring out code during static analysis (IDA Pro ?). Implementing these cunning asm instruction will not cause any issues to the flow of the program but will confuse static analysis tools such as IDA Pro from interpreting the code correctly.
Once upon a time there were 2 kinds of disassembly algorithms -Linear disassembly and flow-oriented disassembly.The former
was used in tutorials/ nobody gives a damn is not used that much in disassemblers.
What we are concerned about is the latter which is used in IDA Pro and sometime gamed by malware authors-
1.Jump Instructions to a location with constant value
This is the most used trick by malware writers/anti-disassembly programs which create jumps into the same location + 1 or 2 bytes. It would lead to interpretation of completely different byte code by the system.
For instance the actual jump instance here would take the flow of program to the bytecode mentioned above.
Since tools like IDA pro are not that clever(no offense to the creator) it cannot make such judgements and instead interprets the opcode from E8 instead which shows us a bunch of call instructions to some random crappy address, weird decrements and adds.
No we can fix this with ease in IDA PRO. Do that by pressing D on the E8 and C key on the 8B Opcode and voila! you get what is actually being interpreted.
After playing around more with the C & D key you get the following in IDA which seems legit :P
Now what has happened here is that the the author might have inserted something known as a rogue byte which confuses IDA pro leading to a wrong interpretation of the rest of the opcode.This is a simple technique and if you dont like to see that ugly E8 byte you could NOP it out :)
2.Jump Instructions to the Same target
IDA Pro usually follows this behavior where for a conditional instruction (jnz) it first disassembles the false branch of the conditional instruction and then moves forward to the true part.
From a malware POV since both the jz and jnz are present it is similar to an unconditional jump
Once IDA pro reaches the jz instruction it would first branch out and interpret the false instruction and move on to jnz where it would do the same.A nice and dirty trick is to insert a rogue byte code and make the disassembler interpret the instructions as a call.
If we do the C & D thingy in IDA pro as mentioned in 1. we get the following code
I have no idea what this technique is named as but it involves doing a lot of jumping around using the method mentioned in 1. and maybe even a bit of 2
Let's look at this innocent jump below.
This jumps goes back to loc_4012E6+2 which would be the EB opcode. If we ignore the 66 and B8 opcode ,make IDA interpret the rest as code instead we get the following
Yay more jumps.
Once again ignoring the other E8 byte and considering the rest as code the result is as follows-
We can see how incorporating rogue bytes obscures the real function call from being hidden in static analysis.
4.Usage of Function Pointers
Instead of a screen shot here is a piece of code
mov [ebp+var8],offset sub4211C1
What happens above is that a function is called via use of a reference to an address. For example for the function call it would get the funciton stringname by the use of some weird bunch of decoding subroutine and save the value in an offset sub4211C1. This would make static analysis really hard since IDA won't recognize it easily.
From a static analysis point of view though it dosen't seem to cause massive harm this coupled with other anti-disassembly techniques can lead to annoyance for an analyst.
There are a couple more annoying techniques which I will explore in another post such as abusing the return pointer (for fun and profit:P ) ,using your own Structed Exception Handler (SEH) and screwing around with the stack-frame construction in IDA pro.