Architecture of VMAware's Brand Detection Scoring System: 3-Layer Technical Breakdown

VMAware's brand detection scoring system operates through a three-layer architecture that maps detection techniques to weighted certainty scores, accumulates them in a static per-brand scoreboard, and compares the aggregate against configurable thresholds (150 or 300 points) to determine VM presence and identify the specific hypervisor brand.

VMAware is an open-source C++ library designed to detect virtual machine environments and identify their underlying hypervisor brands. The architecture of VMAware's brand detection scoring system centers on translating individual detection technique certainties into aggregated brand confidence levels using a tightly-coupled pipeline of score mapping, accumulation, and threshold-based evaluation.

Layer 1: Technique-to-Score Mapping

Individual VM detection techniques return a certainty value between 0 and 100 percent based on their execution results. When a technique reports a positive hit, it invokes the scoring API to add that certainty to the appropriate brand's entry in the global scoreboard.

The core implementation resides in src/vmaware.hpp at lines 11666-11695, specifically within the core::add() and core::add_score() functions. These methods handle the translation of raw technique output into weighted points that get assigned to specific brands in the brand_enum taxonomy.

Layer 2: Scoreboard Management

VMAware maintains a static array brand_scoreboard declared at lines 11664-11668 in src/vmaware.hpp to track accumulated scores across all detected brands. This structure uses std::array<brand_entry, MAX_BRANDS> where each brand_entry stores an 8-bit unsigned integer (u8) representing the brand_score.

After every technique execution completes, the scoreboard undergoes post-processing:

  • Filtering removes all entries with a zero score
  • Sorting arranges remaining entries in descending order using std::sort with a comparator that evaluates a.second > b.second

This ensures that when detection concludes, the brand with the highest confidence score occupies the first index of the array.

Layer 3: Threshold-Based Decision Logic

The final determination of VM presence relies on comparing the running total of all brand scores against configurable thresholds. In src/vmaware.hpp at lines 745-749, two constants define these boundaries:

  • Default threshold: 150 points (threshold_score)
  • High-threshold mode: 300 points (high_threshold_score), activated when the VM::HIGH_THRESHOLD flag is set

If the accumulated score exceeds the active threshold, VMAware declares a virtual machine detected and reports the brand with the highest score from the sorted scoreboard. The CLI presentation layer in src/cli.cpp (lines 381-388) then maps this aggregate score to color-coded output—red for low confidence, green for strong confidence—using the color(score, hardened) helper function.

Scoring Criteria and Weight Calculations

Before techniques contribute points to the scoreboard, their raw certainty values undergo adjustment based on the formal rubric defined in docs/score_system.md. The calculation weighs three factors:

  • Reliability (≤50% weight): Consistency across repeated executions and overall detection accuracy
  • Specificity (≤50% weight): How uniquely the technique targets VM environments versus general system characteristics
  • False-Positive Penalty: A four-tier reduction system (0%, 25%, 50%, or 80%) applied to techniques prone to false positives, with a minimum floor of 5 points regardless of penalties

This ensures that unreliable or overly broad detection methods contribute proportionally less to the final brand confidence than precise, hardware-specific checks.

Execution Flow

The complete detection lifecycle follows six distinct phases:

  1. Initiation: core::run_all(flags) iterates over the compiled detection list
  2. Technique execution: Individual checks (CPUID, I/O timings, registry analysis) run their specific logic
  3. Score reporting: Techniques call core::add(p_brand, score) or core::add_score(p_brand, extra_brand, score) to increment brand scores and update last_detected_score
  4. Accumulation: Points aggregate in the brand_scoreboard array entries
  5. Post-processing: Filtering removes zero-score entries and sorting ranks brands by confidence
  6. Threshold evaluation: The system compares totals against 150 or 300 points to render a final verdict

Implementation Examples

Developers can interact with the scoring system through the public API defined in docs/documentation.md:

// Add a custom technique with 70% certainty for QEMU
VM::add(VM::brand_enum::QEMU, 70, []{
    return cpuid_check() && timing_test();
});
// Modify an existing technique's weight at runtime
// Reduce Hyper-V detection from 100% to 60%
VM::modify_score(VM::technique::HYPERV, 60);
// Execute full detection and retrieve top brand
auto total = VM::core::run_all(VM::flags::NONE);
if (total >= VM::core::threshold_score) {
    auto top = VM::core::brand_scoreboard[0];
    std::cout << "Detected: " << VM::brands::brand_enum_to_string(top.brand)
              << " (score: " << static_cast<int>(top.score) << ")\n";
}

Core Source Files and Locations

The brand detection scoring system spans four primary files in the repository:

  • src/vmaware.hpp contains the brand_enum type definitions, brand_entry structures, brand_scoreboard storage, add_score() implementation (lines 11666-11695), and threshold constants (lines 745-749)
  • src/cli.cpp implements the presentation layer including the color() helper for score visualization (lines 381-388)
  • docs/score_system.md documents the formal scoring rubric covering reliability, specificity, and false-positive penalties
  • docs/documentation.md provides the user-facing API reference for adding techniques and modifying thresholds

Summary

  • VMAware employs a three-layer architecture separating technique execution, score accumulation, and threshold-based decision logic
  • Scores aggregate in a static brand_scoreboard array that filters and sorts entries after each detection run
  • Configurable thresholds at 150 and 300 points allow adjustment of detection sensitivity between standard and high-security modes
  • The scoring rubric applies reliability and specificity weights while penalizing false-positive-prone techniques to ensure accurate brand identification

Frequently Asked Questions

How does VMAware determine which VM brand to report when multiple techniques fire?

After all techniques complete execution, VMAware filters the brand_scoreboard to remove zero-score entries and sorts the remaining brands in descending order by their accumulated score. The system reports the brand at index zero—the one with the highest total confidence points—when the aggregate score exceeds the configured threshold.

What distinguishes the default threshold from the high-threshold mode in VMAware?

The default threshold requires 150 points (threshold_score) to declare a VM detection, while high-threshold mode requires 300 points (high_threshold_score). Developers activate the stricter mode by passing the VM::HIGH_THRESHOLD flag during initialization, which reduces false positives at the cost of potentially missing lightly-virtualized environments.

How are technique scores calculated before being added to the brand scoreboard?

Each technique begins with a raw certainty percentage (0-100%) derived from its specific detection logic. VMAware then applies the scoring rubric from docs/score_system.md, weighting reliability and specificity up to 50% each, then subtracting any applicable false-positive penalty (0%, 25%, 50%, or 80%). The final score never falls below 5 points, ensuring minimal contribution from uncertain techniques.

Can developers modify scoring weights without recompiling the library?

Yes, the public API exposes VM::modify_score() which allows runtime adjustment of existing technique weights, and VM::add() enables registration of custom detection functions with arbitrary brand assignments and certainty values. These modifications affect the next execution of VM::core::run_all() without requiring source recompilation.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →