VMPilot is an advanced virtual machine software development kit (SDK) implemented in C++. Secure by design, VMPilot is specifically engineered to safeguard your software from reverse engineering. Offering seamless integration and ease of use for your projects, VMPilot sets a new standard for software protection.
Unlike traditional black box solutions, VMPilot is built with transparency in mind. Its inner workings are easily understandable, yet formidable to crack. By incorporating modern cryptography and obfuscation techniques, your software is shielded against potential attacks. Even with the computing power of a supercomputer, breaking VMPilot in parallel becomes a daunting challenge.
#include <vmpilot/sdk.hpp>
template <typename T>
T square(T x) {
VMPilot_Begin(__FUNCTION__);
auto result = x * x;
VMPilot_End(__FUNCTION__);
return result;
}Output:
square:
push rbp
call _Z13VMPilot_BeginPKc ; VMPilot_Begin(__FUNCTION__);
... garbage code ...
... garbage code ...
... garbage code ...
call _Z11VMPilot_EndPKc ; VMPilot_End(__FUNCTION__);
pop rbp
retbinary (ELF / PE / Mach-O)
|
v
Segmentator::segment() -- find VMPilot_Begin/End markers, extract regions
|
v
RegionRefiner::refine/group() -- deduplicate, handle inlining, detect canonical copies
|
v
Serializer::build_units() -- convert to CompilationUnits (single conversion point)
|
+-> Serializer::dump/load() -- round-trip to protobuf + TOML manifest
|
v
CompilationOrchestrator -- parallel compilation via work-stealing thread pool
| CompilerBackend::compile_unit() (pluggable: SimpleBackend, future LLVM)
v
CompilationResult -- bytecodes + diagnostics
| Format | Architecture | Segmentation | Reference Analysis |
|---|---|---|---|
| ELF | x86, x86-64 | Yes | Yes |
| ELF | ARM64 | Yes | Yes |
| PE | x86, x86-64 | Yes | Yes |
| Mach-O | ARM64 | Yes | Yes |
| Component | Location | Purpose |
|---|---|---|
| Segmentator | sdk/include/segmentator/ |
Binary parsing, disassembly, region extraction |
| RegionRefiner | sdk/include/region_refiner/ |
Overlap removal, inline grouping, canonical detection |
| Serializer | sdk/include/serializer/ |
Protobuf serialization with SerializationTraits<T> |
| CompilerBackend | sdk/include/bytecode_compiler/ |
Strategy pattern for pluggable backends |
| ReferenceAnalyzer | sdk/include/reference_analyzer/ |
Data/TLS/GOT/atomic reference detection |
| DiagnosticCollector | common/include/diagnostic_collector.hpp |
Unified thread-safe diagnostics across all stages |
| ThreadPool | common/include/thread_pool.hpp |
Work-stealing pool for parallel compilation |
- CMake 3.20+
- C++17 compiler (GCC 14+, Clang 18+, MSVC 2022+, Apple Clang)
| Library | Purpose |
|---|---|
| nlohmann/json | JSON parsing (runtime config) |
| VMPilot-crypto | Common crypto (AES, SHA-256, BLAKE3) |
| ELFIO | ELF binary parsing |
| COFFI | PE/COFF binary parsing |
| capstone | Multi-arch disassembly |
| protobuf | Serialization wire format |
| spdlog | Logging |
| toml++ | Manifest format |
- Ninja (faster builds)
# Debug build with tests
git submodule update --init --recursive
cmake -B build -DCMAKE_BUILD_TYPE=Debug -DENABLE_TESTS=ON -G Ninja
cmake --build build -j
ctest --test-dir build --output-on-failure
# Release build
git submodule update --init --recursive
cmake -B build -DCMAKE_BUILD_TYPE=Release -G Ninja
cmake --build build -j# Debug build with tests
git submodule update --init --recursive
cmake -B build -G "Visual Studio 17 2022" -A x64 -DENABLE_TESTS=ON
cmake --build build --config Debug -j
ctest --test-dir build -C Debug --output-on-failure
# Release build
git submodule update --init --recursive
cmake -B build -G "Visual Studio 17 2022" -A x64
cmake --build build --config Release -j| Tool | Usage | Purpose |
|---|---|---|
dump_regions |
dump_regions <binary> |
Show segmentation groups and sites |
dump_compile |
dump_compile <binary> [key] |
Full pipeline dump: segmentation, grouping, units, bytecodes |
verify_roundtrip |
verify_roundtrip <binary> |
Verify serializer dump/load round-trip (exit 0 = pass) |
| Compiler | Status |
|---|---|
| MSVC 2022 | |
| GCC 14 | |
| Clang 18 | |
| Apple Clang |
- SDK Segmentator -- ELF, PE, Mach-O parsing; x86, x86-64, ARM64 disassembly; VMPilot_Begin/End marker detection
- Region Refiner -- overlap/containment removal, inline grouping, canonical copy detection
- Serializer -- protobuf + TOML manifest,
SerializationTraits<T>, round-trip dump/load - Compilation Backend -- work-stealing thread pool, pluggable
CompilerBackendinterface, SimpleBackend stub - Reference Analyzer -- globals, rodata, TLS, GOT/IAT, atomics, jump tables, scaled-index addressing
- Unified Diagnostics --
DiagnosticCollectorwith thread-safe collection,DiagnosticCodeenum, summary report - CI/CD -- MSVC, GCC, Clang, Apple Clang on GitHub Actions
The compilation backend will replace the SimpleBackend stub with a real native-to-VM-bytecode translator:
CompilationUnit (native code bytes)
|
v
Lifting -- decode native insns, lift to LLVM IR (subset lifter + remill)
|
v
Normalization -- simplify flags, fold constants from .rodata, guest memory AA
|
v
Transform -- virtualize IR to VM opcodes, resolve data refs, encode jump tables
|
v
Emit -- register allocation, bytecode emission, junk insertion, handler variants
|
v
VM Bytecode Blob
VM Bytecode Blob
|
v
Decoder -- decrypt + decode bytecodes using opcode table
|
v
Dispatcher -- fetch-decode-execute loop with handler dispatch
|
v
Handlers -- data movement, arithmetic, logic, compare, control, atomic, width
|
v
Bridge -- native call bridge (x86-64/ARM64 asm), TLS helpers
|
v
Security -- anti-debug, anti-tamper, integrity checks
Original Binary + VM Bytecode Blob
|
v
BinaryPatcher -- patch original binary to redirect protected regions
| ELFPatcher / PEPatcher / MachOPatcher
v
StubGenerator -- emit entry/exit stubs that transfer control to VM runtime
|
v
Final Protected Binary
common/
include/
diagnostic.hpp, diagnostic_collector.hpp
instruction_t.hpp, opcode_enum.hpp, opcode_table.hpp
thread_pool.hpp
vm/ <-- shared VM types (sdk + runtime)
vm_insn.hpp, vm_opcode.hpp, vm_context.hpp
vm_bytecode_blob.hpp, vm_config.hpp, vm_crypto.hpp
sdk/
include/
bytecode_compiler/
CompilationOrchestrator.hpp, CompilerBackend.hpp
compile_pipeline.hpp, LlvmBackend.hpp
lifting/ <-- native -> LLVM IR
Decoder.hpp, Lifter.hpp, SubsetLifter.hpp
RemillLifter.hpp, OpaqueEmitter.hpp, LiftResult.hpp
normalization/ <-- LLVM IR cleanup
NormalizePass.hpp, GuestMemoryAA.hpp
ConstantFoldRodata.hpp, FlagSimplify.hpp
transform/ <-- IR -> VM opcodes
TransformPolicy.hpp, Virtualizer.hpp
DataRefResolver.hpp, JumpTableEncoder.hpp
NativeCallEncoder.hpp
emit/ <-- VM opcodes -> bytecode blob
BytecodeEmitter.hpp, HandlerVariantSelector.hpp
JunkInserter.hpp, RegisterAllocator.hpp
reference_analyzer/
core/
segmentator/
serializer/
runtime/
include/
decoder.hpp
vm/
vm_dispatcher.hpp, vm_handlers.hpp, vm_entry_exit.hpp
src/
vm/
vm_dispatcher.cpp, vm_integrity.cpp
handlers/ <-- one file per category
bridge/
native_call_bridge.cpp
native_call_bridge_{x86_64,arm64}.S
tls_helpers.cpp, tls_helpers_{x86_64,arm64}.S
security/
anti_debug.cpp, anti_tamper.cpp
entry_exit/
vm_{entry,exit}_{x86_64,arm64}.S
loader/
include/
BinaryPatcher.hpp, StubGenerator.hpp
ELFPatcher.hpp, PEPatcher.hpp, MachOPatcher.hpp
src/
BinaryPatcher.cpp, StubGenerator.cpp
ELFPatcher.cpp, PEPatcher.cpp, MachOPatcher.cpp
Please refer to wiki for more information.
flowchart TB
subgraph Input
BIN["Binary<br/>(ELF / PE / Mach-O)"]
end
subgraph SDK["SDK (build time)"]
direction TB
SEG["Segmentator<br/><i>parse binary, find VMPilot_Begin/End,<br/>extract protected regions</i>"]
REF["RegionRefiner<br/><i>deduplicate, handle inlining,<br/>detect canonical copies</i>"]
SER["Serializer<br/><i>build_units(), dump/load,<br/>protobuf + TOML manifest</i>"]
REFA["ReferenceAnalyzer<br/><i>globals, rodata, TLS, GOT/IAT,<br/>atomics, jump tables</i>"]
subgraph Compiler["Compilation Backend"]
direction TB
ORCH["CompilationOrchestrator<br/><i>thread pool parallel dispatch</i>"]
subgraph Future["LLVM Backend (planned)"]
LIFT["Lifting<br/><i>native -> LLVM IR</i>"]
NORM["Normalization<br/><i>flag simplify, const fold</i>"]
XFORM["Transform<br/><i>virtualize to VM opcodes</i>"]
EMIT["Emit<br/><i>bytecode + junk + variants</i>"]
LIFT --> NORM --> XFORM --> EMIT
end
ORCH --> Future
end
SEG --> REF --> SER --> REFA --> ORCH
end
subgraph Output
BLOB["VM Bytecode Blob"]
end
subgraph Loader["Loader (planned)"]
PATCH["BinaryPatcher<br/><i>ELF / PE / Mach-O</i>"]
STUB["StubGenerator<br/><i>entry/exit stubs</i>"]
PATCH --> STUB
end
subgraph Runtime["Runtime VM (planned)"]
DEC["Decoder<br/><i>decrypt + decode bytecodes</i>"]
DISP["Dispatcher<br/><i>fetch-decode-execute loop</i>"]
HAND["Handlers<br/><i>data mov, arith, logic,<br/>control, atomic</i>"]
BRIDGE["Bridge<br/><i>native calls, TLS helpers</i>"]
SEC["Security<br/><i>anti-debug, anti-tamper</i>"]
DEC --> DISP --> HAND --> BRIDGE
DISP --> SEC
end
BIN --> SEG
EMIT --> BLOB
BLOB --> PATCH
STUB --> FINAL["Protected Binary"]
BLOB --> DEC
subgraph Common["common/"]
DIAG["DiagnosticCollector"]
POOL["ThreadPool"]
OPC["Opcode Table + Crypto"]
end
ORCH -.-> POOL
SEG -.-> DIAG
DEC -.-> OPC