diff --git a/src/vmaware.hpp b/src/vmaware.hpp index 94c1cf1..dcefc0d 100644 --- a/src/vmaware.hpp +++ b/src/vmaware.hpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -32,7 +33,6 @@ #include #include #include -#include // shorter and succinct macros #if __cplusplus == 202002L @@ -74,7 +74,6 @@ #endif #if (CPP >= 17) #include - #include #endif #ifdef __VMAWARE_DEBUG__ #include @@ -104,7 +103,6 @@ #pragma comment(lib, "wbemuuid.lib") #pragma comment(lib, "iphlpapi.lib") - #pragma comment(lib,"MPR") #elif (LINUX) #include #include @@ -794,6 +792,14 @@ struct VM { return (!(flags & p_flag)); } + // same as above but for checking enabled flags + #if (LINUX && __has_cpp_attribute(gnu::pure)) + [[gnu::pure]] + #endif + [[nodiscard]] static inline bool enabled(const u64 p_flag) noexcept { + return (flags & p_flag); + } + // easier way to check if the result is memoized [[nodiscard]] static inline bool is_memoized() noexcept { return ( @@ -860,8 +866,6 @@ 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 @@ -928,17 +932,10 @@ struct VM { return false; } -/* auto strconvert = [](u64 n) -> std::string { const std::string &str(reinterpret_cast(&n)); return str; }; -*/ - auto strconvert = [](u64 n) -> std::string { - const std::string str(reinterpret_cast(&n), sizeof(n)); - return str; - }; - std::stringstream ss; ss << strconvert(sig_reg[0]); @@ -959,13 +956,13 @@ struct VM { const bool found = (std::find(std::begin(IDs), std::end(IDs), brand) != std::end(IDs)); if (found) { - if (brand == vmware) { return add(VMWARE); } - if (brand == vbox) { return add(VBOX); } - if (brand == qemu) { return add(QEMU); } if (brand == bhyve) { return add(BHYVE); } if (brand == kvm) { return add(KVM); } + if (brand == qemu) [[likely]] { return add(QEMU); } if (brand == hyperv) { return add(HYPERV); } if (brand == xta) { return add(MSXTA); } + if (brand == vmware) [[likely]] { return add(VMWARE); } + if (brand == vbox) [[likely]] { return add(VBOX); } if (brand == parallels) { return add(PARALLELS); } if (brand == parallels2) { return add(PARALLELS); } if (brand == xen) { return add(XEN); } @@ -1114,7 +1111,7 @@ struct VM { } } - return (match_count > 0); + return (match_count >= 1); #endif } catch (...) { #ifdef __VMAWARE_DEBUG__ @@ -3056,9 +3053,9 @@ struct VM { return false; } - return false; + return false; // TEMPORARY -/* + /* #if (!MSVC) return false; #else @@ -3091,7 +3088,7 @@ struct VM { return false; #endif -*/ + */ } catch (...) { #ifdef __VMAWARE_DEBUG__ debug("WMIC: catched error, returned false"); @@ -3103,57 +3100,22 @@ struct VM { /** * @brief Check if the BIOS serial is valid * @category Windows - * @todo FIX THE FUCKING SEGFAULT */ [[nodiscard]] static bool bios_serial() try { if (disabled(BIOS_SERIAL)) { return false; } - return false; // temporary + return false; /* #if (!MSVC) return false; #else - auto check_wmic_presence = []() -> bool { - FILE* pipe = _popen("wmic /?", "r"); - - if (pipe) { - char buffer[128]; - while (!feof(pipe)) { - if (fgets(buffer, 128, pipe) != nullptr) - return true; - } - _pclose(pipe); - } else { - return false; - } - - return false; - }; - - if (check_wmic_presence() == false) { - #ifdef __VMAWARE_DEBUG__ - debug("BIOS_SERIAL: ", "wmic isn't found, returned false"); - #endif - return false; - } - std::unique_ptr bios = sys_result("wmic bios get serialnumber"); - const std::string str = std::move(*bios); - const std::size_t nl_pos = str.find('\n'); - - if (nl_pos == std::string::npos) { - return false; - } - - #ifdef __VMAWARE_DEBUG__ - debug("BIOS_SERIAL: ", str); - #endif - - const std::string extract = str.substr(nl_pos + 1); + const std::size_t nl_pos = bios->find('\n'); + std::string extract = bios->substr(nl_pos + 1); const bool all_digits = std::all_of(extract.cbegin(), extract.cend(), [](const char c) { return std::isdigit(c); @@ -3684,7 +3646,10 @@ struct VM { if (disabled(HYPERV_WMI)) { return false; } + + return false; // TEMPORARY + /* #if (!MSVC) return false; #else @@ -3716,6 +3681,7 @@ struct VM { return false; } + // Connect to WMI IWbemLocator *pLoc = NULL; hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc); @@ -3820,6 +3786,7 @@ struct VM { return is_vm; #endif + */ } catch (...) { #ifdef __VMAWARE_DEBUG__ debug("HYPERV_WMI: ", "catched error, returned false"); @@ -3839,6 +3806,8 @@ struct VM { return false; } + return false; // TEMPORARY + /* #if (!MSVC) return false; #else @@ -3888,6 +3857,7 @@ struct VM { return is_vm; #endif + */ } catch (...) { #ifdef __VMAWARE_DEBUG__ debug("HYPERV_WMI: ", "catched error, returned false"); @@ -3896,149 +3866,6 @@ struct VM { } - /** - * @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 @@ -4165,7 +3992,7 @@ struct VM { bool result = false; - if (disabled(EXTREME)) { + if (enabled(EXTREME)) { result = (points > 0); } else { result = (points >= 100); @@ -4383,57 +4210,55 @@ const std::map VM::table = { { VM::VMID, { 100, VM::vmid }}, { VM::BRAND, { 50, VM::cpu_brand }}, { VM::HYPERVISOR_BIT, { 95, VM::hypervisor_bit }}, - //{ VM::CPUID_0X4, { 70, VM::cpuid_0x4 }}, - //{ VM::HYPERVISOR_STR, { 45, VM::hypervisor_brand }}, - //{ VM::RDTSC, { 20, VM::rdtsc_check }}, - //{ VM::SIDT, { 65, VM::sidt_check }}, - //{ VM::VMWARE_PORT, { 80, VM::vmware_port }}, - //{ VM::THREADCOUNT, { 35, VM::thread_count }}, - //{ VM::MAC, { 90, VM::mac_address_check }}, - //{ VM::TEMPERATURE, { 15, VM::temperature }}, - //{ VM::SYSTEMD, { 70, VM::systemd_virt }}, - //{ VM::CVENDOR, { 65, VM::chassis_vendor }}, - //{ VM::CTYPE, { 10, VM::chassis_type }}, - //{ VM::DOCKERENV, { 80, VM::dockerenv }}, - //{ VM::DMIDECODE, { 55, VM::dmidecode }}, - //{ VM::DMESG, { 55, VM::dmesg }}, - //{ VM::HWMON, { 75, VM::hwmon }}, - //{ VM::SIDT5, { 45, VM::sidt5 }}, - //{ VM::CURSOR, { 10, VM::cursor_check }}, - //{ VM::VMWARE_REG, { 65, VM::vmware_registry }}, - //{ VM::VBOX_REG, { 65, VM::vbox_registry }}, - //{ VM::USER, { 35, VM::user_check }}, - //{ VM::DLL, { 50, VM::DLL_check }}, - //{ VM::REGISTRY, { 75, VM::registry_key }}, - //{ VM::SUNBELT_VM, { 10, VM::sunbelt_check }}, - //{ VM::WINE_CHECK, { 85, VM::wine }}, - //{ VM::BOOT, { 5, VM::boot_time }}, - //{ VM::VM_FILES, { 20, VM::vm_files }}, - //{ VM::HWMODEL, { 75, VM::hwmodel }}, - //{ VM::DISK_SIZE, { 60, VM::disk_size }}, - //{ VM::VBOX_DEFAULT, { 55, VM::vbox_default_specs }}, - //{ VM::VBOX_NETWORK, { 70, VM::vbox_network_share }}, - //{ VM::COMPUTER_NAME, { 15, VM::computer_name_match }}, - //{ VM::HOSTNAME, { 25, VM::hostname_match }}, - //{ VM::MEMORY, { 35, VM::low_memory_space }}, - //{ VM::VM_PROCESSES, { 30, VM::vm_processes }}, - //{ VM::LINUX_USER_HOST, { 35, VM::linux_user_host }}, - //{ VM::VBOX_WINDOW_CLASS, { 10, VM::vbox_window_class }}, - //{ VM::GAMARUE, { 40, VM::gamarue }}, - ////{ VM::WMIC, { 20, VM::wmic }}, - //{ VM::VMID_0X4, { 90, VM::vmid_0x4 }}, - //{ VM::VPC_BACKDOOR, { 70, VM::vpc_backdoor }}, - //{ VM::PARALLELS_VM, { 50, VM::parallels }}, - //{ VM::SPEC_RDTSC, { 80, VM::speculative_rdtsc }}, - //{ VM::LOADED_DLLS, { 75, VM::loaded_dlls }}, - //{ VM::QEMU_BRAND, { 100, VM::cpu_brand_qemu }}, - //{ 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 }}, - //{ VM::VBOX_FOLDERS, { 45, VM::vbox_shared_folders }}, - //{ VM::VBOX_MSSMBIOS, { 75, VM::vbox_mssmbios }} + { VM::CPUID_0X4, { 70, VM::cpuid_0x4 }}, + { VM::HYPERVISOR_STR, { 45, VM::hypervisor_brand }}, + { VM::RDTSC, { 20, VM::rdtsc_check }}, + { VM::SIDT, { 65, VM::sidt_check }}, + { VM::VMWARE_PORT, { 80, VM::vmware_port }}, + { VM::THREADCOUNT, { 35, VM::thread_count }}, + { VM::MAC, { 90, VM::mac_address_check }}, + { VM::TEMPERATURE, { 15, VM::temperature }}, + { VM::SYSTEMD, { 70, VM::systemd_virt }}, + { VM::CVENDOR, { 65, VM::chassis_vendor }}, + { VM::CTYPE, { 10, VM::chassis_type }}, + { VM::DOCKERENV, { 80, VM::dockerenv }}, + { VM::DMIDECODE, { 55, VM::dmidecode }}, + { VM::DMESG, { 55, VM::dmesg }}, + { VM::HWMON, { 75, VM::hwmon }}, + { VM::SIDT5, { 45, VM::sidt5 }}, + { VM::CURSOR, { 10, VM::cursor_check }}, + { VM::VMWARE_REG, { 65, VM::vmware_registry }}, + { VM::VBOX_REG, { 65, VM::vbox_registry }}, + { VM::USER, { 35, VM::user_check }}, + { VM::DLL, { 50, VM::DLL_check }}, + { VM::REGISTRY, { 75, VM::registry_key }}, + { VM::SUNBELT_VM, { 10, VM::sunbelt_check }}, + { VM::WINE_CHECK, { 85, VM::wine }}, + { VM::BOOT, { 5, VM::boot_time }}, + { VM::VM_FILES, { 20, VM::vm_files }}, + { VM::HWMODEL, { 75, VM::hwmodel }}, + { VM::DISK_SIZE, { 60, VM::disk_size }}, + { VM::VBOX_DEFAULT, { 55, VM::vbox_default_specs }}, + { VM::VBOX_NETWORK, { 70, VM::vbox_network_share }}, + { VM::COMPUTER_NAME, { 15, VM::computer_name_match }}, + { VM::HOSTNAME, { 25, VM::hostname_match }}, + { VM::MEMORY, { 35, VM::low_memory_space }}, + { VM::VM_PROCESSES, { 30, VM::vm_processes }}, + { VM::LINUX_USER_HOST, { 35, VM::linux_user_host }}, + { VM::VBOX_WINDOW_CLASS, { 10, VM::vbox_window_class }}, + { VM::GAMARUE, { 40, VM::gamarue }}, + { VM::WMIC, { 20, VM::wmic }}, // clear issue here + { VM::VMID_0X4, { 90, VM::vmid_0x4 }}, + { VM::VPC_BACKDOOR, { 70, VM::vpc_backdoor }}, + { VM::PARALLELS_VM, { 50, VM::parallels }}, + { VM::SPEC_RDTSC, { 80, VM::speculative_rdtsc }}, + { VM::LOADED_DLLS, { 75, VM::loaded_dlls }}, + { VM::QEMU_BRAND, { 100, VM::cpu_brand_qemu }}, + { 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 }}, // __TABLE_LABEL, add your technique above // { VM::YOUR_FUNCTION, { POINTS, FUNCTION POINTER }}