diff --git a/docs/documentation.md b/docs/documentation.md index a8594c8..19e3591 100644 --- a/docs/documentation.md +++ b/docs/documentation.md @@ -213,7 +213,11 @@ VMAware provides a convenient way to not only check for VMs, but also have the f | `VM::BIOS_SERIAL` | Check if BIOS serial number is null | Windows | 60% | | | `VM::VBOX_FOLDERS` | Check for VirtualBox-specific string for shared folder ID | Windows | 45% | | | `VM::VBOX_MSSMBIOS` | Check VirtualBox MSSMBIOS registry for VM-specific strings | Windows 75% | | - + { VM::BOCHS_CPU, { 95, VM::bochs_cpu }}, + { VM::VPC_BOARD, { 20, VM::vpc_board }}, + { VM::HYPERV_WMI, { 80, VM::hyperv_wmi }}, + { VM::HYPERV_REG, { 80, VM::hyperv_registry }}, + { VM::BIOS_SERIAL, { 60, VM::bios_serial }},
# Non-technique flags diff --git a/src/cli.cpp b/src/cli.cpp index 40d056e..2a25907 100644 --- a/src/cli.cpp +++ b/src/cli.cpp @@ -116,7 +116,6 @@ int main(int argc, char* argv[]) { checker(VM::BIOS_SERIAL, "BIOS serial number"); checker(VM::VBOX_FOLDERS, "VirtualBox shared folders"); checker(VM::VBOX_MSSMBIOS, "VirtualBox MSSMBIOS"); - std::printf("\n"); std::cout << "VM brand: " << (std::string(VM::brand()) == "Unknown" ? red : green) << VM::brand() << ansi_exit << "\n"; diff --git a/src/vmaware.hpp b/src/vmaware.hpp index dcefc0d..812f557 100644 --- a/src/vmaware.hpp +++ b/src/vmaware.hpp @@ -866,6 +866,8 @@ struct VM { HYPERV_WMI = 1ULL << 49, HYPERV_REG = 1ULL << 50, BIOS_SERIAL = 1ULL << 51, + VBOX_FOLDERS = 1ULL << 52, + VBOX_MSSMBIOS = 1ULL << 53, // __UNIQUE_LABEL, ADD YOUR UNIQUE FUNCTION FLAG VALUE ABOVE HERE @@ -3865,6 +3867,148 @@ struct VM { return false; } + /** + * @brief Check for VirtualBox-specific string for shared folder ID + * @category Windows + * @note slightly modified code from original + * @author @waleedassar + * @link https://pastebin.com/xhFABpPL + */ + [[nodiscard]] static bool vbox_shared_folders() try { + if (disabled(VBOX_FOLDERS)) { + return false; + } + + #if (!MSVC) + return false; + #else + unsigned long pnsize = 0x1000; + char* provider = static_cast(LocalAlloc(LMEM_ZEROINIT,pnsize)); + unsigned int retv = WNetGetProviderName(WNNC_NET_RDR2SAMPLE,provider,&pnsize); + if (retv == NO_ERROR) { + if (lstrcmpi(provider,"VirtualBox Shared Folders") == 0) { + return add(VBOX); + } + } + + return false; + #endif + } catch (...) { + #ifdef __VMAWARE_DEBUG__ + debug("VBOX_FOLDERS: ", "catched error, returned false"); + #endif + return false; + } + + + /** + * @brief Check VirtualBox MSSMBIOS registry for VM-specific strings + * @category Windows + * @note slightly modified from original code + * @author @waleedassar + * @link https://pastebin.com/fPY4MiYq + */ + [[nodiscard]] static bool vbox_mssmbios() try { + if (disabled(VBOX_MSSMBIOS)) { + return false; + } + + #if (!MSVC) + return false; + #else + HKEY hk = 0; + int ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\mssmbios\\data", 0, KEY_ALL_ACCESS, &hk); + if (ret != ERROR_SUCCESS) { + return false; + } + + bool is_vm = false; + unsigned long type = 0; + unsigned long length = 0; + ret = RegQueryValueEx(hk, "SMBiosData", 0, &type, 0, &length); + + if (ret != ERROR_SUCCESS) { + RegCloseKey(hk); + return false; + } + + if (length == 0) { + RegCloseKey(hk); + return false; + } + + char* p = static_cast(LocalAlloc(LMEM_ZEROINIT, length)); + + if (p == nullptr) { + RegCloseKey(hk); + return false; + } + + ret = RegQueryValueEx(hk, "SMBiosData", 0, &type, (unsigned char*)p, &length); + + if (ret != ERROR_SUCCESS) { + LocalFree(p); + RegCloseKey(hk); + return false; + } + + auto ScanDataForString = [](unsigned char* data, unsigned long data_length, unsigned char* string2) -> unsigned char* { + std::size_t string_length = strlen(reinterpret_cast(string2)); + + for (std::size_t i = 0; i <= (data_length-string_length); i++) { + if (strncmp(reinterpret_cast(&data[i]), reinterpret_cast(string2), string_length) == 0) { + return &data[i]; + } + } + return 0; + }; + + auto AllToUpper = [](char* str, std::size_t len) -> void { + std::transform(str, str + len, str, [](unsigned char c) -> char { + return static_cast(std::toupper(c)); + }); + }; + + AllToUpper(p, length); + + // cleaner and better shortcut than typing reinterpret_cast a million times + auto cast = [](char* p) -> unsigned char* { + return reinterpret_cast(p); + }; + + unsigned char* x1 = ScanDataForString(cast(p), length, (unsigned char*)("INNOTEK GMBH")); + unsigned char* x2 = ScanDataForString(cast(p), length, (unsigned char*)("VIRTUALBOX")); + unsigned char* x3 = ScanDataForString(cast(p), length, (unsigned char*)("SUN MICROSYSTEMS")); + unsigned char* x4 = ScanDataForString(cast(p), length, (unsigned char*)("VIRTUAL MACHINE")); + unsigned char* x5 = ScanDataForString(cast(p), length, (unsigned char*)("VBOXVER")); + + if (x1 || x2 || x3 || x4 || x5) { + is_vm = true; + #ifdef __VMAWARE_DEBUG__ + if (x1) { debug("VBOX_MSSMBIOS: x1 = ", x1); } + if (x2) { debug("VBOX_MSSMBIOS: x2 = ", x2); } + if (x3) { debug("VBOX_MSSMBIOS: x3 = ", x3); } + if (x4) { debug("VBOX_MSSMBIOS: x4 = ", x4); } + if (x5) { debug("VBOX_MSSMBIOS: x5 = ", x5); } + #endif + } + + LocalFree(p); + RegCloseKey(hk); + + if (is_vm) { + return add(VBOX); + } + + return false; + #endif + } catch (...) { + #ifdef __VMAWARE_DEBUG__ + debug("VBOX_INNOTEK: ", "catched error, returned false"); + #endif + return false; + } + // __TECHNIQUE_LABEL, label for adding techniques above this point