diff --git a/.github/workflows/build_run_win_32_debug.bat b/.github/workflows/build_run_win_32_debug.bat
index 57d07df..ffa0176 100644
--- a/.github/workflows/build_run_win_32_debug.bat
+++ b/.github/workflows/build_run_win_32_debug.bat
@@ -8,5 +8,4 @@ copy "C:\Program Files (x86)\Microsoft Visual Studio\2022\Enterprise\VC\Redist\M
copy "C:\Program Files (x86)\Microsoft Visual Studio\2022\Enterprise\VC\Redist\MSVC\14.30.30704\debug_nonredist\x86\Microsoft.VC143.DebugCRT\vcruntime140d.dll" Debug\
copy "C:\Program Files (x86)\Microsoft Visual Studio\2022\Enterprise\VC\Redist\MSVC\14.30.30704\debug_nonredist\x86\Microsoft.VC143.DebugCRT\msvcp140d.dll" Debug\
cd Debug
-vmaware.exe
-vmaware.exe --disable-hyperv-host
\ No newline at end of file
+vmaware.exe
\ No newline at end of file
diff --git a/.github/workflows/build_run_win_64_debug.bat b/.github/workflows/build_run_win_64_debug.bat
index 1c6154a..f3b0c05 100644
--- a/.github/workflows/build_run_win_64_debug.bat
+++ b/.github/workflows/build_run_win_64_debug.bat
@@ -8,5 +8,4 @@ copy "C:\Program Files (x86)\Microsoft Visual Studio\2022\Enterprise\VC\Redist\M
copy "C:\Program Files (x86)\Microsoft Visual Studio\2022\Enterprise\VC\Redist\MSVC\14.30.30704\debug_nonredist\x86\Microsoft.VC143.DebugCRT\vcruntime140d.dll" Debug\
copy "C:\Program Files (x86)\Microsoft Visual Studio\2022\Enterprise\VC\Redist\MSVC\14.30.30704\debug_nonredist\x86\Microsoft.VC143.DebugCRT\msvcp140d.dll" Debug\
cd Debug
-vmaware.exe
-vmaware.exe --disable-hyperv-host
\ No newline at end of file
+vmaware.exe
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ff2963d..81f9543 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -59,7 +59,7 @@ if (MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Od")
elseif(CMAKE_BUILD_TYPE MATCHES "Release")
MESSAGE(STATUS "Build set to release mode")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /O3")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /O2")
endif()
elseif(LINUX)
if(CMAKE_BUILD_TYPE MATCHES "Debug")
diff --git a/TODO.md b/TODO.md
index 41982f0..245ae0d 100644
--- a/TODO.md
+++ b/TODO.md
@@ -41,6 +41,7 @@
- [ ] maybe add internal is_cached functionalities in the cache fetchers
- [ ] make the whole cache table into a mutex so i can claim it's thread-safe
- [ ] make a medium post about it
+- [ ] test the VM::modify_score() function
# Distant plans
- add the library to conan.io when released
diff --git a/assets/hyperv_fucker.png b/assets/hyperv_fucker.png
new file mode 100644
index 0000000..d7f6178
Binary files /dev/null and b/assets/hyperv_fucker.png differ
diff --git a/docs/documentation.md b/docs/documentation.md
index 5cda705..c16d236 100644
--- a/docs/documentation.md
+++ b/docs/documentation.md
@@ -199,6 +199,8 @@ This will essentially return the VM brand as a `std::string`. The exact possible
- `Intel KGT (Trusty)`
- `Microsoft Azure Hyper-V`
- `Xbox NanoVisor (Hyper-V)`
+- `SimpleVisor`
+- `Hyper-V artifact (not an actual VM)`
If none were detected, it will return `Unknown`. It's often NOT going to produce a satisfying result due to technical difficulties with accomplishing this, on top of being highly dependent on what mechanisms detected a VM. This is especially true for VMware sub-versions (ESX, GSX, Fusion, etc...) Don't rely on this function for critical operations as if it's your golden bullet. It's arguably unreliable and it'll most likely return `Unknown` (assuming it is actually running under a VM).
@@ -322,108 +324,108 @@ VM::add_custom(50, new_technique);
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.
-| Flag alias | Description | Cross-platform? (empty = yes) | Certainty | Admin? | GPL-3.0? | 32-bit? |
-| ---------- | ----------- | --------------- | --------- | ------ | -------- | ------- |
-| `VM::VMID` | Check CPUID output of manufacturer ID for known VMs/hypervisors at leaf 0 | | 100% | | | |
-| `VM::CPU_BRAND` | Check if CPU brand model contains any VM-specific string snippets | | 50% | | | |
-| `VM::HYPERVISOR_BIT` | Check if hypervisor feature bit in CPUID eax bit 31 is enabled (always false for physical CPUs) | | 100% | | | |
-| `VM::HYPERVISOR_STR` | Check for hypervisor brand string length (would be around 2 characters in a host machine) | | 45% | | | |
-| `VM::RDTSC` | Benchmark RDTSC and evaluate its speed, usually it's very slow in VMs | Linux and Windows | 10% | | | |
-| `VM::THREADCOUNT` | Check 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% | | | |
-| `VM::MAC` | Check if mac address starts with certain VM designated values | Linux and Windows | 60% | | | |
-| `VM::TEMPERATURE` | Check if thermal directory in linux is present, might not be present in VMs | Linux | 15% | | |
-| `VM::SYSTEMD` | Check result from systemd-detect-virt tool | Linux | 70% | | | |
-| `VM::CVENDOR` | Check if the chassis vendor is a VM vendor | Linux | 65% | | | |
-| `VM::CTYPE` | Check if the chassis type is valid (it's very often invalid in VMs) | Linux | 10% | | | |
-| `VM::DOCKERENV` | Check if /.dockerenv or /.dockerinit file is present | Linux | 80% | | | |
-| `VM::DMIDECODE` | Check if dmidecode output matches a VM brand | Linux | 55% | Admin | | |
-| `VM::DMESG` | Check if dmesg output matches a VM brand | Linux | 55% | Admin | | |
-| `VM::HWMON` | Check if /sys/class/hwmon/ directory is present. If not, likely a VM | Linux | 75% | | | |
-| `VM::SIDT5` | Check if the 5th byte after sidt is null | Linux | 45% | | | |
-| `VM::CURSOR` | Check if cursor isn't active for 5 seconds (sign of automated VM environment) | Windows | 5% | | | |
-| `VM::VMWARE_REG` | Check for VBox RdrDN | Windows | 65% | | | |
-| `VM::VBOX_REG` | Look for any VirtualBox-specific registry data | Windows | 65% | | | |
-| `VM::USER` | checks for default usernames, often a sign of a VM | Windows | 35% | | | |
-| `VM::DLL` | Check for VM-specific DLLs | Windows | 50% | | | |
-| `VM::REGISTRY` | Check for VM-specific registry values | Windows | 75% | | | |
-| `VM::CWSANDBOX_VM` | Check if CWSandbox-specific file exists | Windows | 10% | | | |
-| `VM::VM_FILES` | Find for VMware and VBox specific files | Windows | 10% | | | |
-| `VM::HWMODEL` | Check if the sysctl for the hwmodel does not contain the "Mac" string | MacOS | 75% | | | |
-| `VM::DISK_SIZE` | Check if disk size is under or equal to 50GB | Linux | 60% | | | |
-| `VM::VBOX_DEFAULT` | Check for default RAM and DISK sizes set by VirtualBox | Linux and Windows | 55% | Admin | | |
-| `VM::VBOX_NETWORK` | Check for VirtualBox network provider string | Windows | 70% | | | |
-| `VM::COMPUTER_NAME` | Check if the computer name (not username to be clear) is VM-specific | Windows | 40% | | GPL | |
-| `VM::WINE_CHECK` | Check wine_get_unix_file_name file for Wine | Windows | 85% | | GPL | |
-| `VM::HOSTNAME` | Check if hostname is specific | Windows | 25% | | GPL | |
-| `VM::MEMORY` | Check if memory space is far too low for a physical machine | Windows | 35% | | GPL | |
-| `VM::VBOX_WINDOW_CLASS` | Check for the window class for VirtualBox | Windows | 10% | | GPL | |
-| `VM::LOADED_DLLS` | Check for loaded DLLs in the process | Windows | 75% | | GPL | |
-| `VM::KVM_REG` | Check for KVM-specific registry strings | Windows | 75% | | GPL | |
-| `VM::KVM_DRIVERS` | Check for KVM-specific .sys files in system driver directory | Windows | 55% | | GPL | |
-| `VM::KVM_DIRS` | Check for KVM directory "Virtio-Win" | Windows | 55% | | GPL | |
-| `VM::AUDIO` | Check if audio device is present | Windows | 35% | | GPL | |
-| `VM::QEMU_DIR` | Check for QEMU-specific blacklisted directories | Windows | 45% | | GPL | |
-| `VM::MOUSE_DEVICE` | Check for the presence of a mouse device | Windows | 20% | | GPL | |
-| `VM::VM_PROCESSES` | Check for any VM processes that are active | Windows | 30% | | | |
-| `VM::LINUX_USER_HOST` | Check for default VM username and hostname for linux | Linux | 25% | | | |
-| `VM::GAMARUE` | Check for Gamarue ransomware technique which compares VM-specific Window product IDs | Windows | 40% | | | |
-| `VM::VMID_0X4` | Check if the CPU manufacturer ID matches that of a VM brand with leaf 0x40000000 | | 100% | | | |
-| `VM::PARALLELS_VM` | Check for any indication of Parallels VM through BIOS data | Windows | 50% | | | |
-| `VM::RDTSC_VMEXIT` | check through alternative RDTSC technique with VMEXIT | | 25% | | | |
-| `VM::QEMU_BRAND` | Match for QEMU CPU brands with "QEMU Virtual CPU" string | | 100% | | | |
-| `VM::BOCHS_CPU` | Check for various Bochs-related emulation oversights through CPU checks | | 95% | | | |
-| `VM::VPC_BOARD` | Check through the motherboard and match for VirtualPC-specific string | Windows | 20% | | | |
-| `VM::HYPERV_WMI` | Check WMI query for "Hyper-V RAW" string | Windows | 80% | | | |
-| `VM::HYPERV_REG` | Check presence for Hyper-V specific string in registry | Windows | 80% | | | |
-| `VM::BIOS_SERIAL` | Check if the BIOS serial is valid (null = VM) | Windows | 60% | | | |
-| `VM::VBOX_FOLDERS` | Check for VirtualBox-specific string for shared folder ID | Windows | 45% | | | |
-| `VM::MSSMBIOS` | Check MSSMBIOS registry for VM-specific strings | Windows | 75% | | | |
-| `VM::MAC_MEMSIZE` | Check if memory is too low for MacOS system | MacOS | 30% | | | |
-| `VM::MAC_IOKIT` | Check MacOS' IO kit registry for VM-specific strings | MacOS | 80% | | | |
-| `VM::IOREG_GREP` | Check for VM-strings in ioreg commands for MacOS | MacOS | 75% | | | |
-| `VM::MAC_SIP` | Check if System Integrity Protection is disabled (likely a VM if it is) | MacOS | 85% | | | |
-| `VM::HKLM_REGISTRIES` | Check HKLM registries for specific VM strings | Windows | 70% | | | |
-| `VM::QEMU_GA` | Check for "qemu-ga" process | Linux | 20% | | | |
-| `VM::VALID_MSR` | check for valid MSR value 0x40000000 | Windows | 35% | | | |
-| `VM::QEMU_PROC` | Check for QEMU processes | Windows | 30% | | | |
-| `VM::VPC_PROC` | Check for VPC processes | Windows | 30% | | | |
-| `VM::VPC_INVALID` | Check for official VPC method | Windows | 75% | | | 32-bit |
-| `VM::SIDT` | Check for sidt instruction method | Linux, Windows | 30% | | | |
-| `VM::SGDT` | Check for sgdt instruction method | Windows | 30% | | | 32-bit |
-| `VM::SLDT` | Check for sldt instruction method | Windows | 15% | | | 32-bit |
-| `VM::OFFSEC_SIDT` | Check for Offensive Security SIDT method | Windows | 60% | | | 32-bit |
-| `VM::OFFSEC_SGDT` | Check for Offensive Security SGDT method | Windows | 60% | | | 32-bit |
-| `VM::OFFSEC_SLDT` | Check for Offensive Security SLDT method | Windows | 20% | | | 32-bit |
-| `VM::HYPERV_BOARD` | Check for Hyper-V specific string in motherboard | Windows | 45% | | | |
-| `VM::VM_FILES_EXTRA` | Check for VPC and Parallels files | Windows | 70% | | | |
-| `VM::VPC_SIDT` | Check for sidt method with VPC's 0xE8XXXXXX range | Windows | 15% | | | 32-bit |
-| `VM::VMWARE_IOMEM` | Check for VMware string in /proc/iomem | Linux | 65% | | | |
-| `VM::VMWARE_IOPORTS` | Check for VMware string in /proc/ioports | Linux | 70% | | | |
-| `VM::VMWARE_SCSI` | Check for VMware string in /proc/scsi/scsi | Linux | 40% | | | |
-| `VM::VMWARE_DMESG` | Check for VMware-specific device name in dmesg output | Linux | 65% | Admin | | |
-| `VM::VMWARE_STR` | Check str assembly instruction method for VMware | Windows | 35% | | | |
-| `VM::VMWARE_BACKDOOR` | Check for official VMware io port backdoor technique | Windows | 100% | | | 32-bit |
-| `VM::VMWARE_PORT_MEM` | Check for VMware memory using IO port backdoor | Windows | 85% | | | 32-bit |
-| `VM::SMSW` | Check for SMSW assembly instruction technique | Windows | 30% | | | 32-bit |
-| `VM::MUTEX` | Check for mutex strings of VM brands | Windows | 85% | | | |
-| `VM::UPTIME` | Check if uptime is less than or equal to 2 minutes | | 10% | | | |
-| `VM::ODD_CPU_THREADS` | Check for odd CPU threads, usually a sign of modification through VM setting because 99% of CPUs have even numbers of threads | | 80% | | | |
-| `VM::INTEL_THREAD_MISMATCH` | Check for Intel CPU thread count database if it matches the system's thread count | | 85% | | | |
-| `VM::XEON_THREAD_MISMATCH` | Same as above, but for Xeon Intel CPUs | | 85% | | | |
-| `VM::NETTITUDE_VM_MEMORY` | Check for memory regions to detect VM-specific brands | Windows | 75% | | | |
-| `VM::CPUID_BITSET` | Check for CPUID technique by checking whether all the bits equate to more than 4000 | | 20% | | | |
-| `VM::CUCKOO_DIR` | Check for cuckoo directory using crt and WIN API directory functions | Windows | 15% | | | |
-| `VM::CUCKOO_PIPE` | Check for Cuckoo specific piping mechanism | Windows | 20% | | | |
-| `VM::HYPERV_HOSTNAME` | Check for default Azure hostname format regex (Azure uses Hyper-V as their base VM brand) | Windows, Linux | 50% | | | |
-| `VM::GENERAL_HOSTNAME` | Check for commonly set hostnames by certain VM brands | Windows, Linux | 20% | | | |
-| `VM::SCREEN_RESOLUTION` | Check for pre-set screen resolutions commonly found in VMs | Windows | 10% | | | |
-| `VM::DEVICE_STRING` | Check if bogus device string would be accepted | Windows | 25% | | | |
-| `VM::BLUESTACKS_FOLDERS` | Check for the presence of BlueStacks-specific folders | Linux | 15% | | | |
-| `VM::CPUID_SIGNATURE` | Check for signatures in leaf 0x40000001 in CPUID | | 95% | | | |
-| `VM::HYPERV_BITMASK` | Check for Hyper-V CPUID bitmask range for reserved values | | 20% | | | |
-| `VM::KVM_BITMASK` | Check for KVM CPUID bitmask range for reserved values | | 40% | | | |
-| `VM::KGT_SIGNATURE` | Check for Intel KGT (Trusty branch) hypervisor signature in CPUID | | 80% | | | |
-| `VM::VMWARE_DMI` | Check for VMware DMI strings in BIOS serial number | Windows | 30% | | | |
+| Flag alias | Description | Cross-platform? (empty = yes) | Certainty | Admin? | GPL-3.0? | 32-bit? | Notes |
+| ---------- | ----------- | ----------------------------- | --------- | ------ | -------- | ------- | ----- |
+| `VM::VMID` | Check CPUID output of manufacturer ID for known VMs/hypervisors at leaf 0 | | 100% | | | | |
+| `VM::CPU_BRAND` | Check if CPU brand model contains any VM-specific string snippets | | 50% | | | | |
+| `VM::HYPERVISOR_BIT` | Check if hypervisor feature bit in CPUID eax bit 31 is enabled (always false for physical CPUs) | | 100% | | | | |
+| `VM::HYPERVISOR_STR` | Check for hypervisor brand string length (would be around 2 characters in a host machine) | | 45% | | | | |
+| `VM::RDTSC` | Benchmark RDTSC and evaluate its speed, usually it's very slow in VMs | Linux and Windows | 10% | | | | Disabled by default |
+| `VM::THREADCOUNT` | Check 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% | | | | |
+| `VM::MAC` | Check if mac address starts with certain VM designated values | Linux and Windows | 60% | | | | |
+| `VM::TEMPERATURE` | Check if thermal directory in linux is present, might not be present in VMs | Linux | 15% | | | |
+| `VM::SYSTEMD` | Check result from systemd-detect-virt tool | Linux | 70% | | | | |
+| `VM::CVENDOR` | Check if the chassis vendor is a VM vendor | Linux | 65% | | | | |
+| `VM::CTYPE` | Check if the chassis type is valid (it's very often invalid in VMs) | Linux | 10% | | | | |
+| `VM::DOCKERENV` | Check if /.dockerenv or /.dockerinit file is present | Linux | 80% | | | | |
+| `VM::DMIDECODE` | Check if dmidecode output matches a VM brand | Linux | 55% | Admin | | | |
+| `VM::DMESG` | Check if dmesg output matches a VM brand | Linux | 55% | Admin | | | |
+| `VM::HWMON` | Check if /sys/class/hwmon/ directory is present. If not, likely a VM | Linux | 75% | | | | |
+| `VM::SIDT5` | Check if the 5th byte after sidt is null | Linux | 45% | | | | |
+| `VM::CURSOR` | Check if cursor isn't active for 5 seconds (sign of automated VM environment) | Windows | 5% | | | | Disabled by default |
+| `VM::VMWARE_REG` | Check for VBox RdrDN | Windows | 65% | | | | |
+| `VM::VBOX_REG` | Look for any VirtualBox-specific registry data | Windows | 65% | | | | |
+| `VM::USER` | checks for default usernames, often a sign of a VM | Windows | 35% | | | | |
+| `VM::DLL` | Check for VM-specific DLLs | Windows | 50% | | | | |
+| `VM::REGISTRY` | Check for VM-specific registry values | Windows | 75% | | | | |
+| `VM::CWSANDBOX_VM` | Check if CWSandbox-specific file exists | Windows | 10% | | | | |
+| `VM::VM_FILES` | Find for VMware and VBox specific files | Windows | 10% | | | | |
+| `VM::HWMODEL` | Check if the sysctl for the hwmodel does not contain the "Mac" string | MacOS | 75% | | | | |
+| `VM::DISK_SIZE` | Check if disk size is under or equal to 50GB | Linux | 60% | | | | |
+| `VM::VBOX_DEFAULT` | Check for default RAM and DISK sizes set by VirtualBox | Linux and Windows | 55% | Admin | | | |
+| `VM::VBOX_NETWORK` | Check for VirtualBox network provider string | Windows | 70% | | | | |
+| `VM::COMPUTER_NAME` | Check if the computer name (not username to be clear) is VM-specific | Windows | 40% | | GPL | | |
+| `VM::WINE_CHECK` | Check wine_get_unix_file_name file for Wine | Windows | 85% | | GPL | | |
+| `VM::HOSTNAME` | Check if hostname is specific | Windows | 25% | | GPL | | |
+| `VM::MEMORY` | Check if memory space is far too low for a physical machine | Windows | 35% | | GPL | | |
+| `VM::VBOX_WINDOW_CLASS` | Check for the window class for VirtualBox | Windows | 10% | | GPL | | |
+| `VM::LOADED_DLLS` | Check for loaded DLLs in the process | Windows | 75% | | GPL | | |
+| `VM::KVM_REG` | Check for KVM-specific registry strings | Windows | 75% | | GPL | | |
+| `VM::KVM_DRIVERS` | Check for KVM-specific .sys files in system driver directory | Windows | 55% | | GPL | | |
+| `VM::KVM_DIRS` | Check for KVM directory "Virtio-Win" | Windows | 55% | | GPL | | |
+| `VM::AUDIO` | Check if audio device is present | Windows | 35% | | GPL | | |
+| `VM::QEMU_DIR` | Check for QEMU-specific blacklisted directories | Windows | 45% | | GPL | | |
+| `VM::MOUSE_DEVICE` | Check for the presence of a mouse device | Windows | 20% | | GPL | | |
+| `VM::VM_PROCESSES` | Check for any VM processes that are active | Windows | 30% | | | | |
+| `VM::LINUX_USER_HOST` | Check for default VM username and hostname for linux | Linux | 25% | | | | |
+| `VM::GAMARUE` | Check for Gamarue ransomware technique which compares VM-specific Window product IDs | Windows | 40% | | | | |
+| `VM::VMID_0X4` | Check if the CPU manufacturer ID matches that of a VM brand with leaf 0x40000000 | | 100% | | | | |
+| `VM::PARALLELS_VM` | Check for any indication of Parallels VM through BIOS data | Windows | 50% | | | | |
+| `VM::RDTSC_VMEXIT` | check through alternative RDTSC technique with VMEXIT | | 25% | | | | Disabled by default |
+| `VM::QEMU_BRAND` | Match for QEMU CPU brands with "QEMU Virtual CPU" string | | 100% | | | | |
+| `VM::BOCHS_CPU` | Check for various Bochs-related emulation oversights through CPU checks | | 95% | | | | |
+| `VM::VPC_BOARD` | Check through the motherboard and match for VirtualPC-specific string | Windows | 20% | | | | |
+| `VM::HYPERV_WMI` | Check WMI query for "Hyper-V RAW" string | Windows | 80% | | | | |
+| `VM::HYPERV_REG` | Check presence for Hyper-V specific string in registry | Windows | 80% | | | | |
+| `VM::BIOS_SERIAL` | Check if the BIOS serial is valid (null = VM) | Windows | 60% | | | | |
+| `VM::VBOX_FOLDERS` | Check for VirtualBox-specific string for shared folder ID | Windows | 45% | | | | |
+| `VM::MSSMBIOS` | Check MSSMBIOS registry for VM-specific strings | Windows | 75% | | | | |
+| `VM::MAC_MEMSIZE` | Check if memory is too low for MacOS system | MacOS | 30% | | | | |
+| `VM::MAC_IOKIT` | Check MacOS' IO kit registry for VM-specific strings | MacOS | 80% | | | | |
+| `VM::IOREG_GREP` | Check for VM-strings in ioreg commands for MacOS | MacOS | 75% | | | | |
+| `VM::MAC_SIP` | Check if System Integrity Protection is disabled (likely a VM if it is) | MacOS | 85% | | | | |
+| `VM::HKLM_REGISTRIES` | Check HKLM registries for specific VM strings | Windows | 70% | | | | |
+| `VM::QEMU_GA` | Check for "qemu-ga" process | Linux | 20% | | | | |
+| `VM::VALID_MSR` | check for valid MSR value 0x40000000 | Windows | 35% | | | | |
+| `VM::QEMU_PROC` | Check for QEMU processes | Windows | 30% | | | | |
+| `VM::VPC_PROC` | Check for VPC processes | Windows | 30% | | | | |
+| `VM::VPC_INVALID` | Check for official VPC method | Windows | 75% | | | 32-bit | |
+| `VM::SIDT` | Check for sidt instruction method | Linux, Windows | 30% | | | | |
+| `VM::SGDT` | Check for sgdt instruction method | Windows | 30% | | | 32-bit | |
+| `VM::SLDT` | Check for sldt instruction method | Windows | 15% | | | 32-bit | |
+| `VM::OFFSEC_SIDT` | Check for Offensive Security SIDT method | Windows | 60% | | | 32-bit | |
+| `VM::OFFSEC_SGDT` | Check for Offensive Security SGDT method | Windows | 60% | | | 32-bit | |
+| `VM::OFFSEC_SLDT` | Check for Offensive Security SLDT method | Windows | 20% | | | 32-bit | |
+| `VM::HYPERV_BOARD` | Check for Hyper-V specific string in motherboard | Windows | 45% | | | | |
+| `VM::VM_FILES_EXTRA` | Check for VPC and Parallels files | Windows | 70% | | | | |
+| `VM::VPC_SIDT` | Check for sidt method with VPC's 0xE8XXXXXX range | Windows | 15% | | | 32-bit | |
+| `VM::VMWARE_IOMEM` | Check for VMware string in /proc/iomem | Linux | 65% | | | | |
+| `VM::VMWARE_IOPORTS` | Check for VMware string in /proc/ioports | Linux | 70% | | | | |
+| `VM::VMWARE_SCSI` | Check for VMware string in /proc/scsi/scsi | Linux | 40% | | | | |
+| `VM::VMWARE_DMESG` | Check for VMware-specific device name in dmesg output | Linux | 65% | Admin | | | |
+| `VM::VMWARE_STR` | Check str assembly instruction method for VMware | Windows | 35% | | | | |
+| `VM::VMWARE_BACKDOOR` | Check for official VMware io port backdoor technique | Windows | 100% | | | 32-bit | |
+| `VM::VMWARE_PORT_MEM` | Check for VMware memory using IO port backdoor | Windows | 85% | | | 32-bit | |
+| `VM::SMSW` | Check for SMSW assembly instruction technique | Windows | 30% | | | 32-bit | |
+| `VM::MUTEX` | Check for mutex strings of VM brands | Windows | 85% | | | | |
+| `VM::UPTIME` | Check if uptime is less than or equal to 2 minutes | | 10% | | | | |
+| `VM::ODD_CPU_THREADS` | Check for odd CPU threads, usually a sign of modification through VM setting because 99% of CPUs have even numbers of threads | | 80% | | | | |
+| `VM::INTEL_THREAD_MISMATCH` | Check for Intel CPU thread count database if it matches the system's thread count | | 85% | | | | |
+| `VM::XEON_THREAD_MISMATCH` | Same as above, but for Xeon Intel CPUs | | 85% | | | | |
+| `VM::NETTITUDE_VM_MEMORY` | Check for memory regions to detect VM-specific brands | Windows | 75% | | | | |
+| `VM::CPUID_BITSET` | Check for CPUID technique by checking whether all the bits equate to more than 4000 | | 20% | | | | |
+| `VM::CUCKOO_DIR` | Check for cuckoo directory using crt and WIN API directory functions | Windows | 15% | | | | |
+| `VM::CUCKOO_PIPE` | Check for Cuckoo specific piping mechanism | Windows | 20% | | | | |
+| `VM::HYPERV_HOSTNAME` | Check for default Azure hostname format regex (Azure uses Hyper-V as their base VM brand) | Windows, Linux | 50% | | | | |
+| `VM::GENERAL_HOSTNAME` | Check for commonly set hostnames by certain VM brands | Windows, Linux | 20% | | | | |
+| `VM::SCREEN_RESOLUTION` | Check for pre-set screen resolutions commonly found in VMs | Windows | 10% | | | | |
+| `VM::DEVICE_STRING` | Check if bogus device string would be accepted | Windows | 25% | | | | |
+| `VM::BLUESTACKS_FOLDERS` | Check for the presence of BlueStacks-specific folders | Linux | 15% | | | | |
+| `VM::CPUID_SIGNATURE` | Check for signatures in leaf 0x40000001 in CPUID | | 95% | | | | |
+| `VM::HYPERV_BITMASK` | Check for Hyper-V CPUID bitmask range for reserved values | | 20% | | | | |
+| `VM::KVM_BITMASK` | Check for KVM CPUID bitmask range for reserved values | | 40% | | | | |
+| `VM::KGT_SIGNATURE` | Check for Intel KGT (Trusty branch) hypervisor signature in CPUID | | 80% | | | | |
+| `VM::VMWARE_DMI` | Check for VMware DMI strings in BIOS serial number | Windows | 30% | | | | |
@@ -434,7 +436,6 @@ VMAware provides a convenient way to not only check for VMs, but also have the f
| `VM::ALL` | This will enable all the technique flags, including the cursor check that's disabled by default. |
| `VM::NO_MEMO` | This will disable memoization, meaning the result will not be fetched through a previous computation of the `VM::detect()` function. Use this if you're only using a single function from the `VM` struct for a performance boost. |
| `VM::DEFAULT` | This represents a range of flags which are enabled if no default argument is provided. |
-| `VM::ENABLE_HYPERV_HOST` | Windows 11 (and 10 if enabled manually) may have Hyper-V as a default virtualisation solution for any host program even if the OS is running as host. There isn't a way to detect whether the host program is ran in default virtualisation mode, or manually intended virtualisation. This is a Hyper-V specific problem, and the library will use heuristical methods to discard Hyper-V's host virtualiser as not running in a VM by default. But if this flag is enabled then it will still count it regardless of the risk that it might be Hyper-V's default host virtualisation for every host program. So basically this flag means that "I'm aware this program might be running in a default virtualised environment on host, but I'll still count this as running in a VM anyway whether it's default virtualisation or manually intended virtualisation". |
| `VM::MULTIPLE` | This is specific to `VM::brand()`. This will basically return a `std::string` message of what brands could be involved. For example, it could return "`VMware or VirtualBox`" instead of having a single brand string output. This has no effect if applied to any other functions than `VM::brand()`. |
| `VM::HIGH_THRESHOLD` | This is specific to `VM::detect()` and `VM::percentage()`, which will set the threshold bar to confidently detect a VM by 3x higher. |
| `VM::SPOOFABLE` | This will enable all the "spoofable" techniques (which are 1/3 of the total amount of techniques) |
diff --git a/src/cli.cpp b/src/cli.cpp
index bfaaed9..1497802 100644
--- a/src/cli.cpp
+++ b/src/cli.cpp
@@ -137,7 +137,6 @@ R"(Usage:
-t | --type returns the VM type (if a VM was found)
Extra:
- --disable-hyperv-host disable the possibility of Hyper-V default virtualisation result on host OS
--disable-notes no notes will be provided
--spoofable allow spoofable techniques to be ran (not included by default)
@@ -247,6 +246,7 @@ Intel KGT (Trusty)
Microsoft Azure Hyper-V
Xbox NanoVisor (Hyper-V)
SimpleVisor
+Hyper-V artifact (not an actual VM)
)";
std::exit(0);
@@ -258,6 +258,7 @@ std::string type(const std::string &brand_str) {
}
const std::map type_table {
+ // type 1
{ "Xen HVM", "Hypervisor (type 1)" },
{ "VMware ESX", "Hypervisor (type 1)" },
{ "ACRN", "Hypervisor (type 1)" },
@@ -274,6 +275,7 @@ std::string type(const std::string &brand_str) {
{ "Intel KGT (Trusty)", "Hypervisor (type 1)" },
{ "SimpleVisor", "Hypervisor (type 1)" },
+ // type 2
{ "VirtualBox", "Hypervisor (type 2)" },
{ "VMware", "Hypervisor (type 2)" },
{ "VMware Express", "Hypervisor (type 2)" },
@@ -286,6 +288,7 @@ std::string type(const std::string &brand_str) {
{ "NetBSD NVMM", "Hypervisor (type 2)" },
{ "OpenBSD VMM", "Hypervisor (type 2)" },
+ // sandbox
{ "Cuckoo", "Sandbox" },
{ "Sandboxie", "Sandbox" },
{ "Hybrid Analysis", "Sandbox" },
@@ -295,6 +298,7 @@ std::string type(const std::string &brand_str) {
{ "Comodo", "Sandbox" },
{ "ThreatExpert", "Sandbox" },
+ // misc
{ "Bochs", "Emulator" },
{ "BlueStacks", "Emulator" },
{ "Microsoft x86-to-ARM", "Emulator" },
@@ -305,7 +309,8 @@ std::string type(const std::string &brand_str) {
{ "Microsoft Virtual PC/Hyper-V", "Hypervisor (either type 1 or 2)" },
{ "Lockheed Martin LMHS", "Hypervisor (unknown type)" },
{ "Wine", "Compatibility layer" },
- { "Apple VZ", "Unknown" }
+ { "Apple VZ", "Unknown" },
+ { "Hyper-V artifact (not an actual VM)", "No VM" }
};
auto it = type_table.find(brand_str);
@@ -551,6 +556,7 @@ void general() {
checker(VM::KVM_BITMASK, "KVM CPUID reserved bitmask");
checker(VM::KGT_SIGNATURE, "Intel KGT signature");
checker(VM::VMWARE_DMI, "VMware DMI");
+ checker(VM::EVENT_LOGS, "Hyper-V event logs");
std::printf("\n");
@@ -560,19 +566,24 @@ void general() {
std::string brand = VM::brand(VM::MULTIPLE, spoofable_setting);
- std::cout << "VM brand: " << (brand == "Unknown" ? red : green) << brand << ansi_exit << "\n";
+ std::cout << "VM brand: " << ((brand == "Unknown") || (brand == "Hyper-V artifact (not an actual VM)") ? red : green) << brand << ansi_exit << "\n";
+ // meaning "if there's no brand conflicts"
if (brand.find(" or ") == std::string::npos) {
- const std::string brand = VM::brand(VM::MULTIPLE, spoofable_setting);
- const std::string type_value = type(brand);
+ const std::string tmp_brand = VM::brand(VM::MULTIPLE, spoofable_setting);
+ const std::string type_value = type(tmp_brand);
std::cout << "VM type: ";
+
+ std::string color = "";
- if (type_value == "Unknown") {
- std::cout << red << "Unknown" << ansi_exit << "\n";
+ if (type_value == "Unknown" || type_value == "No VM") {
+ color = red;
} else {
- std::cout << green << type_value << ansi_exit << "\n";
+ color = green;
}
+
+ std::cout << color << type_value << ansi_exit << "\n";
}
const char* percent_color = "";
@@ -634,28 +645,8 @@ void general() {
<< "\n\n";
- auto is_hyperv_present = []() -> bool {
- std::map brand_map = VM::brand_map();
- bool is_hyperv_vpc_present = false;
-
- for (const auto p_brand : brand_map) {
- if (p_brand.second == 0) {
- continue;
- }
-
- if (
- (std::strcmp(p_brand.first, "Microsoft Hyper-V") == 0) ||
- (std::strcmp(p_brand.first, "Virtual PC") == 0)
- ) {
- is_hyperv_vpc_present = true;
- }
- }
-
- return is_hyperv_vpc_present;
- };
-
- if ((hyperv_setting == VM::ENABLE_HYPERV_HOST) && is_hyperv_present() && notes_enabled) {
- std::cout << note << " If you know you are running on host, Hyper-V leaves VM artifacts in CPUIDs which makes the system look like it's running in a Hyper-V VM when it's not. If you want to disable this mechanism, run with \"--disable-hyperv-host\", or disable Hyper-V in your system.\n\n";
+ if ((hyperv_setting == VM::ENABLE_HYPERV_HOST) && (brand == "Hyper-V artifact (not an actual VM)") && notes_enabled) {
+ std::cout << note << " If you know you are running on host, Hyper-V leaves VM artifacts in CPUIDs which makes the system look like it's running in a Hyper-V VM when it's not. If you want to disable this mechanism, uninstall Hyper-V in your system.\n\n";
} else if (notes_enabled) {
if (!arg_bitset.test(SPOOFABLE)) {
std::cout << tip << "To enable spoofable techniques, run with the \"--spoofable\" argument\n\n";
@@ -768,6 +759,9 @@ int main(int argc, char* argv[]) {
if (arg_bitset.test(HYPERV) == false) {
setting_bits.set(VM::ENABLE_HYPERV_HOST);
+ } else {
+ std::cerr << "--disable-hyperv-host has been deprecated, the determination of whether it's a host Hyper-V or VM Hyper-V is now done automatically";
+ return 1;
}
if (arg_bitset.test(SPOOFABLE)) {
diff --git a/src/vmaware.hpp b/src/vmaware.hpp
index d5a0b9f..2a57b3d 100644
--- a/src/vmaware.hpp
+++ b/src/vmaware.hpp
@@ -214,6 +214,7 @@
#include
#include
#include
+#include
#pragma comment(lib, "wbemuuid.lib")
#pragma comment(lib, "iphlpapi.lib")
@@ -225,6 +226,8 @@
#pragma comment(lib, "strmiids.lib")
#pragma comment(lib, "uuid.lib")
#pragma comment(lib, "ntdll.lib")
+#pragma comment(lib, "wevtapi.lib")
+
#ifdef _UNICODE
#define tregex std::wregex
@@ -408,6 +411,7 @@ struct VM {
KVM_BITMASK,
KGT_SIGNATURE,
VMWARE_DMI,
+ EVENT_LOGS,
// start of non-technique flags (THE ORDERING IS VERY SPECIFIC HERE AND MIGHT BREAK SOMETHING IF RE-ORDERED)
NO_MEMO,
@@ -1575,7 +1579,7 @@ struct VM {
#else
return false;
#endif
- }
+ }
[[nodiscard]] static std::string get_hostname() {
#if (MSVC)
@@ -1596,6 +1600,7 @@ struct VM {
return std::string();
}
+
/**
* @brief Checks whether Hyper-V host artifacts are present instead of an actual Hyper-V VM
* @note idea and credits to Requiem (https://github.com/NotRequiem)
@@ -1966,6 +1971,7 @@ struct VM {
unsigned long length = 0;
ret = RegQueryValueExW(hk, L"SMBiosData", 0, &type, 0, &length);
+
if (ret != ERROR_SUCCESS) {
RegCloseKey(hk);
debug("SMBIOS_string(): ret = error 2");
@@ -1986,6 +1992,7 @@ struct VM {
}
ret = RegQueryValueExW(hk, L"SMBiosData", 0, &type, reinterpret_cast(p), &length);
+
if (ret != ERROR_SUCCESS) {
LocalFree(p);
RegCloseKey(hk);
@@ -2179,8 +2186,132 @@ struct VM {
return is_vm;
}
+
+ /**
+ * @brief Retrieves the last error message from the Windows API. Useful for __VMAWARE_DEBUG__
+ *
+ * @author Requiem (https://github.com/NotRequiem)
+ *
+ * @return A std::wstring containing the error message.
+ */
+ [[nodiscard]] static std::wstring GetLastErrorString() {
+ DWORD error = GetLastError();
+ LPWSTR messageBuffer = nullptr;
+ size_t size = FormatMessageW(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ nullptr, error, 0, (LPWSTR)&messageBuffer, 0, nullptr
+ );
+
+ std::wstring message(messageBuffer, size);
+ LocalFree(messageBuffer);
+ return message;
+ }
+
+
+ /**
+ * @brief Searches for specific strings within events in a Windows Event Log.
+ *
+ * @param logName The name or path of the event log to search (e.g., "System", "Application", "Security", or a custom path).
+ * @param searchStrings A vector of strings to search for within the event messages.
+ * @param flags Query flags that define the direction of the search; default is EvtQueryReverseDirection.
+ * @param timeout The maximum amount of time (in milliseconds) to wait for events; default is INFINITE.
+ * @param maxEvents The maximum number of events to process; default is 1000.
+ *
+ * @author Requiem (https://github.com/NotRequiem)
+ *
+ * @return True if any of the search strings are found in the events; otherwise, false.
+ */
+ [[nodiscard]] static bool query_event_logs(const std::wstring& logName,
+ const std::vector& searchStrings,
+ DWORD flags = EvtQueryReverseDirection,
+ DWORD timeout = INFINITE,
+ DWORD maxEvents = 1000) {
+
+ EVT_HANDLE hLog = EvtOpenLog(nullptr, logName.c_str(), EvtOpenChannelPath);
+ if (!hLog) {
+ std::wcerr << L"Failed to open event log: " << logName << L". Error: " << GetLastErrorString() << std::endl;
+ return false;
+ }
+
+ EVT_HANDLE hResults = EvtQuery(nullptr, logName.c_str(), nullptr, flags);
+ if (!hResults) {
+ std::wcerr << L"Failed to query event log: " << logName << L". Error: " << GetLastErrorString() << std::endl;
+ EvtClose(hLog);
+ return false;
+ }
+
+ EVT_HANDLE hEvent = nullptr;
+ DWORD bufferUsed = 0;
+ DWORD bufferSize = 0;
+ DWORD count = 0;
+ WCHAR* pBuffer = nullptr;
+
+ // Iterate over events up to the maximum number specified
+ for (DWORD eventCount = 0; eventCount < maxEvents; ++eventCount) {
+ if (!EvtNext(hResults, 1, &hEvent, timeout, 0, &count)) {
+ if (GetLastError() == ERROR_NO_MORE_ITEMS) {
+ break; // No more events to process
+ }
+ std::wcerr << L"EvtNext failed. Error: " << GetLastErrorString() << std::endl;
+ EvtClose(hResults);
+ EvtClose(hLog);
+ return false;
+ }
+
+ if (!EvtRender(nullptr, hEvent, EvtRenderEventXml, 0, nullptr, &bufferUsed, &count) &&
+ GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+ bufferSize = bufferUsed;
+ pBuffer = new WCHAR[bufferSize];
+ if (!pBuffer) {
+ std::wcerr << L"Memory allocation failed." << std::endl;
+ EvtClose(hResults);
+ EvtClose(hLog);
+ return false;
+ }
+
+ if (!EvtRender(nullptr, hEvent, EvtRenderEventXml, bufferSize, pBuffer, &bufferUsed, &count)) {
+ std::wcerr << L"EvtRender failed. Error: " << GetLastErrorString() << std::endl;
+ delete[] pBuffer;
+ EvtClose(hResults);
+ EvtClose(hLog);
+ return false;
+ }
+ }
+ else {
+ std::wcerr << L"EvtRender failed. Error: " << GetLastErrorString() << std::endl;
+ EvtClose(hResults);
+ EvtClose(hLog);
+ return false;
+ }
+
+ std::wstring eventMessage(pBuffer);
+ delete[] pBuffer;
+
+ // Check if any of the search strings are found in the event message, not in the event name
+ bool found = false;
+ for (const auto& searchString : searchStrings) {
+ if (eventMessage.find(searchString) != std::wstring::npos) {
+ found = true;
+ break;
+ }
+ }
+
+ if (found) {
+ EvtClose(hResults);
+ EvtClose(hLog);
+ return true;
+ }
+
+ EvtClose(hEvent);
+ }
+
+ EvtClose(hResults);
+ EvtClose(hLog);
+
+ return false;
+ }
#endif
- };
+ };
private: // START OF PRIVATE VM DETECTION TECHNIQUE DEFINITIONS
@@ -7953,31 +8084,31 @@ struct VM {
return false; // returned false because we want the most feature leafs as possible for Hyper-V
}
- /* this is just a tool to check if all the arrows (^) are aligned correctly, think of it as a ruler and ignore this lol
- ||||||||||||||||||||||9876543210
- |||||||||||||||||||||10
- ||||||||||||||||||||11
- |||||||||||||||||||12
- ||||||||||||||||||13
- |||||||||||||||||14
- ||||||||||||||||15
- |||||||||||||||16
- ||||||||||||||17
- |||||||||||||18
- ||||||||||||19
- |||||||||||20
- ||||||||||21
- |||||||||22
- ||||||||23
- |||||||24
- ||||||25
- |||||26
- ||||27
- |||28
- ||29
- |30
- 31
- */
+/* this is just an ascii tool to check if all the arrows (^) are aligned correctly based on bit position, think of it as a ruler. (ignore this btw)
+||||||||||||||||||||||9876543210
+|||||||||||||||||||||10
+||||||||||||||||||||11
+|||||||||||||||||||12
+||||||||||||||||||13
+|||||||||||||||||14
+||||||||||||||||15
+|||||||||||||||16
+||||||||||||||17
+|||||||||||||18
+||||||||||||19
+|||||||||||20
+||||||||||21
+|||||||||22
+||||||||23
+|||||||24
+||||||25
+|||||26
+||||27
+|||28
+||29
+|30
+31
+*/
auto leaf_01 = [&]() -> bool {
u32 eax, ebx, ecx, edx = 0;
@@ -8284,10 +8415,33 @@ struct VM {
}
+ /**
+ * @brief Check for presence of Hyper-V in the Windows Event Logs
+ *
+ * @author Requiem (https://github.com/NotRequiem)
+ *
+ * @category Windows
+ */
+ [[nodiscard]] static bool hyperv_event_logs() try {
+#if (!MSVC)
+ return false;
+#else
+ // Define the log name and search strings
+ std::wstring logName = L"Microsoft-Windows-Kernel-PnP/Configuration"; // Example: "System", "Application", "Security", or a custom path. In this case, we use Microsoft-Windows-Kernel-PnP/Configuration as a Hyper-V VM artifact
+ std::vector searchStrings = { L"Virtual_Machine", L"VMBUS" };
+ bool found = util::query_event_logs(logName, searchStrings);
+ if (found) {
+ return core::add(HYPERV);
+ }
-
+ return false;
+#endif
+ } catch (...) {
+ debug("EVENT_LOGS: caught error, returned false");
+ return false;
+ }
@@ -8557,7 +8711,7 @@ struct VM {
if (flag == SPOOFABLE) {
for (const auto& tmp : technique_table) {
const u8 technique_macro = tmp.first;
- const technique& tuple = tmp.second;
+ const technique &tuple = tmp.second;
if (tuple.spoofable) {
flag_collector.set(technique_macro);
@@ -8903,32 +9057,32 @@ struct VM {
brands.emplace(std::make_pair(TMP_HYPERV_VPC, 2));
}
- merger(TMP_HYPERV, TMP_HYPERV_ARTIFACT, TMP_HYPERV_ARTIFACT);
- merger(TMP_VPC, TMP_HYPERV_ARTIFACT, TMP_HYPERV_ARTIFACT);
+ merger(TMP_HYPERV, TMP_HYPERV_ARTIFACT, TMP_HYPERV_ARTIFACT);
+ merger(TMP_VPC, TMP_HYPERV_ARTIFACT, TMP_HYPERV_ARTIFACT);
merger(TMP_HYPERV_VPC, TMP_HYPERV_ARTIFACT, TMP_HYPERV_ARTIFACT);
- merger(TMP_AZURE, TMP_HYPERV, TMP_AZURE);
- merger(TMP_AZURE, TMP_VPC, TMP_AZURE);
+ merger(TMP_AZURE, TMP_HYPERV, TMP_AZURE);
+ merger(TMP_AZURE, TMP_VPC, TMP_AZURE);
merger(TMP_AZURE, TMP_HYPERV_VPC, TMP_AZURE);
- merger(TMP_NANOVISOR, TMP_HYPERV, TMP_NANOVISOR);
- merger(TMP_NANOVISOR, TMP_VPC, TMP_NANOVISOR);
+ merger(TMP_NANOVISOR, TMP_HYPERV, TMP_NANOVISOR);
+ merger(TMP_NANOVISOR, TMP_VPC, TMP_NANOVISOR);
merger(TMP_NANOVISOR, TMP_HYPERV_VPC, TMP_NANOVISOR);
-
- merger(TMP_QEMU, TMP_KVM, TMP_QEMU_KVM);
- merger(TMP_KVM, TMP_HYPERV, TMP_KVM_HYPERV);
- merger(TMP_QEMU, TMP_HYPERV, TMP_QEMU_KVM_HYPERV);
- merger(TMP_QEMU_KVM, TMP_HYPERV, TMP_QEMU_KVM_HYPERV);
- merger(TMP_KVM, TMP_KVM_HYPERV, TMP_KVM_HYPERV);
- merger(TMP_QEMU, TMP_KVM_HYPERV, TMP_QEMU_KVM_HYPERV);
- merger(TMP_QEMU_KVM, TMP_KVM_HYPERV, TMP_QEMU_KVM_HYPERV);
+
+ merger(TMP_QEMU, TMP_KVM, TMP_QEMU_KVM);
+ merger(TMP_KVM, TMP_HYPERV, TMP_KVM_HYPERV);
+ merger(TMP_QEMU, TMP_HYPERV, TMP_QEMU_KVM_HYPERV);
+ merger(TMP_QEMU_KVM, TMP_HYPERV, TMP_QEMU_KVM_HYPERV);
+ merger(TMP_KVM, TMP_KVM_HYPERV, TMP_KVM_HYPERV);
+ merger(TMP_QEMU, TMP_KVM_HYPERV, TMP_QEMU_KVM_HYPERV);
+ merger(TMP_QEMU_KVM, TMP_KVM_HYPERV, TMP_QEMU_KVM_HYPERV);
triple_merger(TMP_QEMU, TMP_KVM, TMP_KVM_HYPERV, TMP_QEMU_KVM_HYPERV);
- merger(TMP_VMWARE, TMP_FUSION, TMP_FUSION);
- merger(TMP_VMWARE, TMP_EXPRESS, TMP_EXPRESS);
- merger(TMP_VMWARE, TMP_ESX, TMP_ESX);
- merger(TMP_VMWARE, TMP_GSX, TMP_GSX);
+ merger(TMP_VMWARE, TMP_FUSION, TMP_FUSION);
+ merger(TMP_VMWARE, TMP_EXPRESS, TMP_EXPRESS);
+ merger(TMP_VMWARE, TMP_ESX, TMP_ESX);
+ merger(TMP_VMWARE, TMP_GSX, TMP_GSX);
merger(TMP_VMWARE, TMP_WORKSTATION, TMP_WORKSTATION);
using brand_element_t = std::pair;
@@ -9164,14 +9318,14 @@ struct VM {
using table_t = std::map;
- auto modify = [](table_t& table, const enum_flags flag, const u8 percent) -> void {
- core::technique& tmp = table.at(flag);
+ auto modify = [](table_t &table, const enum_flags flag, const u8 percent) -> void {
+ core::technique &tmp = table.at(flag);
table[flag] = { percent, tmp.run, tmp.spoofable };
};
modify(const_cast(core::technique_table), flag, percent);
}
- };
+};
MSVC_ENABLE_WARNING(ASSIGNMENT_OPERATOR NO_INLINE_FUNC SPECTRE)
@@ -9257,6 +9411,8 @@ VM::flagset VM::DEFAULT = []() -> flagset {
// disable all the non-default flags
tmp.flip(NO_MEMO);
tmp.flip(CURSOR);
+ tmp.flip(RDTSC);
+ tmp.flip(RDTSC_VMEXIT);
tmp.flip(HIGH_THRESHOLD);
tmp.flip(ENABLE_HYPERV_HOST);
tmp.flip(SPOOFABLE);
@@ -9315,104 +9471,105 @@ std::vector VM::core::custom_table = {
const std::map VM::core::technique_table = {
// FORMAT: VM:: = { certainty%, function pointer, is spoofable? }
- { VM::VMID, { 100, VM::vmid, false }},
- { VM::CPU_BRAND, { 50, VM::cpu_brand, false }},
- { VM::HYPERVISOR_BIT, { 100, VM::hypervisor_bit , false}},
- { VM::HYPERVISOR_STR, { 45, VM::hypervisor_str, false }},
- { VM::RDTSC, { 10, VM::rdtsc_check, false }},
- { VM::THREADCOUNT, { 35, VM::thread_count, false }},
- { VM::MAC, { 60, VM::mac_address_check, true }},
- { VM::TEMPERATURE, { 15, VM::temperature, false }},
- { VM::SYSTEMD, { 70, VM::systemd_virt, false }},
- { VM::CVENDOR, { 65, VM::chassis_vendor, false }},
- { VM::CTYPE, { 10, VM::chassis_type, false }},
- { VM::DOCKERENV, { 80, VM::dockerenv, true }},
- { VM::DMIDECODE, { 55, VM::dmidecode, false }},
- { VM::DMESG, { 55, VM::dmesg, false }},
- { VM::HWMON, { 75, VM::hwmon, true }},
- { VM::SIDT5, { 45, VM::sidt5, false }},
- { VM::CURSOR, { 5, VM::cursor_check, true }},
- { VM::VMWARE_REG, { 65, VM::vmware_registry, true }},
- { VM::VBOX_REG, { 65, VM::vbox_registry, true }},
- { VM::USER, { 35, VM::user_check, true }},
- { VM::DLL, { 50, VM::DLL_check, true }},
- { VM::REGISTRY, { 75, VM::registry_key, true }},
- { VM::CWSANDBOX_VM, { 10, VM::cwsandbox_check, true }},
- { VM::VM_FILES, { 60, VM::vm_files, true }},
- { VM::HWMODEL, { 75, VM::hwmodel, true }},
- { VM::DISK_SIZE, { 60, VM::disk_size, false }},
- { VM::VBOX_DEFAULT, { 55, VM::vbox_default_specs, false }},
- { VM::VBOX_NETWORK, { 70, VM::vbox_network_share, false }},
- { VM::WINE_CHECK, { 85, VM::wine, false }}, // GPL
- { VM::COMPUTER_NAME, { 15, VM::computer_name_match, true }}, // GPL
- { VM::HOSTNAME, { 25, VM::hostname_match, true }}, // GPL
- { VM::MEMORY, { 35, VM::low_memory_space, false }}, // GPL
- { VM::VBOX_WINDOW_CLASS, { 10, VM::vbox_window_class, false }}, // GPL
- { VM::KVM_REG, { 75, VM::kvm_registry, true }}, // GPL
- { VM::KVM_DRIVERS, { 55, VM::kvm_drivers, true }}, // GPL
- { VM::KVM_DIRS, { 55, VM::kvm_directories, true }}, // GPL
- { VM::LOADED_DLLS, { 75, VM::loaded_dlls, true }}, // GPL
- { VM::AUDIO, { 35, VM::check_audio, false }}, // GPL
- { VM::QEMU_DIR, { 45, VM::qemu_dir, true }}, // GPL
- { VM::MOUSE_DEVICE, { 20, VM::mouse_device, true }}, // GPL
- { VM::VM_PROCESSES, { 30, VM::vm_processes, true }},
- { VM::LINUX_USER_HOST, { 25, VM::linux_user_host, true }},
- { VM::GAMARUE, { 40, VM::gamarue, false }},
- { VM::VMID_0X4, { 90, VM::vmid_0x4, false }},
- { VM::PARALLELS_VM, { 50, VM::parallels, false }},
- { VM::RDTSC_VMEXIT, { 25, VM::rdtsc_vmexit, false }},
- { VM::QEMU_BRAND, { 100, VM::cpu_brand_qemu, false }},
- { VM::BOCHS_CPU, { 95, VM::bochs_cpu, false }},
- { VM::VPC_BOARD, { 20, VM::vpc_board, false }},
- { VM::HYPERV_WMI, { 80, VM::hyperv_wmi, false }},
- { VM::HYPERV_REG, { 80, VM::hyperv_registry, true }},
- { VM::BIOS_SERIAL, { 60, VM::bios_serial, false }},
- { VM::VBOX_FOLDERS, { 45, VM::vbox_shared_folders, false }},
- { VM::MSSMBIOS, { 75, VM::mssmbios, false }},
- { VM::MAC_MEMSIZE, { 30, VM::hw_memsize, true }},
- { VM::MAC_IOKIT, { 80, VM::io_kit, true }},
- { VM::IOREG_GREP, { 75, VM::ioreg_grep, true }},
- { VM::MAC_SIP, { 85, VM::mac_sip, true }},
- { VM::HKLM_REGISTRIES, { 70, VM::hklm_registries, true }},
- { VM::QEMU_GA, { 20, VM::qemu_ga, true }},
- { VM::VALID_MSR, { 35, VM::valid_msr, false }},
- { VM::QEMU_PROC, { 30, VM::qemu_processes, true }},
- { VM::VPC_PROC, { 30, VM::vpc_proc, true }},
- { VM::VPC_INVALID, { 75, VM::vpc_invalid, false }},
- { VM::SIDT, { 30, VM::sidt, false }},
- { VM::SGDT, { 30, VM::sgdt, false }},
- { VM::SLDT, { 15, VM::sldt, false }},
- { VM::OFFSEC_SIDT, { 60, VM::offsec_sidt, false }},
- { VM::OFFSEC_SGDT, { 60, VM::offsec_sgdt, false }},
- { VM::OFFSEC_SLDT, { 20, VM::offsec_sldt, false }},
- { VM::VPC_SIDT, { 15, VM::vpc_sidt, false }},
- { VM::HYPERV_BOARD, { 45, VM::hyperv_board, false }},
- { VM::VM_FILES_EXTRA, { 70, VM::vm_files_extra, true }},
- { VM::VMWARE_IOMEM, { 65, VM::vmware_iomem, false }},
- { VM::VMWARE_IOPORTS, { 70, VM::vmware_ioports, false }},
- { VM::VMWARE_SCSI, { 40, VM::vmware_scsi, false }},
- { VM::VMWARE_DMESG, { 65, VM::vmware_dmesg, false }},
- { VM::VMWARE_STR, { 35, VM::vmware_str, false }},
- { VM::VMWARE_BACKDOOR, { 100, VM::vmware_backdoor, false }},
- { VM::VMWARE_PORT_MEM, { 85, VM::vmware_port_memory, false }},
- { VM::SMSW, { 30, VM::smsw, false }},
- { VM::MUTEX, { 85, VM::mutex, false }},
- { VM::UPTIME, { 10, VM::uptime, true }},
- { VM::ODD_CPU_THREADS, { 80, VM::odd_cpu_threads, false }},
- { VM::INTEL_THREAD_MISMATCH, { 85, VM::intel_thread_mismatch, false }},
- { VM::XEON_THREAD_MISMATCH, { 85, VM::xeon_thread_mismatch, false }},
- { VM::NETTITUDE_VM_MEMORY, { 75, VM::nettitude_vm_memory, false }},
- { VM::CPUID_BITSET, { 20, VM::cpuid_bitset, false }},
- { VM::CUCKOO_DIR, { 15, VM::cuckoo_dir, true }},
- { VM::CUCKOO_PIPE, { 20, VM::cuckoo_pipe, true }},
- { VM::HYPERV_HOSTNAME, { 50, VM::hyperv_hostname, true }},
- { VM::GENERAL_HOSTNAME, { 20, VM::general_hostname, true }},
- { VM::SCREEN_RESOLUTION, { 30, VM::screen_resolution, false }},
- { VM::DEVICE_STRING, { 25, VM::device_string, false }},
- { VM::BLUESTACKS_FOLDERS, { 15, VM::bluestacks, true }},
- { VM::CPUID_SIGNATURE, { 95, VM::cpuid_signature, false }},
- { VM::HYPERV_BITMASK, { 20, VM::hyperv_bitmask, false }},
- { VM::KVM_BITMASK, { 40, VM::kvm_bitmask, false }},
- { VM::KGT_SIGNATURE, { 80, VM::intel_kgt_signature, false }},
- { VM::VMWARE_DMI, { 30, VM::vmware_dmi, false }}
+ { VM::VMID, { 100, VM::vmid, false } },
+ { VM::CPU_BRAND, { 50, VM::cpu_brand, false } },
+ { VM::HYPERVISOR_BIT, { 100, VM::hypervisor_bit , false}} ,
+ { VM::HYPERVISOR_STR, { 45, VM::hypervisor_str, false } },
+ { VM::RDTSC, { 10, VM::rdtsc_check, false } },
+ { VM::THREADCOUNT, { 35, VM::thread_count, false } },
+ { VM::MAC, { 60, VM::mac_address_check, true } },
+ { VM::TEMPERATURE, { 15, VM::temperature, false } },
+ { VM::SYSTEMD, { 70, VM::systemd_virt, false } },
+ { VM::CVENDOR, { 65, VM::chassis_vendor, false } },
+ { VM::CTYPE, { 10, VM::chassis_type, false } },
+ { VM::DOCKERENV, { 80, VM::dockerenv, true } },
+ { VM::DMIDECODE, { 55, VM::dmidecode, false } },
+ { VM::DMESG, { 55, VM::dmesg, false } },
+ { VM::HWMON, { 75, VM::hwmon, true } },
+ { VM::SIDT5, { 45, VM::sidt5, false } },
+ { VM::CURSOR, { 5, VM::cursor_check, true } },
+ { VM::VMWARE_REG, { 65, VM::vmware_registry, true } },
+ { VM::VBOX_REG, { 65, VM::vbox_registry, true } },
+ { VM::USER, { 35, VM::user_check, true } },
+ { VM::DLL, { 50, VM::DLL_check, true } },
+ { VM::REGISTRY, { 75, VM::registry_key, true } },
+ { VM::CWSANDBOX_VM, { 10, VM::cwsandbox_check, true } },
+ { VM::VM_FILES, { 60, VM::vm_files, true } },
+ { VM::HWMODEL, { 75, VM::hwmodel, true } },
+ { VM::DISK_SIZE, { 60, VM::disk_size, false } },
+ { VM::VBOX_DEFAULT, { 55, VM::vbox_default_specs, false } },
+ { VM::VBOX_NETWORK, { 70, VM::vbox_network_share, false } },
+ { VM::WINE_CHECK, { 85, VM::wine, false } }, // GPL
+ { VM::COMPUTER_NAME, { 15, VM::computer_name_match, true } }, // GPL
+ { VM::HOSTNAME, { 25, VM::hostname_match, true } }, // GPL
+ { VM::MEMORY, { 35, VM::low_memory_space, false } }, // GPL
+ { VM::VBOX_WINDOW_CLASS, { 10, VM::vbox_window_class, false } }, // GPL
+ { VM::KVM_REG, { 75, VM::kvm_registry, true } }, // GPL
+ { VM::KVM_DRIVERS, { 55, VM::kvm_drivers, true } }, // GPL
+ { VM::KVM_DIRS, { 55, VM::kvm_directories, true } }, // GPL
+ { VM::LOADED_DLLS, { 75, VM::loaded_dlls, true } }, // GPL
+ { VM::AUDIO, { 35, VM::check_audio, false } }, // GPL
+ { VM::QEMU_DIR, { 45, VM::qemu_dir, true } }, // GPL
+ { VM::MOUSE_DEVICE, { 20, VM::mouse_device, true } }, // GPL
+ { VM::VM_PROCESSES, { 30, VM::vm_processes, true } },
+ { VM::LINUX_USER_HOST, { 25, VM::linux_user_host, true } },
+ { VM::GAMARUE, { 40, VM::gamarue, false } },
+ { VM::VMID_0X4, { 90, VM::vmid_0x4, false } },
+ { VM::PARALLELS_VM, { 50, VM::parallels, false } },
+ { VM::RDTSC_VMEXIT, { 15, VM::rdtsc_vmexit, false } },
+ { VM::QEMU_BRAND, { 100, VM::cpu_brand_qemu, false } },
+ { VM::BOCHS_CPU, { 95, VM::bochs_cpu, false } },
+ { VM::VPC_BOARD, { 20, VM::vpc_board, false } },
+ { VM::HYPERV_WMI, { 80, VM::hyperv_wmi, false } },
+ { VM::HYPERV_REG, { 80, VM::hyperv_registry, true } },
+ { VM::BIOS_SERIAL, { 60, VM::bios_serial, false } },
+ { VM::VBOX_FOLDERS, { 45, VM::vbox_shared_folders, false } },
+ { VM::MSSMBIOS, { 75, VM::mssmbios, false } },
+ { VM::MAC_MEMSIZE, { 30, VM::hw_memsize, true } },
+ { VM::MAC_IOKIT, { 80, VM::io_kit, true } },
+ { VM::IOREG_GREP, { 75, VM::ioreg_grep, true } },
+ { VM::MAC_SIP, { 85, VM::mac_sip, true } },
+ { VM::HKLM_REGISTRIES, { 70, VM::hklm_registries, true } },
+ { VM::QEMU_GA, { 20, VM::qemu_ga, true } },
+ { VM::VALID_MSR, { 35, VM::valid_msr, false } },
+ { VM::QEMU_PROC, { 30, VM::qemu_processes, true } },
+ { VM::VPC_PROC, { 30, VM::vpc_proc, true } },
+ { VM::VPC_INVALID, { 75, VM::vpc_invalid, false } },
+ { VM::SIDT, { 30, VM::sidt, false } },
+ { VM::SGDT, { 30, VM::sgdt, false } },
+ { VM::SLDT, { 15, VM::sldt, false } },
+ { VM::OFFSEC_SIDT, { 60, VM::offsec_sidt, false } },
+ { VM::OFFSEC_SGDT, { 60, VM::offsec_sgdt, false } },
+ { VM::OFFSEC_SLDT, { 20, VM::offsec_sldt, false } },
+ { VM::VPC_SIDT, { 15, VM::vpc_sidt, false } },
+ { VM::HYPERV_BOARD, { 45, VM::hyperv_board, false } },
+ { VM::VM_FILES_EXTRA, { 70, VM::vm_files_extra, true } },
+ { VM::VMWARE_IOMEM, { 65, VM::vmware_iomem, false } },
+ { VM::VMWARE_IOPORTS, { 70, VM::vmware_ioports, false } },
+ { VM::VMWARE_SCSI, { 40, VM::vmware_scsi, false } },
+ { VM::VMWARE_DMESG, { 65, VM::vmware_dmesg, false } },
+ { VM::VMWARE_STR, { 35, VM::vmware_str, false } },
+ { VM::VMWARE_BACKDOOR, { 100, VM::vmware_backdoor, false } },
+ { VM::VMWARE_PORT_MEM, { 85, VM::vmware_port_memory, false } },
+ { VM::SMSW, { 30, VM::smsw, false } },
+ { VM::MUTEX, { 85, VM::mutex, false } },
+ { VM::UPTIME, { 10, VM::uptime, true } },
+ { VM::ODD_CPU_THREADS, { 80, VM::odd_cpu_threads, false } },
+ { VM::INTEL_THREAD_MISMATCH, { 85, VM::intel_thread_mismatch, false } },
+ { VM::XEON_THREAD_MISMATCH, { 85, VM::xeon_thread_mismatch, false } },
+ { VM::NETTITUDE_VM_MEMORY, { 75, VM::nettitude_vm_memory, false } },
+ { VM::CPUID_BITSET, { 20, VM::cpuid_bitset, false } },
+ { VM::CUCKOO_DIR, { 15, VM::cuckoo_dir, true } },
+ { VM::CUCKOO_PIPE, { 20, VM::cuckoo_pipe, true } },
+ { VM::HYPERV_HOSTNAME, { 50, VM::hyperv_hostname, true } },
+ { VM::GENERAL_HOSTNAME, { 20, VM::general_hostname, true } },
+ { VM::SCREEN_RESOLUTION, { 30, VM::screen_resolution, false } },
+ { VM::DEVICE_STRING, { 25, VM::device_string, false } },
+ { VM::BLUESTACKS_FOLDERS, { 15, VM::bluestacks, true } },
+ { VM::CPUID_SIGNATURE, { 95, VM::cpuid_signature, false } },
+ { VM::HYPERV_BITMASK, { 20, VM::hyperv_bitmask, false } },
+ { VM::KVM_BITMASK, { 40, VM::kvm_bitmask, false } },
+ { VM::KGT_SIGNATURE, { 80, VM::intel_kgt_signature, false } },
+ { VM::VMWARE_DMI, { 30, VM::vmware_dmi, false } },
+ { VM::EVENT_LOGS, { 30, VM::hyperv_event_logs, true } }
};
\ No newline at end of file