devirt.re
Create account
Menu

VMProtect research

VMProtect is a commercial software protector that turns selected functions into bytecode for a virtual machine built into the protected file. Devirt's research on it explains how its three protection methods change a program, what devirtualization can recover from VMProtect 2.x and 3.x files, and where that recovery stops.

4 research tracks · Updated

Research policyDated · Build named · Limits stated

Permission-cleared samples only. No customer binaries are published.

What is VMProtect?

VMProtect is a software protector from VMProtect Software that makes a program's code hard to analyze and modify. The vendor's documentation lists support for x86, x86-64 and ARM64 binaries and .NET assemblies on Windows, Linux, macOS and Android, and the product is sold in Lite, Professional and Ultimate editions.

VMProtect's main protection methods are virtualization, mutation and Ultra, which combines the two. A developer can apply a different method to each part of a program, so a single protected file can mix virtualized functions, mutated functions and ordinary native code.

What is VMProtect used for?

VMProtect is used to protect code its owner does not want read or changed, such as license checks and proprietary logic. It also offers its own licensing system for serial numbers and activation, and watermarks that identify the licensed owner of a leaked copy.

Malware authors use the same protection to slow down analysts. A VMProtect file is neither legitimate nor malicious by default; the protection only shows that someone wanted the code to be hard to read.

How does VMProtect virtualization work?

VMProtect virtualization translates protected code (whole functions, or fragments a developer marks in the source) into bytecode for a virtual machine with its own instruction set, then builds that virtual machine into the protected file. The program needs no extra libraries to run it.

At run time, the virtual machine's interpreter reads the bytecode and carries out each instruction through small routines called handlers. The original instructions are never rebuilt, so a disassembler, a decompiler or a memory dump shows the interpreter and its bytecode instead of the function's logic.

Diagram: VMProtect translates a native function into bytecode for its own virtual machine, whose interpreter runs each instruction through a handler.
VMProtect virtualization translates a function into bytecode for a virtual machine built into the protected file. At run time the interpreter reads each bytecode instruction and a handler carries it out, so the original instructions are never rebuilt.

VMProtect can also protect different parts of one application with different virtual machines, so an analysis may have to account for several virtual machine designs in a single file. Virtualized code runs more slowly than native code, and the vendor recommends virtualizing only code that is not speed-critical.

Virtualization, mutation and Ultra compared

VMProtect applies one of three methods to each protected part of a program.

VMProtect protection methods
MethodWhat VMProtect doesWhat an analyst sees
VirtualizationTranslates the code into bytecode that an embedded virtual machine runsThe interpreter and its bytecode, not the original instructions
MutationReplaces instructions with equivalent sequences and adds junk instructions, dead code and random conditional jumpsNative code with the same behavior, buried in extra instructions
UltraMutates the code, then virtualizes the mutated resultBytecode whose logic was obfuscated before it was virtualized

Packing is a separate option that only hides code until the program starts: VMProtect's packer compresses the file and unpacks it in memory at startup. Virtualized code never returns to native form, which is why unpacking a VMProtect file does not make its virtualized functions readable. The comparison of VMProtect unpacking vs devirtualization sets out what each one fixes.

The remaining options, such as import protection, memory protection, resource protection, debugger detection and detection of virtualized environments like VMware or VirtualBox, change how the file loads and how it reacts to inspection or modification. None of them translates code on its own.

Why do security tools flag VMProtect files?

Security tools flag some VMProtect files because malware authors use the same protection to hide what their code does. MITRE ATT&CK lists several malware families and threat groups that pack their code with VMProtect, and F-Secure added heuristic detection for VMProtect after reports that it was being used to obfuscate malicious software.

A detection on a protected file tells you it is protected, not what it does. Finding out takes analysis of the file itself, which is what Devirt's malware analysis service provides for protected and ordinary samples.

VMProtect research tracks

Each track lists the articles in preparation. Articles publish when the evidence exists, so the list is direction, not a schedule.

Start here: a measured VMProtect result

One permission-cleared sample, every protected function counted before recovery, what was proven and what stayed unresolved.

In preparation

  • What VMProtect devirtualization actually recovers

Versions and internals

How VMProtect 2.x and 3.x differ for analysis, and what each part of the virtual machine means for recovery.

In preparation

  • VMProtect 2.x vs 3.x for reverse engineering
  • VMProtect VM handlers explained
  • VMProtect mutation vs virtualization: what changes for recovery
  • VMProtect import protection and what it hides

Benchmarks and failure cases

Recovery measured across tested versions and protection settings, with the sample set described, and the functions Devirt could not prove.

In preparation

  • VMProtect benchmark: version and profile matrix
  • A failure case: what Devirt could not prove, and why

How we publish VMProtect research.

Every VMProtect article is dated and names the VMProtect build and protection settings it tested. Samples are permission-cleared, never customer files. Protected functions are counted before recovery starts, so the denominator cannot move afterwards, and every result separates proven, runtime-dependent, unresolved and bounded functions. Failures get published too.

The same rules apply across Devirt Research.