Documentation

May 6, 2026 ยท View on GitHub

Contents


VM::detect()

This is basically the main function you're looking for, which returns a bool. If no parameter is provided, all the recommended checks will be performed. But you can optionally set which techniques are used.

#include "vmaware.hpp"

int main() {
    /**
     * The basic way to detect a VM where the default checks will 
     * be performed. This is the recommended usage of the lib.
     */ 
    bool is_vm = VM::detect();


    /**
     * This does the exact same as above, but as an explicit alternative.
     */ 
    bool is_vm2 = VM::detect(VM::DEFAULT);


    /**
     * All checks are performed including techniques that are
     * disabled by default for a viariety of reasons. If you 
     * want all techniques for the sake of completeness, then 
     * you can use this flag but remember that there may be potential 
     * performance bottlenecks and an increase in false positives.
     */ 
    bool is_vm3 = VM::detect(VM::ALL);


    /**
     * This will raise the detection threshold above the default level.
     * Use this if you want to be extremely sure if it's a VM, but this 
     * increases the chance of a false negative. Use VM::percentage() 
     * for a more precise result if you want.
     */ 
    bool is_vm4 = VM::detect(VM::HIGH_THRESHOLD);


    /**
     * Essentially means only the CPU brand, MAC, and hypervisor bit techniques 
     * should be performed. Note that the less technique flags you provide, the more 
     * likely the result will not be accurate. If you just want to check for 
     * a single technique, use VM::check() instead. Also, read the flag table
     * at the end of this doc file for a full list of technique flags.
     */
    bool is_vm5 = VM::detect(VM::CPU_BRAND, VM::MAC, VM::HYPERVISOR_BIT);


    /**
     * If you want to disable any technique for whatever reason, use VM::DISABLE(...).
     * This code snippet essentially means "perform all the default flags, but only 
     * disable the VM::RDTSC technique". 
     */ 
    bool is_vm6 = VM::detect(VM::DISABLE(VM::RDTSC));


    /**
     * Same as above, but you can disable multiple techniques at the same time.
     */ 
    bool is_vm7 = VM::detect(VM::DISABLE(VM::VMID, VM::RDTSC, VM::HYPERVISOR_BIT));


    /**
     * This is just an example to show that you can use a combination of 
     * different flags and non-technique flags with the above examples. 
     */ 
    bool is_vm8 = VM::detect(VM::DEFAULT, VM::HIGH_THRESHOLD, VM::DISABLE(VM::RDTSC, VM::VMID));
}

VM::percentage()

This will return a std::uint8_t between 0 and 100. It'll return the certainty of whether it has detected a VM based on all the techniques available as a percentage.

#include "vmaware.hpp"
#include <iostream>
#include <cstdint>

int main() {
    // uint8_t and unsigned char works too
    const std::uint8_t percent = VM::percentage();

    if (percent == 100) {
        std::cout << "Definitely a VM!\n";
    } else if (percent == 0) {
        std::cout << "Definitely NOT a VM\n";
    } else {
        std::cout << "Unsure if it's a VM\n";
    }

    // converted to int for console character encoding reasons
    std::cout << "percentage: " << static_cast<int>(percent) << "%\n"; 

    return 0;
}

Note

you can use the same flag system as shown with VM::detect() for this function.


VM::brand()

This will essentially return the VM brand as a std::string. All the brands and brand alias variables are listed here

If none were detected, it will return Unknown. It should be noted that this could be a common scenario even if you're running inside a VM due to technical difficulties with accomplishing this. This is especially true for VMware sub-versions (ESX, GSX, Fusion, etc...). It's not recommended to rely on this function for critical operations as if your whole program depends on it.

#include "vmaware.hpp"
#include <string>

int main() {
    const std::string result = VM::brand();

    if (result == "KVM") {
        // do KVM specific stuff
    } else if (result == "VirtualBox") {
        // you get the idea
    } else if (result == brands::VMWARE) {
        // having manual string comparisons like the two
        // previous ones can lead to typos which will 
        // make the whole check completely redundant.
        // So the lib provides hardcoded string variables 
        // as aliases to avoid these kinds of situations. 
        // They are located in the aforementioned brand table
    }

    return 0;
}

