Reviewing a recovered
VMProtect result in IDA
A recovered VMProtect result in IDA is an IDA database (.i64) in which the functions VMProtect had virtualized appear as functions you can follow again. Each one carries a proof state from the coverage ledger, and the four states tell you how far to trust what you read.
This guide explains what a Devirt database contains and a review order that keeps evidence and interpretation apart. It assumes you already use IDA, and it describes your own review of a file you are authorized to analyze.
What is in a recovered VMProtect IDA database?
A recovered VMProtect IDA database is an .i64 file that contains the proven functions, semantic names, resolved imports, typed API calls, comments and the coverage ledger for the agreed scope. Devirt saves and reopens every IDA database as part of its output audit before release.
| Part | What it is |
|---|---|
| Proven functions | Recovered functions that passed their checks within the stated assumptions. |
| Semantic names | Names the analysis gave recovered functions, so the database reads by purpose. |
| Resolved imports | The external functions the program calls, named in the database. |
| Typed API calls | Calls to those imports with their types applied, so arguments read correctly. |
| Comments | Notes added by the analysis beside the recovered code. |
| Coverage ledger | Every protected function in scope and the proof state it reached. |
Named functions and typed calls stay linked to the coverage and verification record, so a name in the database points back to the evidence behind it.

Before you open it: version, scope and the ledger
Check three things before opening a recovered VMProtect database. First, the tool version: Devirt lists the tool versions with the artifacts, and a newer database is not promised to open in an older IDA. Second, the scope: the ledger names the functions it covers, so confirm that the ones your question depends on are inside it.
Third, the download window. A released result stays available for 72 hours by default, or 30 days on the Team plan, and each signed download link lasts up to 24 hours. Save the database and the ledger in your own evidence store as soon as you download them.
Where should you start reviewing?
Start reviewing a recovered VMProtect result in IDA with the coverage ledger, not the pseudocode. The ledger places every function in scope in one of four states: proven, runtime-dependent, unresolved or permanently bounded. Find the functions your question depends on, confirm which state each one is in, and read the proven ones first.

Readable code that is not proven is a lead, not a finding. The article on how to read a devirtualization coverage figure walks through the ledger arithmetic in detail.
How do you read a proven function?
A proven function in a VMProtect result passed its checks within the stated model and assumptions. Read it in IDA's decompiler view like any other function: the semantic name gives you its purpose, the typed calls give you its arguments, and the comments add the analysis notes.
Then check the assumptions. A proof says the recovered code cannot disagree with the original under the declared model. It does not cover inputs or environments outside that model, so note the scope before you quote the function in a report.
How do you check imports and API calls?
The resolved imports in a recovered VMProtect database name the external functions the program calls, and the typed API calls apply their types at each call site. Together they are often the fastest route to what a program does: file access, network calls, registry work and other system services usually go through imports.
Use IDA's Imports view and cross-references to list the recovered functions that call each API you care about. Then check the proof state of each caller in the ledger before you build a conclusion on it.
How do recovered functions connect to native code?
A VMProtect file can mix three kinds of protected code with ordinary native code. Virtualization turns instructions into bytecode for a virtual machine, mutation replaces instructions with equivalent but more complex sequences, and Ultra mutates code and then virtualizes it.
Devirtualization reconnects virtual operations, branches and native exits into functions you can follow. In the database, follow cross-references out of a recovered function into the native code it calls, and back from native code into the recovered functions that call it. Mutated code is still native instructions, so read it in IDA as native code. The guide to VMProtect unpacking versus devirtualization explains why an unpacked file still hides its virtualized functions.
What do names and comments tell you, and what don't they?
The names and comments in a recovered VMProtect database come from the analysis, not from the original developer. They make the code easier to read and point you to what a function appears to do.
They are not evidence on their own. Readable output shows what a function appears to do, while proof shows that the recovered code cannot disagree with the original under a stated model. Treat a name on an unproven function as a hypothesis to test.
How do you handle runtime-dependent and unresolved functions?
Runtime-dependent and unresolved functions stay in a VMProtect result, and each needs a different next step:
- Runtime-dependent: a real input or environment is needed to settle the behavior. Supply that input in your own dynamic analysis, or ask for a wider engagement.
- Unresolved: the function was inspected and the evidence did not settle it. Treat its code as unverified.
- Permanently bounded: the function sits outside an explicit analysis limit, so the result makes no claim about it.
The article on runtime-dependent, unresolved and bounded functions explains each state in depth.
Why does the original source not come back?
Devirtualizing a VMProtect file does not return its original source code. Compilation discards names, comments and project structure, and VMProtect's protection removes more on top of that.
A recovered IDA database is a new description of the program's logic, tied to the evidence for each function. If you need to explain the result to people who do not use IDA, the annotated pseudocode or the full report presents the same recovery in another form.
Keeping the result after the download window
A recovered VMProtect result is yours to keep once you have downloaded it. Store the database with its ledger and proof summary, because the ledger is what lets you defend a conclusion later.
If your work runs through scripts or agents, the API JSON output carries the same coverage ledger and proof counts for your own pipeline. The reverse engineering MCP guide shows how an agent can read result status and coverage, and the checks to make before you pay are in how to evaluate a devirtualization result before paying.
The VMProtect research hub covers how the protector works, and VMProtect devirtualization covers what Devirt delivers and how to start.