Files
2026-08-24 14:47:59 +08:00

362 lines
6.9 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "check_vmware.h"
#include "utils.h"
#include <initguid.h>
#include <devguid.h>
#include <SetupAPI.h>
#include <initguid.h>
#include <dxgi.h>
#include <intrin.h>
#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置0FALSE
jmp vm_end; //跳转到结尾
vm_found:
mov al, 1; //找到VMwareAL置1TRUE
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
}
}