More Bypassing of Malware Anti-Analysis Techniques
For last few articles, we have seen how malware employs some anti-analysis techniques and how we can bypass those techniques. Now, let's raise the bar a bit more and look out for more advanced anti-analysis techniques.
In this article, we will look at how we can reach the Original Entry Point of a packed Exe and then how malware can trick to override Structured Exception Handler(SEH).
Let's start.
We have a malware specimen (named sample.exe), and on loading to ExeInfo, it looks to be packed. I have intentionally hide the packer name because it would be great to treat this packer as a custom one and then analyze the malware.
Note the Entry Point is 28E8.
Also, we start debugging it, let's make sure that the ASLR is not checked to avoid issues related to dynamic loading later. Looking at the DLL characteristics, we can see that this DLL cannot move.
Now loading this sample inside OllyDBG, it presents us with a warning that the code can be compressed which is what we have seen earlier.
As soon as the sample is loaded into the OllyDBG, it will start working in the Unpacker code but manually stepping through this code will take so much time and we might miss the OEP. Let's analyze few lines of code where we have landed.
There are some references to FS[0] which points to SHE structures. Are we dealing with Exception handlers here? Let's find out. Before we move further, it is important to know how Windows locates the address of FS register. FS register points to Thread Information Block(TIB) which contains information about current running thread and pointer to the start of SHE chain resides in TIB at offset 0x00.
Now, let's look the Structure exception handler
Single SEH record consists of two elements on the stack, and this process is known as _Exception_Registration. Those two elements which form an SEH record are:
- SEH Handler Function
- PTR to next SEH record
Thus, it forms an SEH chain structure.
Now with the above understanding, let's see what code is doing. As soon as the code is loaded, it is copying 519870 to EAX and pushing it to the top of Stack.
We can look at the top of the stack for this push with ESP pointing to 14FF80.
As per above explanation of SEH, this is the handler function code, but it still needs to be pointed out by FS[0] which is done by the next line of code PUSH DWORD PTR FS:[0]. This will push the pointer to the start of SEH chain to the top of the stack, and it will complete the SEH record. Current state of registers at this point is like below
The with statement MOV DWORD PTR FS:[0], ESP ; code is designating the newly created record to the top of SEH chain by moving ESP(which points to the top of record) to FS: [0]. After executing this statement, we can see stack states that two elements of the SEH record.
We can also in VEH/SEH chain that a new record is created.
However, the specimen code should execute this SEH handler code. We do not have to go too far to figure that out since the next line of code XOR EAX, EAX which puts 0 into EAX
and then it is trying to write it to a read-only location which causes an exception. The first handler catches this exception, and then unpacker code is executed.
Moreover, on execution of the last statement in snipped, it will jump to 519870(remember this is the address of that we put into EAX register earlier and is the SEH handler function part of the SEH record)
Wow, what an intelligent technique employed to conceal the unpacker code but our job is not finished yet as we still need to find the OEP, extract the unpacked code from the binary and the rebuild it which is tricky.
I will try to bring experience in here by looking for some common patterns which packers usually use just before unpacking the code. One is to look for the patterns in the unpacker code for a jump of EAX which is usually a jump to the unpacked code. Also, packers usually clean up the stack before unpacking code, so we should look out in that order:
Cleaning up of the stack -> followed by a JMP EAX.
Once we are in 519870(SEH handler code) we can either step through each instruction or we can setup a breakpoint along the creation of the SEH record. Let's follow the 2nd approach
We know that when SEH is created onto the system and since we are on the heuristics that it will clean up the stack, let's put a breakpoint on the top of the stack when the structure is created.
And then running the specimen, it takes us to below code section
This matched with the patters that we were looking for. Let's execute JMP eax and then see where this code will take us:
See how the code 28E8 now looks more clean and unpacked. Let's dump this code
We still need to check whether this dumped code will execute or not. Before we execute it, let build the Import Address table
Now since the file is ready let's analyze whether the exe is running or not in Process Hacker. As soon the exe is launched, it gives an error
Interesting thing is that it was just to deviate people from concern by throwing an error message because even after clicking ok, we can see in the process hacker the process is running and spawns a process
So, this is all about this technique in how malicious author can pack the code and thwart the analysis.