#include "check_vmware.h" #include "utils.h" #include #include #include #include #include #include #pragma comment(lib, "dxgi.lib") #pragma comment(lib, "Setupapi.lib") CONST WCHAR* processList[] = { L"vmtoolsd.exe", L"vm3dservice.exe", L"VGAuthService.exe", }; CONST CHAR* filePathName[] = { "C:\\Program Files\\VMware", "C:\\Windows\\System32\\drivers\\vmmouse.sys", "C:\\Windows\\System32\\drivers\\vmusbmouse.sys", "C:\\Windows\\System32\\drivers\\vm3dmp.sys", "C:\\Windows\\System32\\drivers\\vm3dmp_loader.sys", "C:\\Windows\\System32\\drivers\\vm3dmp-debug.sys", "C:\\Windows\\System32\\drivers\\vm3dmp-stats.sys", }; namespace check_vmware { bool registry() { char szBuf[256]{ 0 }; if (utils::RegReadString(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\BIOS", "SystemManufacturer", szBuf, sizeof(szBuf))) { if (strstr(szBuf, "VMware")) return true; } if (utils::RegReadString(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\BIOS", "SystemProductName", szBuf, sizeof(szBuf))) { if (strstr(szBuf, "VMware")) return true; } return false; } bool process() { auto Snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); if (Snapshot == INVALID_HANDLE_VALUE) return false; PROCESSENTRY32 pe32{ 0 }; pe32.dwSize = sizeof(pe32); if (Process32First(Snapshot, &pe32)) { do { for (size_t i = 0; i < sizeof(processList) / sizeof(processList[0]); i++) { if (!wcscmp(processList[i], pe32.szExeFile)) { CloseHandle(Snapshot); return true; } } } while (Process32Next(Snapshot, &pe32)); } CloseHandle(Snapshot); return false; } bool cpuid() { int info[4]{ 0 }; CHAR szHypervisorVendor[256]; __cpuid(info, 0x40000000); SecureZeroMemory(szHypervisorVendor, sizeof(szHypervisorVendor)); memcpy(szHypervisorVendor, info + 1, 12); if (!_strcmpi(szHypervisorVendor, "VMwareVMware")) return true; return false; } bool cpuid2() { int info[4]{ 0 }; __cpuid(info, 1); if ((info[2] >> 31) & 1) return true; return false; } bool diskname() { HDEVINFO hDevInfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_DISKDRIVE, NULL, NULL, DIGCF_PRESENT); if (hDevInfo == INVALID_HANDLE_VALUE) return false; SP_DEVINFO_DATA devInfo = { 0 }; devInfo.cbSize = sizeof(SP_DEVINFO_DATA); DWORD dwIndex = 0; // 循环枚举全部磁盘设备 while (SetupDiEnumDeviceInfo(hDevInfo, dwIndex, &devInfo)) { WCHAR szBuffer[1024] = { 0 }; DWORD dwDataType = 0; DWORD dwBufSize = sizeof(szBuffer); // 读取设备友好名称 SPDRP_FRIENDLYNAME if (SetupDiGetDeviceRegistryPropertyW( hDevInfo, &devInfo, SPDRP_FRIENDLYNAME, &dwDataType, (PBYTE)szBuffer, dwBufSize, &dwBufSize)) { if (utils::StrContainsI(szBuffer, L"VBOX") || utils::StrContainsI(szBuffer, L"QEMU") || utils::StrContainsI(szBuffer, L"VMWARE") || utils::StrContainsI(szBuffer, L"VIRTUAL HD")) { SetupDiDestroyDeviceInfoList(hDevInfo); return true; } } dwIndex++; } SetupDiDestroyDeviceInfoList(hDevInfo); return false; } bool mousename() { HDEVINFO hDevInfo = SetupDiGetClassDevs( &GUID_DEVCLASS_MOUSE, NULL, NULL, DIGCF_PRESENT); if (hDevInfo == INVALID_HANDLE_VALUE) return false; SP_DEVINFO_DATA DeviceInfoData; DeviceInfoData.cbSize = sizeof(DeviceInfoData); bool bVirtual = false; for (DWORD i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); i++) { WCHAR Name[512] = { 0 }; // FriendlyName if (!SetupDiGetDeviceRegistryPropertyW( hDevInfo, &DeviceInfoData, SPDRP_FRIENDLYNAME, NULL, (PBYTE)Name, sizeof(Name), NULL)) { // 有些设备没有 FriendlyName SetupDiGetDeviceRegistryPropertyW( hDevInfo, &DeviceInfoData, SPDRP_DEVICEDESC, NULL, (PBYTE)Name, sizeof(Name), NULL); } std::wstring str = Name; if (str.find(L"VMware") != std::wstring::npos || str.find(L"VirtualBox") != std::wstring::npos || str.find(L"Hyper-V") != std::wstring::npos || str.find(L"Virtual") != std::wstring::npos || str.find(L"QEMU") != std::wstring::npos || str.find(L"Xen") != std::wstring::npos || str.find(L"Parallels") != std::wstring::npos) { bVirtual = true; } } SetupDiDestroyDeviceInfoList(hDevInfo); return bVirtual; } bool dxgiGpuName() { HRESULT hr; IDXGIFactory1* pFactory = nullptr; hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&pFactory); if (FAILED(hr) || !pFactory) return false; UINT adapterIndex = 0; IDXGIAdapter1* pAdapter = nullptr; // 遍历所有显卡适配器 while (pFactory->EnumAdapters1(adapterIndex, &pAdapter) != DXGI_ERROR_NOT_FOUND) { DXGI_ADAPTER_DESC1 desc; hr = pAdapter->GetDesc1(&desc); if (SUCCEEDED(hr)) { // 虚拟机显卡特征关键词 if (wcsstr(desc.Description, L"VMware") != nullptr || wcsstr(desc.Description, L"VBox") != nullptr || wcsstr(desc.Description, L"VirtualBox") != nullptr || wcsstr(desc.Description, L"Basic Display Adapter") != nullptr) { pAdapter->Release(); pFactory->Release(); return true; } } pAdapter->Release(); adapterIndex++; } pFactory->Release(); return false; } bool In() { #if _WIN64 __try { Asm_CheckVmWare(); return true; } __except (1) { return false; } #else __try { __asm { mov eax, 0x564D5868; //魔法值 'VMXh',VMware端口通信固定标识 mov ebx, 0xFFFFFFFF; //EBX初始值,用于接收Hypervisor返回标识 mov ecx, 10; //命令号 10 = CMD_GetVersion(获取VMware版本) mov edx, 0x5658; //VMware专属I / O端口号 0x5658 in eax, dx; //向VMware端口发起通信请求 cmp ebx, 0x564D5868; //判断EBX是否被改写为'VMXh'魔法值 je vm_found; //相等 = 检测到VMware,跳转 xor al, al; //未找到,AL置0(FALSE) jmp vm_end; //跳转到结尾 vm_found: mov al, 1; //找到VMware,AL置1(TRUE) vm_end: } } __except (GetExceptionCode() == EXCEPTION_PRIV_INSTRUCTION) { return FALSE; } #endif } bool file() { for (size_t i = 0; i < sizeof(filePathName) / sizeof(filePathName[0]); i++) { if (GetFileAttributesA(filePathName[i]) != INVALID_FILE_ATTRIBUTES) { return true; } } return false; } unsigned long long rdtsc_exit() { int info[4]{ 0 }; DWORD64 tsc1, tsc2; DWORD64 sum = 0; for (size_t i = 0; i < 200; i++) { tsc1 = __rdtsc(); __cpuid(info, 0); tsc2 = __rdtsc(); sum += (tsc2 - tsc1); } return sum; } bool virutal_check_vmcall() { #if _WIN64 __try { Asm_VMCall(); return true; } __except (1) { return false; } #else __try { _asm { _emit 0x0F _emit 0x01 _emit 0xC1 mov eax, 1 } } __except (1) { return false; } #endif } }