注册表检测 虚拟机软件会在系统注册表中留下特定键值,可通过查询这些注册表项判断是否存在虚拟机。
检测点位 VMware:
1 2 3 4 5 6 HKEY_LOCAL_MACHINE\SOFTWARE\VMware, Inc.\VMware Tools HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\vmdebug HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\vmmouse HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\vmci HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\VMnetAdapter HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0\Identifier = "VMware Virtual IDE Hard Drive"
VirtualBox:
1 2 3 4 5 6 7 8 HKEY_LOCAL_MACHINE\SOFTWARE\Oracle\VirtualBox Guest Additions HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\VBoxGuest HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\VBoxMouse HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\VBoxService HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\VBoxSF HKEY_LOCAL_MACHINE\HARDWARE\ACPI\DSDT\VBOX__ HKEY_LOCAL_MACHINE\HARDWARE\ACPI\FADT\VBOX__ HKEY_LOCAL_MACHINE\HARDWARE\ACPI\RSDT\VBOX__
Parallels:
1 2 3 4 5 HKEY_LOCAL_MACHINE\SOFTWARE\Parallels HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\prl_tools HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\prl_sound HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\prl_vid HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\prl_dd
检测代码示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 BOOL CheckVMRegistry () { HKEY hKey; const WCHAR* vmRegistryPaths[] = { L"SOFTWARE\\VMware, Inc.\\VMware Tools" , L"SOFTWARE\\Oracle\\VirtualBox Guest Additions" , L"SYSTEM\\CurrentControlSet\\Services\\VBoxGuest" , L"SYSTEM\\CurrentControlSet\\Services\\vmdebug" , L"SYSTEM\\CurrentControlSet\\Services\\vmmouse" , L"HARDWARE\\ACPI\\DSDT\\VBOX__" , L"HARDWARE\\ACPI\\FADT\\VBOX__" , L"HARDWARE\\ACPI\\RSDT\\VBOX__" }; for (int i = 0 ; i < _countof(vmRegistryPaths); i++) { if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, vmRegistryPaths[i], 0 , KEY_READ, &hKey) == ERROR_SUCCESS) { RegCloseHandle(hKey); return TRUE; } } return FALSE; }
进程检测 虚拟机软件通常会在客户机(Guest OS)中运行一些特定的进程,这些进程用于提供虚拟机与宿主机之间的集成服务。
检测点位 VMware 进程
1 2 3 4 5 vmware.exe - VMware 主程序 vmware-vmx.exe - VMware 虚拟机进程 vmware-tray.exe - VMware 托盘程序 vmware-user.exe - VMware 用户服务 vmtoolsd.exe - VMware Tools 守护进程
VirtualBox 进程
1 2 3 4 VBoxService.exe - VirtualBox 服务 VBoxTray.exe - VirtualBox 托盘程序 VBoxHeadless.exe - VirtualBox 无头模式进程 VBoxControl.exe - VirtualBox 控制程序
Parallels 进程
1 2 3 4 prl_cc.exe - Parallels 控制中心 prl_tools.exe - Parallels 工具 prl_srv.exe - Parallels 服务 prl_disp_service.exe - Parallels 显示服务
检测代码示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 #include <windows.h> #include <tlhelp32.h> #include <tchar.h> #include <stdio.h> const WCHAR* g_vmProcesses[] = { L"vmware.exe" , L"vmware-vmx.exe" , L"VBoxService.exe" , L"VBoxTray.exe" , L"VBoxHeadless.exe" , L"prl_cc.exe" , L"prl_tools.exe" , L"vmware-authd.exe" , L"VBoxManage.exe" }; BOOL DetectVMProcesses () { HANDLE hProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0 ); if (hProcessSnapshot == INVALID_HANDLE_VALUE) { printf ("创建进程快照失败,错误码: %d\n" , GetLastError()); return FALSE; } PROCESSENTRY32W processEntry = {0 }; processEntry.dwSize = sizeof (PROCESSENTRY32W); if (!Process32FirstW(hProcessSnapshot, &processEntry)) { printf ("获取进程信息失败,错误码: %d\n" , GetLastError()); CloseHandle(hProcessSnapshot); return FALSE; } do { for (size_t i = 0 ; i < _countof(g_vmProcesses); i++) { if (_wcsicmp(processEntry.szExeFile, g_vmProcesses[i]) == 0 ) { wprintf(L"检测到虚拟机进程: %s (PID: %d)\n" , processEntry.szExeFile, processEntry.th32ProcessID); CloseHandle(hProcessSnapshot); return TRUE; } } } while (Process32NextW(hProcessSnapshot, &processEntry)); CloseHandle(hProcessSnapshot); return FALSE; }
文件系统检测 虚拟机软件的安装目录、系统文件或环境变量会留下痕迹。
检测点位 VMware 文件
1 2 3 4 5 6 7 8 C:\Program Files\VMware\VMware Tools\ C:\Windows\System32\drivers\vmmouse.sys C:\Windows\System32\drivers\vm3dmp.sys C:\Windows\System32\drivers\vmci.sys C:\Windows\System32\drivers\vmx86.sys C:\Windows\System32\vmtray.dll C:\Windows\System32\vmGuestLib.dll C:\Windows\System32\vmhgfs.dll
VirtualBox 文件
1 2 3 4 5 6 7 8 C:\Program Files\Oracle\VirtualBox Guest Additions\ C:\Windows\System32\drivers\VBoxGuest.sys C:\Windows\System32\drivers\VBoxMouse.sys C:\Windows\System32\drivers\VBoxSF.sys C:\Windows\System32\drivers\VBoxVideo.sys C:\Windows\System32\VBoxControl.exe C:\Windows\System32\VBoxDisp.dll C:\Windows\System32\VBoxHook.dll
Parallels 文件
1 2 3 4 5 6 7 8 C:\Program Files\Parallels\ C:\Windows\System32\drivers\prl_eth.sys C:\Windows\System32\drivers\prl_fs.sys C:\Windows\System32\drivers\prl_mouf.sys C:\Windows\System32\drivers\prl_pv.sys C:\Windows\System32\drivers\prl_sound.sys C:\Windows\System32\drivers\prl_tg.sys C:\Windows\System32\drivers\prl_vid.sys
检测代码示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 BOOL CheckVMFiles () { const WCHAR* vmFiles[] = { L"C:\\Program Files\\VMware\\VMware Tools\\" , L"C:\\Program Files\\Oracle\\VirtualBox Guest Additions\\" , L"C:\\Windows\\System32\\drivers\\vmmouse.sys" , L"C:\\Windows\\System32\\drivers\\vm3dmp.sys" , L"C:\\Windows\\System32\\drivers\\vmtray.dll" , L"C:\\Windows\\System32\\drivers\\VBoxMouse.sys" , L"C:\\Windows\\System32\\drivers\\VBoxGuest.sys" , L"C:\\Windows\\System32\\drivers\\prl_sound.sys" }; for (int i = 0 ; i < _countof(vmFiles); i++) { if (GetFileAttributesW(vmFiles[i]) != INVALID_FILE_ATTRIBUTES) { return TRUE; } } return FALSE; }
服务检测 虚拟机会安装一些特定的服务。
检测点位 VMware 服务 VMware Physical Disk Helper Service VMware Tools vmicheartbeat vmickvpexchange vmicrdv vmicshutdown vmictimesync vmicvmsession vmicvss
VirtualBox 服务 VBoxService VBoxGuest VBoxMouse VBoxSF
Parallels 服务 prl_tools prl_sound prl_dd prl_vid prl_disp_service
检测代码示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 BOOL CheckVMServices () { SC_HANDLE scManager = OpenSCManagerW(NULL , NULL , SC_MANAGER_ENUMERATE_SERVICE); if (!scManager) return FALSE; const WCHAR* vmServices[] = { L"VBoxService" , L"VBoxGuest" , L"VMware Physical Disk Helper Service" , L"VMware Tools" , L"vmicheartbeat" , L"vmicshutdown" , L"vmictimesync" , L"PrlTools" , L"prl_sound" }; for (int i = 0 ; i < _countof(vmServices); i++) { SC_HANDLE service = OpenServiceW(scManager, vmServices[i], SERVICE_QUERY_STATUS); if (service) { CloseServiceHandle(service); CloseServiceHandle(scManager); return TRUE; } } CloseServiceHandle(scManager); return FALSE; }
硬件检测 虚拟机的虚拟硬件(如主板、网卡、磁盘控制器等)会包含特定标识,可通过枚举硬件信息识别。
检测点位 硬件标识符
1 2 3 4 5 6 7 PCI\VEN_80EE&DEV_CAFE VirtualBox 显卡 PCI\VEN_15AD&DEV_0405 VMware SVGA 显卡 PCI\VEN_15AD&DEV_0740 VMware VMXNET3 网卡 PCI\VEN_15AD&DEV_07E0 VMware PVSCSI 控制器 PCI\VEN_1AB8&DEV_4000 Parallels 网卡 PCI\VEN_1AF4&DEV_1000 VirtIO 网卡 (QEMU/KVM) PCI\VEN_1AF4&DEV_1041 VirtIO 块设备 (QEMU/KVM)
检测代码示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 #include <windows.h> #include <setupapi.h> #include <initguid.h> #include <devguid.h> #include <stdio.h> #pragma comment(lib, "setupapi.lib" ) BOOL CheckDeviceName (HDEVINFO hDevInfo, SP_DEVINFO_DATA* pDevInfoData) { TCHAR szDeviceName[256 ] = {0 }; if (!SetupDiGetDeviceRegistryProperty( hDevInfo, pDevInfoData, SPDRP_FRIENDLYNAME, NULL , (PBYTE)szDeviceName, sizeof (szDeviceName), NULL )) { SetupDiGetDeviceRegistryProperty( hDevInfo, pDevInfoData, SPDRP_DEVICEDESC, NULL , (PBYTE)szDeviceName, sizeof (szDeviceName), NULL ); } if (_tcschr(szDeviceName, _T('VMware' )) || _tcschr(szDeviceName, _T('VirtualBox' )) || _tcschr(szDeviceName, _T('QEMU' )) || _tcschr(szDeviceName, _T('VirtIO' ))) { _tprintf(_T("检测到虚拟设备: %s\n" ), szDeviceName); return TRUE; } return FALSE; } BOOL DetectVMByDevice () { HDEVINFO hDevInfo = SetupDiGetClassDevs(&GUID_DEVINTERFACE_DISK, NULL , NULL , DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (hDevInfo == INVALID_HANDLE_VALUE) return FALSE; SP_DEVINFO_DATA devInfoData = {0 }; devInfoData.cbSize = sizeof (SP_DEVINFO_DATA); for (DWORD i = 0 ; SetupDiEnumDeviceInfo(hDevInfo, i, &devInfoData); i++) { if (CheckDeviceName(hDevInfo, &devInfoData)) { SetupDiDestroyDeviceInfoList(hDevInfo); return TRUE; } } SetupDiDestroyDeviceInfoList(hDevInfo); return FALSE; }
WMI检测 通过 Windows 管理规范(WMI)查询系统信息,虚拟机的硬件 / 系统描述会包含特征。
检测点位 查询WMI类Win32_ComputerSystem或Win32_BaseBoard:Win32_ComputerSystem.Manufacturer:VMware返回VMware, Inc.,VirtualBox返回Oracle CorporationWin32_BaseBoard.Product:虚拟机通常返回Virtual Machine或厂商名(如 VMware Virtual Platform)
检测代码示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 #include <wbemidl.h> #pragma comment(lib, "wbemuuid.lib" ) BOOL CheckVMWMI () { HRESULT hres; hres = CoInitializeEx(0 , COINIT_MULTITHREADED); if (FAILED(hres)) return FALSE; hres = CoInitializeSecurity(NULL , -1 , NULL , NULL , RPC_C_AUTHN_LEVEL_NONE, RPC_C_IMP_LEVEL_IMPERSONATE, NULL , EOAC_NONE, NULL ); IWbemLocator* pLoc = NULL ; hres = CoCreateInstance(CLSID_WbemLocator, 0 , CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc); IWbemServices* pSvc = NULL ; hres = pLoc->ConnectServer(_bstr_t (L"ROOT\\CIMV2" ), NULL , NULL , 0 , NULL , 0 , 0 , &pSvc); IEnumWbemClassObject* pEnumerator = NULL ; hres = pSvc->ExecQuery(bstr_t ("WQL" ), bstr_t ("SELECT * FROM Win32_ComputerSystem" ), WBEM_FLAG_FORWARD_ONLY, NULL , &pEnumerator); IWbemClassObject* pclsObj = NULL ; ULONG uReturn = 0 ; BOOL isVM = FALSE; while (pEnumerator) { HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1 , &pclsObj, &uReturn); if (0 == uReturn) break ; VARIANT vtManufacturer, vtModel; VariantInit(&vtManufacturer); VariantInit(&vtModel); hr = pclsObj->Get(L"Manufacturer" , 0 , &vtManufacturer, 0 , 0 ); hr = pclsObj->Get(L"Model" , 0 , &vtModel, 0 , 0 ); if (VT_BSTR == vtManufacturer.vt && VT_BSTR == vtModel.vt) { if (wcsstr(vtManufacturer.bstrVal, L"VMware" ) || wcsstr(vtModel.bstrVal, L"VirtualBox" ) || wcsstr(vtManufacturer.bstrVal, L"innotek" ) || wcsstr(vtModel.bstrVal, L"Virtual Machine" ) || wcsstr(vtManufacturer.bstrVal, L"Parallels" )) { isVM = TRUE; } } VariantClear(&vtManufacturer); VariantClear(&vtModel); pclsObj->Release(); if (isVM) break ; } pSvc->Release(); pLoc->Release(); pEnumerator->Release(); CoUninitialize(); return isVM; }
CPU 指令与行为检测 通过执行特定 CPU 指令(如 CPUID),虚拟机的返回结果与物理机存在差异。
检测点位 1.CPUID指令特征执行CPUID指令(功能号0x40000000及以上),虚拟机可能返回特定厂商字符串: VMware:CPUID返回VMwareVMware VirtualBox:返回 VBoxVBox 2.时间戳差异虚拟机中某些指令的执行时间与物理机不同(如 RDTSC 指令),可通过测量指令耗时判断是否在虚拟机中运行。
检测代码示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 #include <cstdint> #include <stdio.h> void cpuid (uint32_t eax, uint32_t * eax_out, uint32_t * ebx_out, uint32_t * ecx_out, uint32_t * edx_out) { __asm { mov eax, [eax] cpuid mov [eax_out], eax mov [ebx_out], ebx mov [ecx_out], ecx mov [edx_out], edx } } BOOL DetectVMByCPUID () { uint32_t eax, ebx, ecx, edx; char vendor[13 ] = {0 }; cpuid(0 , &eax, &ebx, &ecx, &edx); *(uint32_t *)&vendor[0 ] = ebx; *(uint32_t *)&vendor[4 ] = edx; *(uint32_t *)&vendor[8 ] = ecx; if (strcmp (vendor, "VMwareVMware" ) == 0 ) { printf ("CPUID检测到VMware\n" ); return TRUE; } if (strcmp (vendor, "VBoxVBox" ) == 0 ) { printf ("CPUID检测到VirtualBox\n" ); return TRUE; } if (strcmp (vendor, "KVMKVMKVM" ) == 0 ) { printf ("CPUID检测到KVM/QEMU\n" ); return TRUE; } return FALSE; }
虚拟机官网 更具体的信息可以去查阅官网。1.VMware 全球官网:https://www.vmware.com/ 提供 Workstation Pro(Windows/Linux)、Fusion(macOS)等产品,覆盖个人和企业级虚拟化解决方案。2.VirtualBox 官方网站:https://www.virtualbox.org/ 3.Parallels 全球官网:https://www.parallels.com/