Protection Engineering

Selective Code Virtualization: Protect Critical Logic Without Sacrificing Performance

A measurement-driven method for choosing which functions to virtualize, defining safe boundaries, and balancing protection strength against latency, throughput, and compatibility.

KeeProtect Team 6 min read

Protect the decision, not the workload

The first instinct in a VM-protection project is often to virtualize as much code as possible. That usually produces the wrong balance. Virtualization raises the cost of reverse engineering by translating selected native instructions into custom bytecode, but the interpreter adds execution work that the original native path did not have.

Oreans explicitly recommends avoiding VM macros around functions called many times per second, tight loops, and latency-critical code. VMProtect likewise describes virtualization as slower than native execution and recommends applying the strongest modes where speed is not critical.

The practical conclusion is simple: selection matters more than coverage.

Start with an asset map

List the code paths that carry proprietary value or enforce a commercial decision. Typical candidates include:

• License and entitlement decisions.

• Decryption-key derivation and protected resource access.

• Proprietary scoring, optimization, or transformation algorithms.

• Integrity verdicts and anti-tamper response logic.

• Premium-feature gates.

• Protocol or file-format logic that differentiates the product.

Then distinguish between a sensitive decision and the surrounding workload. A media application may have a valuable codec policy, but virtualizing the inner pixel loop would be expensive. A better boundary may protect the algorithm-selection logic, secret-derived tables, or authorization step while leaving bulk processing native.

Measure before choosing a protection mode

Use an unprotected release build as the baseline. For every candidate function, record:

1. Invocation frequency.

2. Inclusive and exclusive CPU time.

3. Typical and worst-case input sizes.

4. Allocation and memory-access behavior.

5. Exception, thread, and callback behavior.

6. Dependencies on compiler-generated code or runtime metadata.

A function that takes only 100 microseconds can still be a poor candidate if it runs hundreds of thousands of times. Conversely, a function that takes several milliseconds once during activation may tolerate a stronger protection mode.

Profile realistic customer workflows rather than a synthetic function call in isolation. Startup, first-run activation, project loading, exports, background services, and automated batch jobs can expose different bottlenecks.

Shrink the protected region

If a sensitive function contains a hot loop, move the loop outside the VM boundary when the security model permits it. Keep the compact part that chooses parameters, validates a trusted result, or derives a protected state inside the virtualized region.

This creates a useful pattern:

• Native code handles parsing, I/O, and bulk computation.

• A small virtualized core makes the security-sensitive decision.

• Native code consumes a narrow result.

• Integrity checks make simple patching less reliable.

The boundary should not expose a single obvious boolean that can be patched without consequence. Consider deriving an internal capability value, validating it at more than one use site, or making the result necessary for later computation. These measures should remain maintainable and testable; accidental complexity can hurt legitimate users more than attackers.

Use different strengths deliberately

Not every protected region requires the heaviest mode. VMProtect documents mutation, virtualization, and a combined Ultra mode. Oreans documents multiple VM architectures with different speed characteristics. Regardless of product terminology, establish internal tiers such as:

• Tier 1: lightweight transformation for broader low-risk checks.

• Tier 2: standard virtualization for important decision logic.

• Tier 3: strongest available VM configuration for small crown-jewel regions.

Document why each function is assigned to a tier. A future maintainer should be able to tell whether a setting is intentional or historical.

VM diversity also has a cost. Oreans notes that adding many unused or unnecessary virtual machines can increase disk and memory footprint. Diversity is valuable when it makes analysis less reusable, but it should be allocated to meaningful boundaries rather than maximized as a checkbox exercise.

Build a repeatable performance gate

For each protected release, compare protected and unprotected artifacts under the same conditions. Track:

• Cold and warm startup time.

• P50, P95, and P99 latency for affected workflows.

• Throughput for batch operations.

• CPU and peak working set.

• Binary size and load time.

• Crash, exception, and timeout rates.

Set a budget before protection is enabled. For example, a one-time activation path may accept more latency than an interactive command. If the budget is exceeded, first reduce the protected boundary, then choose a lighter VM mode, and only then consider removing virtualization.

Always test supported architectures independently. x86, x64, and ARM64 builds can have different compiler output, calling conventions, and performance profiles. The same source-level marker is not evidence of the same runtime cost.

A practical review checklist

Before approving a virtualized function, ask:

• Does it contain logic that attackers have a reason to study or patch?

• Is the protected boundary smaller than the complete feature?

• Have hot loops, callbacks, and blocking I/O been excluded?

• Is the function covered by correctness and performance tests?

• Is the chosen VM strength proportional to the asset?

• Can the team reproduce the protected build and its benchmark?

• Will support engineers recognize compatibility regressions?

Selective virtualization is not a compromise in protection quality. It is the method that concentrates the strongest transformation where it creates the greatest economic and security value.

Sources

• Oreans performance guidance: https://www.oreans.com/help/cv/hm_faq_we-tried-to-adopt-code-virtual.htm

• Oreans Virtual Machine Settings: https://www.oreans.com/help/cv/hm_virtual-machine.htm

• VMProtect User Manual: https://vmpsoft.com/vmprotect/user-manual/

selective virtualization performance VM protection function selection binary hardening

Comments

0 approved

No approved comments yet.