On rare occasions, there might be cases where there's multiple brands that have been detected, which might cause a conflicting output with an inaccurate result. To prevent this, you can use the VM::MULTIPLE flag that returns a message rather than a VM brand string. For example, if it found 2 conflicting brands, it will return VMware or VirtualBox. For 3 conflicts, it's VMware or VirtualBox or QEMU and so on.

#include "vmaware.hpp"
#include <string>

int main() {
    // format: "vmbrand1 or vmbrand2 [or vmbrandx...]"
    const std::string result = VM::brand(VM::MULTIPLE);

    // example output: "VMware or Bochs"
    std::cout << result << "\n";

    // Keep in mind that there's no limit to how many conflicts there can be.
    // And if there's no conflict, it'll revert back to giving the brand string
    // normally as if the VM::MULTIPLE wasn't there

    return 0;
}

Note

you can use the same flag system as shown with VM::detect() for VM::brand()

Important

VM::MULTIPLE has no effect for any other function other than VM::brand()


VM::check()

This takes a single technique argument and returns a bool. It essentially returns a technique's effective output. Nothing more, nothing less.

#include "vmaware.hpp"
#include <iostream>

int main() {
    if (VM::check(VM::VMID)) {
        std::cout << "VMID technique detected a VM!\n";
    }

    if (VM::check(VM::HYPERVISOR_BIT)) {
        std::cout << "Hypervisor bit is set, most definitely a VM!\n";
    }

    return 0;
}

VM::add_custom()

This function allows you to add your own custom VM detection techniques to the scoring system. The first parameter is the percentage score (0 to 100) of how likely it's a VM if your custom code returns true, and the second parameter should either be a lambda, a function pointer, or a std::function<bool()>

// Example 1 with function pointers

bool new_technique() {
    // add your VM detection code here
    return true; 
}

VM::add_custom(50, new_technique);
// Example 2 with lambdas

VM::add_custom(50, []() -> bool { 
    // add your VM detection code here
    return true; 
});

auto new_technique = []() -> bool { 
    // add your VM detection code here
    return true;
}

VM::add_custom(50, new_technique);
// Example 3 with std::function

std::function<bool()> new_technique = []() -> bool {
    // add your VM detection code here
    return true;
};

VM::add_custom(50, new_technique);

VM::type()

This will return the VM type (or architecture) as a std::string based on the brand found. The possible return values are listed here in the type column.

#include "vmaware.hpp"
#include <iostream>

int main() {
    // example output: VirtualBox is a Hypervisor (type 2) VM
    std::cout << VM::brand() << " is a " << VM::type() << " VM\n";
    return 0;
}

VM::conclusion()

This will return the "conclusion" message of what the overall result is as a std::string. By default, there are 2 possible outputs:

  • Running on baremetal
  • Running inside a [brand] VM

The [brand] part might contain a brand or may as well be empty, depending on whether a brand has been found. Additionally, you can extend this by adding the VM::DYNAMIC flag which will now allow much more variadic potential outputs:

  • Running on baremetal
  • Very unlikely a [brand] VM
  • Unlikely a [brand] VM
  • Potentially a [brand] VM
  • Might be a [brand] VM
  • Likely a [brand] VM
  • Very likely a [brand] VM
  • Running inside a [brand] VM

VM::detected_count()

This will fetch the number of techniques that have been detected as a std::uint8_t.

#include "vmaware.hpp"
#include <iostream>

int main() {
    const std::uint8_t count = VM::detected_count();

    // output: 7 techniques were detected
    std::cout << count << " techniques were detected" << "\n"; 

    // note that if it's baremetal, it should be 0.
    // if it's a VM, it should have at least 4 to  
    // maybe around 15 max. The most I've seen was 
    // around 18 but that only occurs very rarely.

    return 0;
}

VM::is_hardened()

