Analysis of Malware Protected with Themida and VMprotect

HomeMalware Analysis

Analyzing Malware Protected with Themida and VMprotect: Is It Really That Hard?

Malware authors use protectors like Themida and VMProtect in the hope that they will completely prevent analysts from reversing samples.  

These protectors can use sophisticated techniques to hide malicious functionality: code virtualization, obfuscation, anti-debugging, compression, and encryption. (We’ll see later in the article why we said “can.”)  

So, do Themida and VMProtect really always prevent something interesting from being extracted from malicious samples, like C2 servers, strings, or analyzable code? 

To answer that question, we’ll analyze malware samples from different families that use Themida and VMProtect and compare the specific protection mechanisms they use. 

Research results 

Our analysis is quite detailed, so to make it easier to keep up, we’ll take a somewhat unusual approach and start with the results. 

The table below shows our findings for six malware families — all of which use protectors. The table ranks them from least to most difficult to analyze. 

Compressed/
encrypted  
 Virtualization  Obfuscation  Anti-debug What is encrypted in the dump
Strings  С2 
Arkei (VMP)  –  Only 
unpacker 
–  –  – 
RisePro (Themida)  –  Only unpacker  –  – 
RisePro (VMP)  –  Only unpacker  –  – 
PrivateLoader (VMP)  –  Only unpacker  – 
Amadey (Themida)  –  Only unpacker 
Lumma (VMP)  –  Control flow flattening technique  –  –  – 

You may have noticed something interesting — none of the samples use code virtualization. This makes analysis so much easier! Only one sample has anti-debugging enabled. The malware code itself is largely unprotected, except for the initial stages of compression and decryption. And, while almost all samples have encrypted/obfuscated strings, only two obfuscate their C2 servers. 

RisePro

RisePro is a stealer known since 2022 and distributed as Malware-as-a-Service. It’s known to use various protectors — there are samples found with Themida and VMProtect. 


RisePro with Themida

Of all the protection techniques Themida offers, this sample only uses compressed/encrypted sections, junk code, and API wrapping. What’s more, the junk code and API wrapping were only used in the unpacking routine. 

We didn’t encounter any anti-debugging tricks, nor did we notice any code virtualization employed. 

Our first goal is to extract the malware body and see how amenable it is to analysis. For this, we’ll need the x64dbg debugger and a couple of minutes. 

After loading the sample in the debugger and reaching its entry point, we need to set a breakpoint on the loading of any system DLL. 

Next, we’ll let the program run until it hits the breakpoint (press F9), and we can then dump the unpacked sample for further static analysis:

Now that we have the dump, we can assess how amenable it is to analysis. As we’ll see, the code is quite readable. For instance, the following code loads an encrypted string onto the stack and calls a function to decrypt it: 

This code ultimately generates this string: 

However, there is still some obfuscation in play – the encrypted string isn’t stored anywhere, but rather pushed onto the stack using instructions. This raises the question: was this obfuscation done by Themida, or was it present in the sample before packing?   

We’ll answer that a little later. 

We can also try searching the dump for anything interesting. In the example below, using the ImHex hex editor and regular expressions, we manage to find the C2 server. 

RisePro with VMProtect   

Unpacking the VMProtect sample happens similarly. After the first system DLL loads, we dump it and see the same picture — the C2 server right there in the dump, along with quite readable code. 

The code that pushes the same string (“CreateDirect3dd11DeviceFromDXGIDevice”) onto the stack looks very similar to the snippet we saw in the Themida sample. From this, we can conclude that the string protection functionality belongs to RisePro itself, not the protector. 

The VMProtect sample also doesn’t use any code virtualization. 

You may notice that although the C2 servers differ between the two samples, their offsets from the start of the segment are identical, despite the different protectors. The same goes for the code that pushes and decrypts the string — the offsets match. 

Other families 

In addition to RisePro, similar protectors are used by families like PrivateLoader, Amadey, Arkei, and Lumma. In each case, the virtualization functionality is ignored – the protectors are used as simple packers, barely hindering analysis. 

Try all features of ANY.RUN for free
Request a 14-day trial 



Request now


PrivateLoader 

Let’s look at the sample packed with VMProtect

The PrivateLoader sample unpacks in a similar fashion, but unlike RisePro, it doesn’t store the C2 server in the dump. Instead, it uses a simple XOR algorithm (unrelated to the protector) to decrypt it. To obtain the C2, you just need to emulate the code below or step through it with a debugger. 

Arkei 

The Arkei sample is also packed with VMProtect. After unpacking, we get readable code that loads the required functions from libraries: 

We can also find the DDR (Dead Drop Resolver) profiles for C2 server address in the dump among other strings. 

Lumma 

Here’s the Lumma sample we’ll look at. 

Lumma is packed with VMProtect, and unlike the other samples, obfuscation mechanisms are enabled here. 

The unpacked code executes in a loop: 

This appears to be the control flow flattening technique. The function is broken into blocks, each assigned a number. The loop selects which block will execute next on each iteration. 

Meanwhile, the C2 server is present in the dump among other strings: 

Amadey 

This Amadey sample is packed with Themida. 

In Amadey’s case, strings only appear in memory after loading kernel.appcore.dll. Unlike previous samples, anti-debugging mechanisms are enabled here. To reach the kernel.appcore.dll loading stage, you’ll need to use something like TitanHide. 

After that, you can dump it like in all the previous cases. 

Amadey stores base64-encoded strings in encrypted form. Using the strings utility, we can extract them from the dump: 

To obtain the original strings, we need to decrypt them (Amadey uses its own shuffling algorithm) and decode from base64. 

So, what’s the takeaway? 

We’ve looked at samples packed with Themida and VMProtect across many families. Did you notice a trend? Almost all of them skip key features like virtualization. This makes reverse engineering them so much easier! They use protectors like basic packers, and that barely hides the analysis. 

We can say this: the main challenges that make analysis difficult are not the protectors themselves, but rather the string obfuscation and C2 concealment techniques implemented in the malware itself. 

Malware deobfuscation is a whole other complex area that we have previously covered in our blog. This link will take you to an in-depth explanation of common obfuscation techniques, ways to get around them, and real-world examples based on GuLoader. Check it out! 

About ANY.RUN  

ANY.RUN helps more than 400,000 cybersecurity professionals worldwide. Our interactive sandbox simplifies malware analysis of threats that target both Windows and Linux systems. Our threat intelligence products, TI Lookup, Yara Search, and Feeds,help you find IOCs or files to learn more about the threats and respond to incidents faster.  

Advantages of ANY.RUN  

ANY.RUN helps you analyze threats faster while improving detection rates. The platform detects common malware families with YARA and Suricata rules and identifies malware behavior with signatures when detection by family is not possible. 

With ANY.RUN you can: 

  • Detect malware in under 40s. 
  • Record and study all aspects of malware behavior. 
  • Scale as you need. 

Try the full power of ANY.RUN for free 

Request free trial → 

Source: Original Post