Skip to content

Commit

Permalink
misc changes and added VM::MICROSOFT_EMU technique
Browse files Browse the repository at this point in the history
  • Loading branch information
kernelwernel committed Jan 22, 2025
1 parent da80326 commit 5e377b9
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 27 deletions.
1 change: 1 addition & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
- [ ] update the conclusion with the VM type
- [ ] add a description of every vm brand detected in the CLI
- [ ] make a hardware scanner module where it'll find for VM strings in all sorts of devices
- [ ] add more QEMU techniques

# Distant plans
- add the library to conan.io when released
Expand Down
18 changes: 10 additions & 8 deletions docs/documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ This is basically the main function you're looking for, which returns a bool. If
int main() {
/**
* The basic way to detect a VM where the default checks will
* be performed. This is the recommended usage of the library.
* be performed. This is the recommended usage of the lib.
*/
bool is_vm = VM::detect();

Expand Down Expand Up @@ -456,19 +456,19 @@ VMAware provides a convenient way to not only check for VMs, but also have the f
| `VM::LSHW_QEMU` | Check for QEMU string instances with lshw command | Linux | 80% | | | | |
| `VM::VIRTUAL_PROCESSORS` | Checks if the number of maximum virtual processors matches the maximum number of logical processors | Windows | 50% | | | | |
| `VM::MOTHERBOARD_PRODUCT` | Check if the motherboard product string matches "Virtual Machine" | Windows | 50% | | | | |
| `VM::HVLQUERYDETAILINFO` | Checks if a call to NtQuerySystemInformation with the 0x9f leaf fills a _SYSTEM_HYPERVISOR_DETAIL_INFORMATION structure | Windows | 50% | | | | |

| `VM::HYPERV_QUERY` | Checks if a call to NtQuerySystemInformation with the 0x9f leaf fills a _SYSTEM_HYPERVISOR_DETAIL_INFORMATION structure | Windows | 50% | | | | |
| `VM::MICROSOFT_EMU` | Check for x86 emulation by a "Windows on ARM" OS | Windows | 60% | | | | |
<!-- ADD DETAILS HERE -->

<br>

# Brand table

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

| String | Variable alias | VM type | Notes |
| -------------- | ------ | ------- | ----- |
| Unknown | `VM::brands::NULL_BRAND` | Unknown | |
| Unknown | `VM::brands::NULL_BRAND` | Unknown | This is the default brand it returns if none were found |
| VirtualBox | `VM::brands::VBOX` | Hypervisor (type 2) | |
| VMware | `VM::brands::VMWARE` | Hypervisor (type 2) | |
| VMware Express | `VM::brands::VMWARE_EXPRESS` | Hypervisor (type 2) | |
Expand All @@ -494,7 +494,7 @@ This is the table of all the brands the library supports.
| Sandboxie | `VM::brands::SANDBOXIE` | Sandbox | |
| Docker | `VM::brands::DOCKER` | Container | |
| Wine | `VM::brands::WINE` | Compatibility layer | |
| Apple Rosetta 2 | `VM::brands::APPLE_ROSETTA` | Binary Translation Layer/Emulator | |
| Apple Rosetta 2 | `VM::brands::APPLE_ROSETTA` | Binary Translation Layer/Emulator | Debatable if this should even be in the lib in the first place |
| Virtual PC | `VM::brands::VPC` | Hypervisor (type 2) | |
| Anubis | `VM::brands::ANUBIS` | Sandbox | |
| JoeBox | `VM::brands::JOEBOX` | Sandbox | |
Expand All @@ -506,7 +506,7 @@ This is the table of all the brands the library supports.
| OpenBSD VMM | `VM::brands::BSD_VMM` | Hypervisor (type 2) | |
| Intel HAXM | `VM::brands::INTEL_HAXM` | Hypervisor (type 1) | |
| Unisys s-Par | `VM::brands::UNISYS` | Partitioning Hypervisor | |
| Lockheed Martin LMHS | `VM::brands::LMHS` | Hypervisor (unknown type) | Yes, you read that right. The library can detect VMs running on US military fighter jets, apparently |
| Lockheed Martin LMHS | `VM::brands::LMHS` | Hypervisor (unknown type) | Yes, you read that right. The lib can detect VMs running on US military fighter jets, apparently |
| Cuckoo | `VM::brands::CUCKOO` | Sandbox | |
| BlueStacks | `VM::brands::BLUESTACKS` | Emulator | |
| Jailhouse | `VM::brands::JAILHOUSE` | Partitioning Hypervisor | |
Expand All @@ -523,12 +523,14 @@ This is the table of all the brands the library supports.
| KubeVirt (KVM) | `VM::brands::KUBEVIRT` | Hypervisor (type 1) | |
| AWS Nitro System EC2 (KVM-based) | `VM::brands::AWS_NITRO` | Hypervisor (type 1) | |
| Podman | `VM::brands::PODMAN` | Container | |
| WSL | `VM::brands::WSL` | Hybrid Hyper-V (type 1 and 2) | The type is debatable |
| WSL | `VM::brands::WSL` | Hybrid Hyper-V (type 1 and 2) | The type is debatable, it's not exactly clear |
| OpenVZ | `VM::brands::OPENVZ` | Container | |
| ANY.RUN | N/A | Sandbox | Removed from the lib, available only in the CLI |
| Barevisor | `VM::brands::BAREVISOR` | Hypervisor (type 1) | |
| HyperPlatform | `VM::brands::HYPERPLATFORM` | Hypervisor (type 1) | |
| MiniVisor | `VM::brands::MINIVISOR` | Hypervisor (type 1) | |
| Microsoft Prism | `VM::brands::MICROSOFT_PRISM` | Emulator | |
| Microsoft x86 Emulator | `VM::brands::MICROSOFT_X86_EMU` | Emulator | |

<br>

Expand Down
29 changes: 15 additions & 14 deletions src/cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
#define WINDOWS 1
#include <windows.h>
#else
#define MSVC 0
#define WINDOWS 0
#endif

#if (MSVC)
Expand Down Expand Up @@ -141,7 +141,7 @@ R"(Usage:
Options:
-h | --help prints this help menu
-v | --version print cli version and other details
-v | --version print CLI version and other details
-a | --all run the result with ALL the techniques enabled (might contain false positives)
-d | --detect returns the result as a boolean (1 = VM, 0 = baremetal)
-s | --stdout returns either 0 or 1 to STDOUT without any text output (0 = VM, 1 = baremetal)
Expand Down Expand Up @@ -465,11 +465,9 @@ bool is_unsupported(VM::enum_flags flag) {
case VM::SETUPAPI_DISK:
case VM::VMWARE_HARDENER:
case VM::VIRTUAL_PROCESSORS:
<<<<<<< HEAD
=======
case VM::MOTHERBOARD_PRODUCT:
case VM::HVLQUERYDETAILINFO:
>>>>>>> d6b88811dd5e1f0b73c8a3fd08718ccab5294f75
case VM::HYPERV_QUERY:
case VM::MICROSOFT_EMU:
// ADD WINDOWS FLAG
return false;
default: return true;
Expand Down Expand Up @@ -585,8 +583,8 @@ std::string vm_description(const std::string& vm_brand) {
{ VM::brands::VMWARE_HARD, "" },
{ VM::brands::BHYVE, "bhyve (pronounced \"bee hive\", formerly written as BHyVe for \"BSD hypervisor\") is a free type 2 hosted hypervisor initially written for FreeBSD. It can also be used on a number of illumos based distributions including SmartOS, OpenIndiana, and OmniOS. bhyve has a modern codebase and uses fewer resources compared to its competitors. In the case of FreeBSD, the resource management is more efficient." },
{ VM::brands::KVM, "KVM is a free and open source module of the Linux kernel released in 2007. It uses hardware virtualization extensions, and has had support for hot swappable vCPUs, dynamic memory management, and Live Migration. It also reduces the impact that memory write-intensive workloads have on the migration process. KVM emulates very little hardware components, and it defers to a higher-level client application such as QEMU." },
{ VM::brands::QEMU, "" },
{ VM::brands::QEMU_KVM, "" },
{ VM::brands::QEMU, "The Quick Emulator (QEMU) is a free and open-source emulator that uses dynamic binary translation to emulate a computer's processor. It translates the emulated binary codes to an equivalent binary format which is executed by the machine. It provides a variety of hardware and device models for the VM, while often being combined with KVM. However, no concrete evidence of KVM was found for this system." },
{ VM::brands::QEMU_KVM, "The Quick Emulator (QEMU) is a free and open-source emulator that uses dynamic binary translation to emulate a computer's processor. It translates the emulated binary codes to an equivalent binary format which is executed by the machine. It provides a variety of hardware and device models for the VM, while often being combined with KVM which the library has detected as the case for this system." },
{ VM::brands::KVM_HYPERV, "" },
{ VM::brands::QEMU_KVM_HYPERV, "" },
{ VM::brands::HYPERV, "Hyper-V is Microsoft's proprietary native hypervisor that can create x86 VMs on Windows. Released in 2008, it supercedes previous virtualization solutions such as Microsoft Virtual Server and Windows VirtualPC. Hyper-V uses partitioning to isolate the guest OSs, and has \"enlightenment\" features for bypassing device emulation layers, allowing for faster execution including when Windows is virtualization on Linux." },
Expand All @@ -606,22 +604,22 @@ std::string vm_description(const std::string& vm_brand) {
{ VM::brands::JOEBOX, "" },
{ VM::brands::THREATEXPERT, "" },
{ VM::brands::CWSANDBOX, "" },
{ VM::brands::COMODO, "" },
{ VM::brands::COMODO, "Comodo is a proprietary sandbox running an isolated operating environment. Comodo have integrated sandboxing technology directly into the security architecture of Comodo Internet Security to complement and strengthen the Firewall, Defense+ and Antivirus modules of their product line. It features a hybrid of user mode hooks along with a kernel mode driver, preventing any modification to files or registry on the host machine." },
{ VM::brands::BOCHS, "Bochs (pronounced \"box\") is a free and open-source portable IA-32 and x86-64 IBM PC compatible emulator and debugger mostly written in C++. Bochs is mostly used for OS development and to run other guest OSs inside already running host OSs, while emulating the hardware needed such as hard drives, CD drives, and floppy drives. It doesn't utilize any host CPU virtualization features, therefore is slower than most virtualization software." },
{ VM::brands::NVMM, "NVMM (NetBSD Virtual Machine Monitor) is NetBSD's native hypervisor for NetBSD 9.0. It provides a virtualization API, libnvmm, that can be leveraged by emulators such as QEMU. A unique property of NVMM is that the kernel never accesses guest VM memory, only creating it. Intel's Hardware Accelerated Execution Manager (HAXM) provides an alternative solution for acceleration in QEMU for Intel CPUs only, similar to Linux's KVM." },
{ VM::brands::BSD_VMM, "" },
{ VM::brands::INTEL_HAXM, "" },
{ VM::brands::INTEL_HAXM, "HAXM is a cross-platform hardware-assisted virtualization engine (hypervisor), widely used as an accelerator for Android Emulator and QEMU. HAXM runs as a kernel-mode driver on the host operating system thereby enabling applications like QEMU to utilize the hardware virtualization capabilities built into modern Intel CPUs, namely Intel Virtualization Technology. The project has been discontinued as of 2023." },
{ VM::brands::UNISYS, "" },
{ VM::brands::LMHS, "" },
{ VM::brands::LMHS, "LMHS is Lockheed Martin's native hypervisor. I assume you got this result because you're an employee in the company and you're doing security testing. But if you're not, how the hell did you get this result? Did you steal a US military fighter jet or something? I'm genuinely curious. I really don't expect anybody to have this result frankly but I'll assume it's just a false positive (please create an issue in the repo if it is)." },
{ VM::brands::CUCKOO, "" },
{ VM::brands::BLUESTACKS, "BlueStacks is a chain of cloud-based cross-platform products developed by the San Francisco-based company of the same name. The BlueStacks App Player enables the execution of Android applications on computers running Microsoft Windows or macOS. It functions through an Android emulator referred to as App Player. The basic features of the software are available for free, while advanced features require a paid monthly subscription." },
{ VM::brands::JAILHOUSE, "" },
{ VM::brands::JAILHOUSE, "Jailhouse is a free and open source partitioning Hypervisor based on Linux, made by Siemens. It is able to run bare-metal applications or (adapted) operating systems besides Linux. For this purpose, it configures CPU and device virtualization features of the hardware platform in a way that none of these domains, called \"cells\", can interfere with each other in an unacceptable way." },
{ VM::brands::APPLE_VZ, "" },
{ VM::brands::INTEL_KGT, "" },
{ VM::brands::AZURE_HYPERV, "" },
{ VM::brands::NANOVISOR, "NanoVisor is a Hyper-V modification serving as the host OS of Xbox's devices: the Xbox System Software. It contains 2 partitions: the \"Exclusive\" partition is a custom VM for games, while the other partition, called the \"Shared\" partition is a custom VM for running multiple apps including the OS itself. The OS was based on Windows 8 Core at the Xbox One launch in 2013." },
{ VM::brands::SIMPLEVISOR, "" },
{ VM::brands::HYPERV_ARTIFACT, "" },
{ VM::brands::HYPERV_ARTIFACT, "The result means that the CLI has found Hyper-V, but as an artifact instead of an actual VM. Although the hardware values do in fact match with the brand due to how it's designed by Microsoft, the CLI has determined you are NOT in a Hyper-V VM from our \"Hyper-X\" mechanism which differentiates between an actual Hyper-V and a false Hyper-V VM that left out breadcrumbs in the system, making it seem like it's a real Hyper-V VM." },
{ VM::brands::UML, "" },
{ VM::brands::POWERVM, "" },
{ VM::brands::GCE, "" },
Expand All @@ -634,6 +632,8 @@ std::string vm_description(const std::string& vm_brand) {
{ VM::brands::BAREVISOR, "" },
{ VM::brands::HYPERPLATFORM, "" },
{ VM::brands::MINIVISOR, "" },
{ VM::brands::MICROSOFT_PRISM, "Prism is the new emulator included with Windows 11. Relative to previous emulation technology included in Windows, it includes significant optimizations that improve the performance and lower CPU usage of apps under emulation. Prism is optimized and tuned specifically for Qualcomm Snapdragon processors, and Prism is available for all supported \"Windows 11 on Arm\" devices with Windows 11." },
{ VM::brands::MICROSOFT_X86_EMU, "" },
{ VM::brands::NULL_BRAND, "" }
};

Expand Down Expand Up @@ -972,7 +972,8 @@ void general() {
checker(VM::LSHW_QEMU, "QEMU in lshw output");
checker(VM::VIRTUAL_PROCESSORS, "virtual processors");
checker(VM::MOTHERBOARD_PRODUCT, "motherboard product");
checker(VM::HVLQUERYDETAILINFO, "HvlQueryDetailInfo");
checker(VM::HYPERV_QUERY, "Hyper-V query");
checker(VM::MICROSOFT_EMU, "Microsoft x86 emulation");
// ADD NEW TECHNIQUE CHECKER HERE

std::printf("\n");
Expand Down
63 changes: 58 additions & 5 deletions src/vmaware.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,8 @@ struct VM {
LSHW_QEMU,
VIRTUAL_PROCESSORS,
MOTHERBOARD_PRODUCT,
HVLQUERYDETAILINFO,
HYPERV_QUERY,
MICROSOFT_EMU,
// ADD NEW TECHNIQUE ENUM NAME HERE

// start of settings technique flags (THE ORDERING IS VERY SPECIFIC HERE AND MIGHT BREAK SOMETHING IF RE-ORDERED)
Expand All @@ -463,7 +464,7 @@ struct VM {
static constexpr u8 INVALID = 255; // explicit invalid technique macro
static constexpr u16 base_technique_count = NO_MEMO; // original technique count, constant on purpose (can also be used as a base count value if custom techniques are added)
static constexpr u16 maximum_points = 5510; // theoretical total points if all VM detections returned true (which is practically impossible)
static constexpr u16 high_threshold_score = 300; // new threshold score from 100 to 350 if VM::HIGH_THRESHOLD flag is enabled
static constexpr u16 high_threshold_score = 300; // new threshold score from 150 to 300 if VM::HIGH_THRESHOLD flag is enabled
static constexpr bool SHORTCUT = true; // macro for whether VM::core::run_all() should take a shortcut by skipping the rest of the techniques if the threshold score is already met


Expand Down Expand Up @@ -574,6 +575,8 @@ struct VM {
static constexpr const char* BAREVISOR = "Barevisor";
static constexpr const char* HYPERPLATFORM = "HyperPlatform";
static constexpr const char* MINIVISOR = "MiniVisor";
static constexpr const char* MICROSOFT_PRISM = "Microsoft Prism";
static constexpr const char* MICROSOFT_X86_EMU = "Microsoft x86 Emulator";
static constexpr const char* NULL_BRAND = "Unknown";
};

Expand Down Expand Up @@ -9449,7 +9452,7 @@ static bool rdtsc() {
* @brief Checks if a call to NtQuerySystemInformation with the 0x9f leaf fills a _SYSTEM_HYPERVISOR_DETAIL_INFORMATION structure
* @category Windows
*/
[[nodiscard]] static bool hvlquerydetailinfo() {
[[nodiscard]] static bool hyperv_query() {
#if (!WINDOWS)
return false;
#else
Expand Down Expand Up @@ -9508,6 +9511,48 @@ static bool rdtsc() {
#endif
}


/**
* @brief Check for x86 emulation by a "Windows on ARM" OS
* @category Windows
* @note https://learn.microsoft.com/en-us/windows/arm/apps-on-arm-x86-emulation#detecting-emulation
*/
[[nodiscard]] static bool microsoft_x86_emulation() {
#if (!(WINDOWS && x86))
return false;
#else
USHORT process_machine = 0
USHORT native_machine = 0;

if (IsWoW64Process2(GetCurrentProcess(), &process_machine, &native_machine)) {
debug("MICROSOFT_PRISM: process Machine: ", process_machine);
debug("MICROSOFT_PRISM: native Machine: ", native_machine);

bool is_emulated = (
(native_machine == IMAGE_FILE_MACHINE_ARM64) &&
(
(process_machine == IMAGE_FILE_MACHINE_AMD64) || // not to be misread as "ARM64"
(process_machine == IMAGE_FILE_MACHINE_I386)
)
);

if (is_emulated) {
const u8 version = util::get_windows_version();

if (version == 11) {
return core::add(brands::MICROSOFT_PRISM);
} else if (version == 10) {
return core::add(brands::MICROSOFT_X86_EMU);
}
}
} else {
debug("MICROSOFT_EMU: failed to run IsWow64Process2()");
}

return false;
#endif
}

// ADD NEW TECHNIQUE FUNCTION HERE


Expand Down Expand Up @@ -10546,7 +10591,8 @@ static bool rdtsc() {
case LSHW_QEMU: return "LSHW_QEMU";
case VIRTUAL_PROCESSORS: return "VIRTUAL_PROCESSORS";
case MOTHERBOARD_PRODUCT: return "MOTHERBOARD_PRODUCT";
case HVLQUERYDETAILINFO: return "HVLQUERYDETAILINFO";
case HYPERV_QUERY: return "HYPERV_QUERY";
case MICROSOFT_EMU: return "MICROSOFT_EMU";
// ADD NEW CASE HERE FOR NEW TECHNIQUE
default: return "Unknown flag";
}
Expand Down Expand Up @@ -10680,6 +10726,8 @@ static bool rdtsc() {

// misc
{ brands::BOCHS, "Emulator" },
{ brands::MICROSOFT_PRISM, "Emulator" },
{ brands::MICROSOFT_X86_EMU, "Emulator" },
{ brands::BLUESTACKS, "Emulator" },
{ brands::MSXTA, "Emulator" },
{ brands::QEMU, "Emulator/Hypervisor (type 2)" },
Expand All @@ -10704,6 +10752,8 @@ static bool rdtsc() {
return it->second;
}

debug("VM::type(): No known brand found, something went terribly wrong here...");

return "Unknown";
}

Expand Down Expand Up @@ -10862,6 +10912,8 @@ std::map<const char*, VM::brand_score_t> VM::core::brand_scoreboard{
{ VM::brands::BAREVISOR, 0 },
{ VM::brands::HYPERPLATFORM, 0 },
{ VM::brands::MINIVISOR, 0 },
{ VM::brands::MICROSOFT_PRISM, 0 },
{ VM::brands::MICROSOFT_X86_EMU, 0 },
{ VM::brands::NULL_BRAND, 0 }
};

Expand Down Expand Up @@ -11090,7 +11142,8 @@ std::pair<VM::enum_flags, VM::core::technique> VM::core::technique_list[] = {
{ VM::LSHW_QEMU, { 80, VM::lshw_qemu, false } },
{ VM::VIRTUAL_PROCESSORS, { 50, VM::virtual_processors, false } },
{ VM::MOTHERBOARD_PRODUCT, { 50, VM::motherboard_product, false } },
{ VM::HVLQUERYDETAILINFO, { 50, VM::hvlquerydetailinfo, false } },
{ VM::HYPERV_QUERY, { 50, VM::hyperv_query, false } },
{ VM::MICROSOFT_EMU, { 60, VM::microsoft_x86_emulation, false } },
// ADD NEW TECHNIQUE STRUCTURE HERE
};

Expand Down

0 comments on commit 5e377b9

Please sign in to comment.