# VMAware Technique Table Internal Structure: Compile-Time Detection Array Architecture

> Explore the VMAware technique table internal structure. Discover how techniques are organized in a compile-time detection array for efficient VM detection.

- Repository: [Louis/vmaware](https://github.com/kernelwernel/vmaware)
- Tags: internals
- Published: 2026-03-05

---

**The VMAware library organizes every VM detection routine into a static, compile-time initialized `std::array` indexed by enum values, where each entry stores a certainty score and a function pointer to the platform-specific detection logic.**

The kernelwernel/vmaware repository implements its detection engine through a sophisticated technique table that enables zero-overhead dispatch across Windows, Linux, and macOS. This internal structure maps unique enum identifiers to executable detection routines while supporting both compile-time and runtime extensibility.

## Core Data Structures

### The technique Struct

At the heart of the system lies the `technique` struct defined in [[`src/vmaware.hpp`](https://github.com/kernelwernel/vmaware/blob/main/src/vmaware.hpp)](https://github.com/kernelwernel/vmaware/blob/main/src/vmaware.hpp) at lines **11641‑11644**. This minimal structure contains two critical fields:

```cpp
struct technique {
    u16 points;        // Certainty score (0-100%)
    bool(*run)();      // Function pointer to detection logic
};

```

The `points` field represents the confidence weight assigned to a successful detection, while `run` holds the address of the static C++ function that performs the actual VM check.

### Static Table Storage

The **master lookup table** is declared at line **11659** as a compile-time initialized array:

```cpp
static std::array<technique, enum_size + 1> technique_table;

```

This array is indexed directly by the `enum_flags` values defined at lines **553‑563**, creating an O(1) mapping between technique identifiers and their executable logic. The enum includes placeholders marked with `// ADD NEW TECHNIQUE ENUM NAME HERE` for extending the framework.

### Temporary Construction Pairs

To populate the table, VMAware uses a helper struct `technique_entry` (lines **11645‑11648**) that pairs enum values with technique data during the build process:

```cpp
struct technique_entry {
    enum_flags id;
    technique tech;
};

```

## Compile-Time Table Construction

### The Population Lambda

The table is populated through a constexpr lambda located at lines **12852‑12955**. This compile-time logic iterates over a static array of `technique_entry` objects and assigns each to its indexed position:

```cpp
for (const auto& entry : entries) {
    table[entry.id] = entry.tech;
}

```

### Platform-Specific Guarding

Techniques are wrapped in OS-specific preprocessor blocks (`#if WINDOWS`, `#if LINUX`, `#if APPLE`) within the `entries[]` array. This conditional compilation ensures that only relevant detection routines are included in the final binary for each target platform. For example, a Windows-specific entry appears as:

```cpp
{ VM::TRAP, {100, VM::trap} }   // Windows-only: 100% certainty

```

## Runtime Execution Flow

### The run_all Dispatcher

The execution engine resides in `VM::core::run_all` (lines **11732‑11835**). This method iterates over the index range `[technique_begin, technique_end)` and performs the following operations for each `technique_table[i]`:

1. Skips entries where `run` is `nullptr`
2. Checks the **bitset flag** to determine if the technique is disabled via `core::is_disabled`
3. Looks up **cached results** through `memo::is_cached` to avoid redundant execution
4. Executes `technique_data.run()` if not cached
5. Adds the technique's `points` (or an overridden `last_detected_score`) to the global confidence total
6. Stores the result in the memo cache via `memo::cache_store`

### Shortcut and Threshold Logic

When the **shortcut** flag is enabled, the loop aborts early if the accumulated score exceeds `threshold_score` or `high_threshold_score`, optimizing performance for high-confidence detections.

## Extending the Technique Table

### Runtime Custom Techniques

Beyond the static table, VMAware supports runtime extension through `custom_table` (lines **11661‑11663**). Users can register up to **256 custom techniques** via the `VM::add_custom` API:

```cpp
bool my_custom_check() { return true; }

VM::add_custom(VM::core::custom_technique{
    VM::core::technique_count++,
    { 80, my_custom_check }
});

```

Custom entries participate in `run_all` exactly like built-in techniques after registration.

### Automated Technique Addition

The repository includes [`auxiliary/add_technique.py`](https://github.com/kernelwernel/vmaware/blob/main/auxiliary/add_technique.py), an interactive script that automates the insertion of new detection methods. The script updates:
- The enum definition at the `// ADD NEW TECHNIQUE ENUM NAME HERE` marker
- The static `entries[]` array in the technique table
- Checklist entries in [`src/cli.cpp`](https://github.com/kernelwernel/vmaware/blob/main/src/cli.cpp)
- Documentation rows in [`docs/documentation.md`](https://github.com/kernelwernel/vmaware/blob/main/docs/documentation.md)

The script also handles GPL-only techniques by wrapping generated code in `/* GPL */` comments.

## Practical Implementation Examples

### Running Default Detection

```cpp
// Initialize default flagset with all techniques enabled
VM::flagset flags = VM::generate_default();

// Execute with shortcut optimization (stops at threshold 150)
uint16_t score = VM::run_all(flags, VM::SHORTCUT);
std::cout << "VM confidence: " << score << "%\n";

```

### Selective Technique Execution

```cpp
VM::flagset flags = VM::generate_all();
flags.reset();                           // Clear all
flags.set(VM::FIRMWARE);                 // Enable specific Linux check
flags.set(VM::SMBIOS_VM_BIT);

// Run without shortcut (all selected techniques execute)
uint16_t score = VM::run_all(flags, false);

```

### Adding Custom Detection Logic

```cpp
// Define custom detection
bool detect_container_artifact() {
    return std::filesystem::exists("/.dockerenv");
}

// Register with 90% confidence
VM::add_custom(VM::core::custom_technique{
    VM::core::technique_count++,
    { 90, detect_container_artifact }
});

```

## Summary

- The **technique table** is a compile-time initialized `std::array` mapping enum indices to detection functions and certainty scores.
- Each entry in [[`src/vmaware.hpp`](https://github.com/kernelwernel/vmaware/blob/main/src/vmaware.hpp)](https://github.com/kernelwernel/vmaware/blob/main/src/vmaware.hpp) lines **11641‑11644** contains a `u16 points` field and a `bool(*run)()` function pointer.
- Platform-specific techniques are guarded by preprocessor blocks, ensuring only relevant code compiles for Windows, Linux, or macOS targets.
- The `run_all` dispatcher (lines **11732‑11835**) handles execution, memoization, scoring accumulation, and early termination via shortcut logic.
- Runtime extensibility is supported through `custom_table` (lines **11661‑11663**) with a maximum of 256 user-defined techniques.
- The [`auxiliary/add_technique.py`](https://github.com/kernelwernel/vmaware/blob/main/auxiliary/add_technique.py) script automates the boilerplate required to add new built-in detection methods to the enum, table, CLI, and documentation.

## Frequently Asked Questions

### How does VMAware handle techniques that are not supported on the current operating system?

Unsupported techniques are excluded at compile time through preprocessor guards (`#if WINDOWS`, `#if LINUX`, `#if APPLE`) surrounding entries in the static `entries[]` array. This ensures the technique table only contains functions callable on the target platform, eliminating runtime checks or dead code.

### Can the technique table be modified after the program starts?

The static `technique_table` itself is immutable at runtime, but VMAware provides the `custom_table` mechanism (lines **11661‑11663**) which accepts new entries via `VM::add_custom`. These runtime additions are stored separately and merged into the execution flow by `run_all`, allowing dynamic extension without modifying the compiled table.

### What is the performance cost of checking hundreds of techniques?

The table uses O(1) array indexing and supports **shortcut optimization**, which terminates execution early when the accumulated confidence score exceeds the configured threshold. Additionally, a **memoization cache** prevents redundant execution of techniques within the same process, minimizing CPU overhead for repeated scans.

### Why does the technique struct use raw function pointers instead of std::function?

The `bool(*run)()` function pointer in the `technique` struct (lines **11641‑11644**) provides **zero-overhead abstraction** compatible with compile-time initialization. Unlike `std::function`, raw pointers impose no allocation overhead, no type erasure costs, and allow the entire table to be constructed as a `constexpr` static array, ensuring minimal binary size and maximum dispatch speed.