This will detect whether the environment has any hardening indications as a bool.

Internally, this function works by analysing which combination of techniques are expected to be detected together. If a certain combination rule is mismatched, it indicates some kind of tampering of the system which assumes some sort of VM hardening.

Similiary to VM::brand(), do not rely on this function for critical operations. This is meant to be a heuristic assumption rather than a concrete guarantee.

#include "vmaware.hpp"
#include <iostream>

int main() {
    if (VM::is_hardened()) {
        std::cout << "Potential hardening detected" << "\n";
    } else {
        std::cout << "Unsure if hardened" << "\n";
    }

    return 0;
}

(Advanced) VM::flag_to_string()

Show

This will take a technique flag enum as an argument and return the string version of it. For example:

#include "vmaware.hpp"
#include <iostream>

int main() {
    const std::string name = VM::flag_to_string(VM::VMID);

    // output: VM::VMID 
    std::cout << "VM::" << name << "\n"; 

    return 0;
}

The reason why this exists is because it can be useful for debugging and infodumping purposes. It should be noted that the "VM::" part is not included in the string output, so that's based on the programmer's choice if it should remain in the string or not. The example given above is obviously useless since the whole code can be manually handwritten, but the function is especially convenient if it's being used with VM::technique_vector. For example:

#include "vmaware.hpp"
#include <iostream>

int main() {
    // this will loop through all the enums in the technique_vector variable,
    // and then checks each of them and outputs the enum that was detected
    for (const auto technique_enum : VM::technique_vector) {
        if (VM::check(technique_enum)) {
            const std::string name = VM::flag_to_string(technique_enum);
            std::cout << "VM::" << name << " was detected\n";
        }
    }

    return 0;
}

(Advanced) VM::detected_enums()

Show

This is a function that will return a vector of all the technique flags that were detected as running in a VM. The return type is std::vector<VM::enum_flags>, and it's designed to give a more programmatic overview of the result.

#include "vmaware.hpp"
#include <iostream>

int main() {
    std::vector<VM::enum_flags> flag_list = VM::detected_enums();

    for (const auto flag : flag_list) {
        std::cout << "VM::" << VM::flag_to_string(flag) << " was detected" << "\n"; 
    }

    return 0;
}

vmaware struct

If you prefer having an object to store all the relevant information about the program's environment instead of calling static member functions, you can use the VM::vmaware struct:

struct vmaware {
    std::string brand;
    std::string type;
    std::string conclusion;
    bool is_vm;
    bool is_hardened;
    std::uint8_t percentage;
    std::uint8_t detected_count;
    std::uint8_t technique_count;
    std::vector<enum_flags> detected_techniques;
    std::vector<std::string> detected_technique_strings;
    std::vector<enum_flags> disabled_techniques;
}; 

example:

#include "vmaware.hpp"
#include <iostream>

int main() {
    VM::vmaware vm;

    std::cout << "Is this a VM? = " << vm.is_vm << "\n";
    std::cout << "How many techniques detected a VM? = " << vm.detected_count << "%\n";
    std::cout << "What's the VM's type? = " << vm.type << "%\n";
    std::cout << "What's the overview in a human-readable message?" << vm.conclusion << "\n";
}

Note

the flag system is compatible for the struct constructor.


Notes and overall things to avoid

โŒ 1. Do NOT rely on the percentage to determine whether you're in a VM. The lib is not designed for this way, and you're potentially increasing false positives. Use VM::detect() instead for that job.

โŒ 2. Do NOT depend your whole program on whether a specific brand was found. VM::brand() will not guarantee it'll give you the result you're looking for even if the environment is in fact that specific VM brand.

Tip

It should also be mentioned that it's recommended for the end-user to create a wrapper around the header file. C++ compilation is notoriously slow compared to C or other systems programming languages, and recompiling the header over and over again is a time waste, especially considering there's around 10k lines of code in it. This is incredibly unreliable and cumbersome for large-scale projects utilising the lib. If you have a build configuration that supports header dependency handling or incremental compilation (which is present in most build systems such as CMake), you can fix the issue by doing something like this:

