# How to Use VMAware's Technique Flags to Selectively Enable or Disable Specific Detection Methods

> Master VMAware's technique flags to tailor detection. Learn to enable or disable methods via flagsets, command-line arguments, or runtime vectors for precise control.

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

---

**Use VMAware's technique flags to control detection methods by passing a custom `VM::flagset` bitset to `VM::detect()`, using command-line arguments like `--disable` or `--enable`, or populating the `VM::disabled_techniques` vector to exclude specific checks at runtime.**

VMAware implements every virtual machine detection method as a distinct technique flag defined in the `VM::enum_flags` enumeration. These flags allow granular control over which hardware and heuristic checks execute during the detection pipeline. Understanding how to manipulate these flags in the `kernelwernel/vmaware` repository enables you to optimize performance, avoid false positives, or target specific hypervisor signatures.

## Understanding the Technique Flag Architecture

Each detection method in VMAware corresponds to a unique value in the `VM::enum_flags` enumeration 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) (lines 557‑603). Internally, the library stores active flags in a `std::bitset<enum_size + 1>` that the core engine examines when running `VM::core::run_all`.

The detection pipeline iterates through these flags to determine which techniques to execute. You can modify this behavior through three distinct control mechanisms: command-line arguments, programmatic bitset construction, or runtime disabling via a global vector.

## Method 1: Command-Line Control via CLI Arguments

The VMAware CLI parser maps textual flag names directly to `enum_flags` values and builds an internal `arg_bitset`. This bitset is then passed to `VM::detect()` or `VM::core::run_all()`, effectively filtering which techniques run.

In [[`src/cli.cpp`](https://github.com/kernelwernel/vmaware/blob/main/src/cli.cpp)](https://github.com/kernelwernel/vmaware/blob/main/src/cli.cpp) (lines 84‑1324), the parser handles `--disable` and `--enable` switches to construct the final bitset. Only the explicitly enabled techniques execute, or alternatively, the specified techniques are skipped while all others run.

```bash

# Run the detector but skip the GPU_CAPABILITIES and CPU_HEURISTIC checks

./vmaware --disable GPU_CAPABILITIES CPU_HEURISTIC

# Enable only a specific subset (e.g., DISK_SERIAL and HYPERVISOR_QUERY)

./vmaware --enable DISK_SERIAL HYPERVISOR_QUERY

```

## Method 2: Programmatic Bitset Selection

For C++ integration, construct a `VM::flagset` object and populate it with the specific techniques you want to run. Pass this bitset to the overloaded `VM::detect(const VM::flagset&)` function. The core engine will iterate only over the set bits, skipping any detection methods not explicitly enabled.

This approach is implemented in [[`src/vmaware.hpp`](https://github.com/kernelwernel/vmaware/blob/main/src/vmaware.hpp)](https://github.com/kernelwernel/vmaware/blob/main/src/vmaware.hpp), where the `detect()` overload forwards your custom bitset to `VM::core::run_all`.

```cpp
#include "vmaware.hpp"

int main() {
    // Build a bitset that enables only specific techniques
    VM::flagset custom_flags;
    custom_flags.set(VM::GPU_CAPABILITIES);   // enable GPU check
    custom_flags.set(VM::CPU_HEURISTIC);      // enable CPU heuristic check
    // All other bits remain clear → those techniques are skipped

    // Run detection with the custom flagset
    bool vm_present = VM::detect(custom_flags);
    if (vm_present) {
        std::cout << "VM detected: " << VM::brand() << '\n';
    } else {
        std::cout << "No VM detected.\n";
    }
}

```

## Method 3: Runtime Disabling via Global Vector

Add entries to the `VM::disabled_techniques` vector (a `std::vector<enum_flags>`) before invoking the scan. The core loop checks each technique against this list using `core::is_disabled(flags, technique_macro)` before execution.

This logic resides 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 11744‑11755), where `VM::core::run_all` verifies whether a technique should be skipped based on the global disabled list.

```cpp
#include "vmaware.hpp"

int main() {
    // Prevent the BOCHS_CPU and KVM checks from running
    VM::disabled_techniques.push_back(VM::BOCHS_CPU);
    VM::disabled_techniques.push_back(VM::KVM);

    // Normal detection call (the core automatically skips disabled entries)
    if (VM::detect()) {
        std::cout << "VM found: " << VM::brand() << '\n';
    }
}

```

## Critical Flag Ordering Constraints

The ordering of the *settings* flags (`HIGH_THRESHOLD`, `DYNAMIC`, `MULTIPLE`) within the enumeration is critical. These must not be reordered, or the bitset layout breaks and causes undefined behavior. This constraint is documented in the comment block at [[`src/vmaware.hpp`](https://github.com/kernelwernel/vmaware/blob/main/src/vmaware.hpp)](https://github.com/kernelwernel/vmaware/blob/main/src/vmaware.hpp) (lines 660‑663).

Always verify that your custom bitset construction respects the original enum ordering if you are manually setting bits by integer values rather than using the named enum constants.

## Summary

- **VM::enum_flags** defines all available detection techniques 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 557‑603).
- **Command-line arguments** (`--disable`, `--enable`) route through [[`src/cli.cpp`](https://github.com/kernelwernel/vmaware/blob/main/src/cli.cpp)](https://github.com/kernelwernel/vmaware/blob/main/src/cli.cpp) to build an `arg_bitset` for filtering.
- **Programmatic control** requires building a `VM::flagset` and passing it to `VM::detect(const VM::flagset&)`.
- **Runtime disabling** uses the global `VM::disabled_techniques` vector checked by `core::is_disabled` (lines 11744‑11755).
- **Settings flags order** is immutable; reordering `HIGH_THRESHOLD`, `DYNAMIC`, or `MULTIPLE` breaks the bitset layout (lines 660‑663).

## Frequently Asked Questions

### What is the difference between VM::flagset and VM::disabled_techniques?

`VM::flagset` is a bitset type that specifies which techniques to actively run when passed to `VM::detect()`, functioning as a whitelist of enabled methods. `VM::disabled_techniques` is a global vector that acts as a blacklist; the core engine checks this list before executing any technique and skips those present in the vector. Use `VM::flagset` for explicit opt-in behavior and `VM::disabled_techniques` for excluding specific checks while running all others.

### Can I combine CLI arguments with programmatic flag sets?

Yes, but they serve different execution paths. The CLI builds an internal bitset that it passes to the detection engine, while programmatic usage allows direct bitset manipulation within your code. If you are embedding VMAware as a library, CLI argument parsing (handled in [[`src/cli.cpp`](https://github.com/kernelwernel/vmaware/blob/main/src/cli.cpp)](https://github.com/kernelwernel/vmaware/blob/main/src/cli.cpp)) is separate from the programmatic API calls. You would need to manually parse arguments and populate a `VM::flagset` if you want CLI-like behavior in your own application.

### Where are the technique flag definitions located in the source code?

All technique flags are defined in the `VM::enum_flags` enumeration within [[`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 557‑603. Each enum value corresponds to a specific VM detection method, such as `VM::GPU_CAPABILITIES` or `VM::BOCHS_CPU`, which the core engine maps to its respective detection function.

### Does disabling techniques affect the confidence score or threshold calculations?

Techniques disabled via `VM::disabled_techniques` or omitted from a custom `VM::flagset` are completely skipped and do not contribute to the confidence score or threshold calculations. The detection percentage and threshold compliance (such as `HIGH_THRESHOLD`) are calculated based only on the techniques that actually execute. Removing high-confidence techniques may require adjusting your threshold settings to maintain accurate detection rates.