VMAware is a cross-platform, header-only C++ library that provides comprehensive virtual machine detection capabilities. This page introduces the library's purpose, architecture, and key components.
For installation and basic usage instructions, see Getting Started. For detailed information about the core library's internal structure, see Core Library Architecture. For a complete list of detection techniques, see Detection Techniques.
VMAware (VM + Aware) is a C++11-compatible library designed to detect virtual machine environments programmatically. The library consists of a single header file src/vmaware.hpp that provides:
The library targets security researchers, anti-cheat developers, malware analysts, and software developers who need robust VM detection integrated into their applications.
Sources: src/vmaware.hpp1-215 README.md22-36
| Capability | Description | Code Reference |
|---|---|---|
| Boolean Detection | Returns true/false if VM detected | VM::detect() at src/vmaware.hpp11111 |
| Brand Identification | Returns string name of detected VM | VM::brand() at src/vmaware.hpp11111 |
| Type Classification | Categorizes VM as hypervisor/emulator/container | VM::type() at src/vmaware.hpp11111 |
| Confidence Percentage | Returns 0-100% certainty score | VM::percentage() at src/vmaware.hpp11111 |
| Hardening Detection | Detects anti-detection tampering | VM::is_hardened() at src/vmaware.hpp11111 |
| Aggregate Results | Convenience struct for all data | VM::vmaware struct at src/vmaware.hpp11111 |
The library employs a threshold-based scoring system where each detection technique contributes 0-100 points. By default, a cumulative score of 150+ points indicates VM presence, though this can be raised to 300 using the VM::HIGH_THRESHOLD flag.
Sources: src/vmaware.hpp545-658 src/vmaware.hpp66-79
Diagram: VMAware Core Architecture with Code Entities
This diagram shows how the public API functions (VM::detect(), VM::brand(), etc.) interact with the core orchestration layer. All public functions eventually invoke core::run_all(), which iterates through the TECHNIQUE table, executes selected techniques, and updates the brand scoreboard. Techniques leverage three internal modules for their operations.
Sources: src/vmaware.hpp534-12096 src/vmaware.hpp10765-11110
Diagram: VM Detection Execution Flow
This sequence diagram illustrates the execution path when a user calls VM::detect(). The function parses configuration flags into a std::bitset<enum_size + 1> stored in flagset (src/vmaware.hpp701), then invokes core::run_all() (src/vmaware.hpp10765). The core module iterates through enabled techniques, checking the memoization cache before execution to avoid redundant work. Each technique returns a boolean and contributes points to both the total score and brand-specific scores.
Sources: src/vmaware.hpp10765-11110 src/vmaware.hpp1213-1385 src/vmaware.hpp143-174
The entire library is contained within a single VM struct (src/vmaware.hpp534), which acts as a namespace for all functionality. This struct has a deleted constructor, making it purely static:
Sources: src/vmaware.hpp534-12096 src/vmaware.hpp704-707
Techniques are organized using an enum_flags enumeration (src/vmaware.hpp546-658) and stored in a compile-time TECHNIQUE table. Each technique has:
| Property | Type | Purpose |
|---|---|---|
| Enum ID | enum_flags | Unique identifier (e.g., VM::VMID, VM::CPU_BRAND) |
| Function | std::function<bool()> | Technique implementation returning bool |
| Score | u8 (0-100) | Points awarded if technique detects VM |
| Platform Flags | Compile-time checks | Determines if technique runs on current OS |
Platform compatibility is enforced through range checks:
VM::WINDOWS_START to VM::WINDOWS_END (src/vmaware.hpp679-680)VM::LINUX_START to VM::LINUX_END (src/vmaware.hpp681-682)VM::MACOS_START to VM::MACOS_END (src/vmaware.hpp683-684)Sources: src/vmaware.hpp545-658 src/vmaware.hpp679-684 src/vmaware.hpp2436
VM brands are identified through a scoreboard mechanism. The library maintains an array of brand scores (src/vmaware.hpp695-698) where each detected technique increments the score for its associated brand(s) using core::add(). Brands are defined as string constants in the brands namespace (src/vmaware.hpp450-520):
After all techniques execute, VM::brand() sorts the scoreboard and returns the highest-scoring brand. Special logic merges related brands (e.g., Azure + Hyper-V becomes "Microsoft Azure Hyper-V").
Sources: src/vmaware.hpp450-520 src/vmaware.hpp10765 README.md27
The memo module (src/vmaware.hpp1213-1385) provides multiple caching mechanisms:
| Cache Type | Stores | Purpose |
|---|---|---|
| cache_table | Technique results | Avoid re-executing techniques |
| brand cache | Brand string | Cache VM::brand() result |
| cpu_brand cache | CPU brand string | Cache CPUID brand string parsing |
| threadcount cache | Thread count | Cache std::thread::hardware_concurrency() |
| hyperx cache | Hyper-V state | Cache Hyper-V detection logic |
| leaf_cache | CPUID leaf support | Cache CPUID leaf availability checks |
The primary cache_table is an std::array<cache_entry, enum_size + 1> where each entry contains {result, points, has_value}. When core::run_all() encounters a technique, it first checks memo::is_cached() before execution.
Sources: src/vmaware.hpp1213-1385 src/vmaware.hpp1226-1252
The vmaware.hpp header is organized into distinct sections as documented in the file header (src/vmaware.hpp54-62):
| Line Range | Section | Contents |
|---|---|---|
| 545 | Public Enums | enum_flags technique identifiers |
| 721 | CPU Module | CPUID wrappers, brand parsing, thread databases |
| 1213 | Memo Module | Caching infrastructure |
| 1387 | Util Module | File I/O, system commands, permissions |
| 10765 | Core Module | Orchestration, scoring, technique execution |
| 2436 | Technique Definitions | ~100 private technique implementations |
| 11111 | Public API | VM::detect(), VM::brand(), etc. |
| 12096 | External Variables | Static variable definitions |
The library uses preprocessor macros (WINDOWS, LINUX, APPLE, x86, ARM) to enable/disable platform-specific code at compile time. This ensures the library compiles and runs correctly on all supported platforms without runtime overhead.
Sources: src/vmaware.hpp54-62 src/vmaware.hpp227-247 src/vmaware.hpp279-313
VMAware follows several key design principles documented in the code (src/vmaware.hpp82-215):
Static Everything: No constructors or instances required. All functions are static members of the VM struct.
Header-Only: The entire library exists in a single header file with no separate compilation units or linking requirements.
Memoization-First: Results are aggressively cached to support multiple API calls without performance degradation.
Threshold-Based Detection: Rather than binary true/false, the library accumulates weighted evidence from multiple techniques to reduce false positives.
Cross-Platform Abstraction: Platform-specific code is isolated and selected at compile time, presenting a unified API regardless of OS.
Extensibility: Users can add custom techniques via VM::add_custom() that integrate into the existing scoring system.
The library maintains C++11 compatibility (src/vmaware.hpp275-277) while using C++14/17/20 features when available through conditional compilation.
Sources: src/vmaware.hpp82-215 src/vmaware.hpp275-277 src/vmaware.hpp534
Diagram: VMAware API Usage Patterns
Users interact with VMAware through three primary patterns:
Simple Detection: Call VM::detect() for a boolean result. Optionally pass flags like VM::ALL to enable all techniques or VM::HIGH_THRESHOLD for stricter detection.
Detailed Analysis: Call individual functions (VM::brand(), VM::type(), VM::percentage()) to retrieve specific information about the detected environment.
Aggregate Retrieval: Instantiate VM::vmaware struct which internally calls all detection functions and stores results in member variables for convenient access.
All patterns support flag arguments for fine-grained control over which techniques execute.
Sources: src/vmaware.hpp11111 src/vmaware.hpp66-79 src/vmaware.hpp545-658
This overview provides the foundational understanding needed to work with VMAware. For deeper dives into specific subsystems, consult the linked wiki pages at the beginning of this document.
Refresh this wiki
This wiki was recently refreshed. Please wait 3 days to refresh again.