// wrapper.hpp
#include <string>

namespace wrapper {
    bool is_this_a_vm();
    std::string vm_brand_name();
}
// wrapper.cpp
#include "vmaware.hpp"
#include "wrapper.hpp"

bool wrapper::is_this_a_vm() {
    return VM::detect();
}

std::string wrapper::vm_brand_name() {
    return VM::brand();
}
// something.cpp
#include "wrapper.hpp"

void something() {
    if (wrapper::is_this_a_vm()) {
        std::cout << wrapper::vm_brand_name() << "\n";
    }
}

This wrapper structure would prevent any avoidable recompilations as opposed to potentially recompiling the vmaware.hpp file for every build that modifies the source that #includes the lib, especially if there's a deep hierarchy of file dependencies within your project.


Flag table

VMAware provides a convenient way to not only check for VMs, but also have the flexibility and freedom for the end-user to choose what techniques are used with complete control over what gets executed or not. This is handled with a flag system.

IconPlatform
๐ŸงLinux
๐ŸชŸWindows
๐ŸmacOS
Flag aliasDescriptionSupported platformsCertaintyAdmin?32-bit only?NotesCode implementation
VM::VMIDCheck CPUID output of manufacturer ID for known VMs/hypervisors at leaf 0 and 0x40000000-0x40000100๐Ÿง๐ŸชŸ๐Ÿ100%link
VM::CPU_BRANDCheck if CPU brand model contains any VM-specific string snippets๐Ÿง๐ŸชŸ๐Ÿ95%link
VM::HYPERVISOR_BITCheck if hypervisor feature bit in CPUID ECX bit 31 is enabled (always false for physical CPUs)๐Ÿง๐ŸชŸ๐Ÿ100%link
VM::HYPERVISOR_STRCheck for hypervisor brand string length (would be around 2 characters in a host machine)๐Ÿง๐ŸชŸ๐Ÿ100%link
VM::TIMERCheck for timing anomalies in the system๐ŸชŸ95%link
VM::THREAD_COUNTCheck if there are only 1 or 2 threads, which is a common pattern in VMs with default settings, nowadays physical CPUs should have at least 4 threads for modern CPUs๐Ÿง๐ŸชŸ๐Ÿ35%link
VM::MACCheck if mac address starts with certain VM designated values๐Ÿง20%link
VM::TEMPERATURECheck for device's temperature๐Ÿง20%link
VM::SYSTEMDCheck result from systemd-detect-virt tool๐Ÿง35%link
VM::CVENDORCheck if the chassis vendor is a VM vendor๐Ÿง65%link
VM::CTYPECheck if the chassis type is valid (it's very often invalid in VMs)๐Ÿง20%link
VM::DOCKERENVCheck if /.dockerenv or /.dockerinit file is present๐Ÿง30%link
VM::DMIDECODECheck if dmidecode output matches a VM brand๐Ÿง55%Adminlink
VM::DMESGCheck if dmesg output matches a VM brand๐Ÿง55%Adminlink
VM::HWMONCheck if /sys/class/hwmon/ directory is present. If not, likely a VM๐Ÿง35%link
VM::DLLCheck for VM-specific DLLs๐ŸชŸ50%link
VM::HWMODELCheck if the sysctl for the hwmodel does not contain the "Mac" string๐Ÿ100%link
VM::WINECheck if the function "wine_get_unix_file_name" is present and if the OS booted from a VHD container๐ŸชŸ100%link
VM::POWER_CAPABILITIESCheck what power states are enabled๐ŸชŸ25%link
VM::PROCESSESCheck for any VM processes that are active๐Ÿง40%link
VM::LINUX_USER_HOSTCheck for default VM username and hostname for linux๐Ÿง10%link
VM::GAMARUECheck for Gamarue ransomware technique which compares VM-specific Window product IDs๐ŸชŸ10%link
VM::BOCHS_CPUCheck for various Bochs-related emulation oversights through CPU checks๐Ÿง๐ŸชŸ๐Ÿ100%link
VM::MAC_MEMSIZECheck if memory is too low for MacOS system๐Ÿ15%link
VM::MAC_IOKITCheck MacOS' IO kit registry for VM-specific strings๐Ÿ100%link
VM::IOREG_GREPCheck for VM-strings in ioreg commands for MacOS๐Ÿ100%link
VM::MAC_SIPCheck for the status of System Integrity Protection and hv_mm_present๐Ÿ100%link
VM::VPC_INVALIDCheck for official VPC method๐ŸชŸ75%32-bitlink
VM::SYSTEM_REGISTERS50%link
VM::VMWARE_IOMEMCheck for VMware string in /proc/iomem๐Ÿง65%link
VM::VMWARE_IOPORTSCheck for VMware string in /proc/ioports๐Ÿง70%link
VM::VMWARE_SCSICheck for VMware string in /proc/scsi/scsi๐Ÿง40%link
VM::VMWARE_DMESGCheck for VMware-specific device name in dmesg output๐Ÿง65%AdminDisabled by defaultlink
VM::VMWARE_STRCheck str assembly instruction method for VMware๐ŸชŸ35%32-bitlink
VM::VMWARE_BACKDOORCheck for official VMware io port backdoor technique๐ŸชŸ100%32-bitlink
VM::MUTEXCheck for mutex strings of VM brands๐ŸชŸ100%link
VM::THREAD_MISMATCHCheck if the system's thread count matches the expected thread count for the detected CPU model๐Ÿง๐ŸชŸ๐Ÿ50%link
VM::CUCKOO_DIRCheck for cuckoo directory using crt and WIN API directory functions๐ŸชŸ30%link
VM::CUCKOO_PIPECheck for Cuckoo specific piping mechanism๐ŸชŸ30%link
VM::AZURECheck for default Azure hostname format (Azure uses Hyper-V as their base VM brand)๐Ÿง๐ŸชŸ30%link
VM::DISPLAYCheck for display configurations commonly found in VMs๐ŸชŸ25%link
VM::DEVICE_STRINGCheck if bogus device string would be accepted๐ŸชŸ25%link
VM::BLUESTACKS_FOLDERSCheck for the presence of BlueStacks-specific folders๐Ÿง5%link
VM::CPUID_SIGNATURECheck for CPUID signatures that reveal the presence of a hypervisor๐Ÿง๐ŸชŸ๐Ÿ95%link
VM::KGT_SIGNATURECheck for Intel KGT (Trusty branch) hypervisor signature in CPUID๐Ÿง๐ŸชŸ๐Ÿ80%link
VM::QEMU_VIRTUAL_DMICheck for presence of QEMU in the /sys/devices/virtual/dmi/id directory๐Ÿง40%link
VM::QEMU_USBCheck for presence of QEMU in the /sys/kernel/debug/usb/devices directory๐Ÿง20%Adminlink
VM::HYPERVISOR_DIRCheck for presence of any files in /sys/hypervisor directory๐Ÿง20%link
VM::UML_CPUCheck for the "UML" string in the CPU brand๐Ÿง80%link
VM::KMSGCheck for any indications of hypervisors in the kernel message logs๐Ÿง5%Adminlink
VM::VBOX_MODULECheck for a VBox kernel module๐Ÿง15%link
VM::SYSINFO_PROCCheck for potential VM info in /proc/sysinfo๐Ÿง15%link
VM::DMI_SCANCheck for string matches of VM brands in the linux DMI๐Ÿง50%link
VM::SMBIOS_VM_BITCheck for the VM bit in the SMBIOS data๐Ÿง50%Adminlink
VM::PODMAN_FILECheck for podman file in /run/๐Ÿง5%link
VM::WSL_PROCCheck for WSL or microsoft indications in /proc/ subdirectories๐Ÿง30%link
VM::DRIVERSCheck for VM-specific names for drivers๐ŸชŸ100%link
VM::DISK_SERIALCheck for serial numbers of virtual disks๐ŸชŸ100%link
VM::IVSHMEMCheck for IVSHMEM device presence๐ŸชŸ100%link
VM::GPU_CAPABILITIESCheck for GPU capabilities related to VMs๐ŸชŸ25%link
VM::HANDLESCheck for vm-specific devices๐ŸชŸ100%link
VM::QEMU_FW_CFGDetect QEMU fw_cfg interface. This first checks the Device Tree for a fw-cfg node or hypervisor tag, then verifies the presence of the qemu_fw_cfg module and firmware directories in sysfs.๐Ÿง70%link
VM::VIRTUAL_PROCESSORSCheck if the number of virtual and logical processors are reported correctly by the system๐ŸชŸ100%link
VM::HYPERVISOR_QUERYCheck if a call to NtQuerySystemInformation with the 0x9f leaf fills a _SYSTEM_HYPERVISOR_DETAIL_INFORMATION structure๐ŸชŸ100%link
VM::AMD_SEV_MSRCheck for AMD-SEV MSR running on the system๐Ÿง๐Ÿ50%Adminlink
VM::VIRTUAL_REGISTRYCheck for particular object directory which is present in Sandboxie virtual environment but not in usual host systems๐ŸชŸ90%link
VM::FIRMWARECheck for VM signatures on all firmware tables๐Ÿง๐ŸชŸ100%Adminlink
VM::FILE_ACCESS_HISTORYCheck if the number of accessed files are too low for a human-managed environment๐Ÿง15%link
VM::AUDIOCheck if no waveform-audio output devices are present in the system๐ŸชŸ25%link
VM::NSJAIL_PIDCheck if process status matches with nsjail patterns with PID anomalies๐Ÿง75%link
VM::DEVICESCheck for PCI vendor and device IDs that are VM-specific๐Ÿง๐ŸชŸ95%link
VM::ACPI_SIGNATURECheck for VM-specific ACPI device signatures๐ŸชŸ100%link
VM::TRAPCheck if after raising two traps at the same RIP, a hypervisor interferes with the instruction pointer delivery๐ŸชŸ100%link
VM::UDCheck if no waveform-audio output devices are present in the system๐ŸชŸ25%link
VM::BLOCKSTEPCheck if a hypervisor does not properly restore the interruptibility state after a VM-exit๐ŸชŸ100%link
VM::DBVMCheck if Dark Byte's VM is present๐ŸชŸ150%link
VM::BOOT_LOGOCheck boot logo for known VM images๐Ÿง๐ŸชŸ100%link
VM::MAC_SYSCheck for VM-strings in system profiler commands for MacOS๐Ÿ100%link
VM::KERNEL_OBJECTSCheck for any signs of VMs in Windows kernel object entities๐ŸชŸ100%link
VM::NVRAMCheck for known NVRAM signatures that are present on virtual firmware๐ŸชŸ100%Adminlink
VM::EDIDCheck for non-standard EDID configurations๐ŸชŸ100%link
VM::CPU_HEURISTICCheck whether the CPU is genuine and its reported instruction capabilities are not masked๐ŸชŸ90%link
VM::CLOCKCheck the presence of system timers๐ŸชŸ45%link
VM::MSRCheck for AMD-SEV MSR running on the system๐Ÿง๐Ÿ100%Adminlink
VM::KVM_INTERCEPTIONCheck whether KVM attempts to patch a mismatched hypercall instruction๐ŸชŸ100%link
VM::HYPERVISOR_HOOKCheck whether a hypervisor uses EPT/NPT hooking to intercept hardware breakpoints๐ŸชŸ100%This hypervisor detection also affects debuggerslink
VM::POPFCheck whether a hypervisor delays trap flags over exiting instructions๐ŸชŸ100%link
VM::EIP_OVERFLOWCheck whether a hypervisor does not correctly emulate instructions in compatibility mode๐ŸชŸ100%link
VM::CGROUPCheck for cgroup paths in /proc/self/cgroup๐Ÿง70%link

Brand table

This is the table of all the brands the lib supports.

StringVariable aliasVM typeNotes
Unknownbrands::NULL_BRANDUnknownThis is the default brand it returns if none were found
VirtualBoxbrands::VBOXHypervisor (type 2)
VMwarebrands::VMWAREHypervisor (type 2)
VMware Expressbrands::VMWARE_EXPRESSHypervisor (type 2)
VMware ESXbrands::VMWARE_ESXHypervisor (type 1)
VMware GSXbrands::VMWARE_GSXHypervisor (type 2)
VMware Workstationbrands::VMWARE_WORKSTATIONHypervisor (type 2)
VMware Fusionbrands::VMWARE_FUSIONHypervisor (type 2)
VMware (with VmwareHardenedLoader)brands::VMWARE_HARDHypervisor (type 2)See the repository
bhyvebrands::BHYVEHypervisor (type 2)
KVMbrands::KVMHypervisor (type 1)
QEMUbrands::QEMUEmulator/Hypervisor (type 2)
QEMU+KVMbrands::QEMU_KVMHypervisor (type 1)
KVM Hyper-V Enlightenmentbrands::KVM_HYPERVHypervisor (type 1)
QEMU+KVM Hyper-V Enlightenmentbrands::QEMU_KVM_HYPERVHypervisor (type 1)
Microsoft Hyper-Vbrands::HYPERVHypervisor (type 1)
Microsoft Virtual PC/Hyper-Vbrands::HYPERV_VPCHypervisor (either type 1 or 2)
Parallelsbrands::PARALLELSHypervisor (type 2)
Xen HVMbrands::XENHypervisor (type 1)
ACRNbrands::ACRNHypervisor (type 1)
QNX hypervisorbrands::QNXHypervisor (type 1)
Hybrid Analysisbrands::HYBRIDSandbox
Sandboxiebrands::SANDBOXIESandbox
Dockerbrands::DOCKERContainer
Winebrands::WINECompatibility layer
Virtual PCbrands::VPCHypervisor (type 2)
Anubisbrands::ANUBISSandbox
JoeBoxbrands::JOEBOXSandbox
ThreatExpertbrands::THREATEXPERTSandbox
CWSandboxbrands::CWSANDBOXSandbox
Comodobrands::COMODOSandbox
Bochsbrands::BOCHSEmulator
NetBSD NVMMbrands::NVMMHypervisor (type 2)
OpenBSD VMMbrands::BSD_VMMHypervisor (type 2)
Intel HAXMbrands::INTEL_HAXMHypervisor (type 1)
Unisys s-Parbrands::UNISYSPartitioning Hypervisor
Lockheed Martin LMHSbrands::LMHSHypervisor (unknown type)Yes, you read that right. The lib can detect VMs running on US military fighter jets, apparently.
Cuckoobrands::CUCKOOSandbox
BlueStacksbrands::BLUESTACKSEmulator
Jailhousebrands::JAILHOUSEPartitioning Hypervisor
Apple VZbrands::APPLE_VZUnknown
Intel KGT (Trusty)brands::INTEL_KGTHypervisor (type 1)
Microsoft Azure Hyper-Vbrands::AZURE_HYPERVHypervisor (type 1)
SimpleVisorbrands::SIMPLEVISORHypervisor (type 1)
Hyper-V root partition (host system, not an actual VM)brands::HYPERV_ARTIFACTHost machineWindows Hyper-V has a tendency to modify host hardware values with VM values. In other words, this brand signifies that you're running on a host system, but the Hyper-V that's installed (either by default or manually by the user) is misleadingly making the whole system look like it's in a VM when in reality it's not.

For more information, refer to this graph.
User-mode Linuxbrands::UMLParavirtualised/Hypervisor (type 2)
IBM PowerVMbrands::POWERVMHypervisor (type 1)
OpenStack (KVM)brands::OPENSTACKHypervisor (type 1)
KubeVirt (KVM)brands::KUBEVIRTHypervisor (type 1)
AWS Nitro System EC2 (KVM-based)brands::AWS_NITROHypervisor (type 1)
Podmanbrands::PODMANContainer
WSLbrands::WSLHybrid Hyper-V (type 1 and 2)This is a type 1 at the fundamental level, but WSL has components that are reminiscent of type 2 VM designs to an extent.
OpenVZbrands::OPENVZContainer
ANY.RUNN/ASandboxRemoved from the lib, available only in the CLI due to ethical reasons.
Barevisorbrands::BAREVISORHypervisor (type 1)
HyperPlatformbrands::HYPERPLATFORMHypervisor (type 1)
MiniVisorbrands::MINIVISORHypervisor (type 1)
Intel TDXbrands::INTEL_TDXTrusted Domain
LKVMbrands::LKVMHypervisor (type 1)
AMD SEVbrands::AMD_SEVVM encryptor
AMD SEV-ESbrands::AMD_SEV_ESVM encryptor
AMD SEV-SNPbrands::AMD_SEV_SNPVM encryptor
Neko Project IIbrands::NEKO_PROJECTEmulator
Google Compute Engine (KVM)brands::GCECloud VM service
NoirVisorbrands::NOIRVISORHypervisor (type 1)
Qihoo 360 Sandboxbrands::QIHOOSandbox
nsjailbrands::NSJAILProcess isolator
DBVMbrands::DBVMHypervisor (type 1)See the Cheat Engine's Website
UTMbrands::UTMHypervisor (type 2)
Compaq FX!32brands::COMPAQEmulator
Insignia RealPCbrands::INSIGNIAEmulator
Connectix Virtual PCbrands::CONNECTIXEmulator

Setting flags

FlagDescriptionSpecific to
VM::ALLThis will enable all the technique flags, including checks that are disabled by default.
VM::DEFAULTThis represents a range of flags which are enabled if no default argument is provided.
VM::MULTIPLEThis will basically return a std::string message of which brands could be involved. For example, it could return "VMware or VirtualBox" instead of having a single brand string output.VM::brand()
VM::HIGH_THRESHOLDThis will set the threshold bar to confidently detect a VM by 2x higher.VM::detect() and VM::percentage()
VM::DYNAMICThis will add 8 options to the conclusion message rather than 2, each with their own varying likelihoods.VM::conclusion()
VM::NULL_ARGDoes nothing, meant as a placeholder flag mainly for CLI purposes. It's best to ignore this.

Variables

VariableTypeDescription
VM::technique_countstd::uint16_tThis will store the number of VM detection techniques
VM::technique_vectorstd::vector<std::uint8_t>This will store all the technique macros as a vector. Useful if you're trying to loop through all the techniques for whatever operation you're performing.

CLI documentation

ShorthandFull commandDescription
-h--helpPrints the help menu
-v--versionPrints the version and miscellaneous details
-d--detectPrints the VM detection result (1 = VM, 0 = baremetal)
-s--stdoutReturns either 0 or 1 to STDOUT without any text output (0 = VM, 1 = baremetal)
-b--brandPrints the most likely brand
-l--brand-listPrints all the possible VM brand strings the CLI supports
-c--conclusionPrints the conclusion message string
-p--percentPrints the VM likeliness percentage between 0 and 100
-n--numberPrints the number of VM detection techniques it can perform
-t--typeReturns the VM type (if a VM was found)
-o--outputSet the output path for files, specifically with the --json command
--disable-notesNo notes will be provided
--high-thresholdA higher threshold bar for a VM detection will be applied
--no-ansiRemoves all the ANSI encodings (color and text style). This is added due to some terminals not supporting ANSI escape codes while cluttering the output
--dynamicallow the conclusion message to be dynamic (8 possibilities instead of only 2)
--verboseadd more information to the output
--enumsdisplay the technique enum name used by the lib
--detected-onlyOnly display the techniques that were detected
--jsonOutput a json-formatted file of the results

Note

If you want a general result with the default settings, do not put any arguments. This is the intended way to use the CLI tool.