本文为看雪论坛优秀文章
看雪论坛作者ID:gmhax
一
基于特征的检测
GetFileAttributes
、etModuleHandle
C:\Program Files\VMware\
C:\Windows\System32\vm3dc003.dll
C:\Windows\System32\vm3ddevapi64-debug.dll
C:\Windows\System32\vm3ddevapi64-release.dll
C:\Windows\System32\vm3ddevapi64-stats.dll
C:\Windows\System32\vm3ddevapi64.dll
C:\Windows\System32\vm3dgl64.dll
C:\Windows\System32\vm3dglhelper64.dll
C:\Windows\System32\vm3dservice.exe
C:\Windows\System32\vm3dum64-debug.dll
C:\Windows\System32\vm3dum64-stats.dll
C:\Windows\System32\vm3dum64.dll
C:\Windows\System32\vm3dum64_10-debug.dll
C:\Windows\System32\vm3dum64_10-stats.dll
C:\Windows\System32\vm3dum64_10.dll
C:\Windows\System32\vm3dum64_loader.dll
C:\Windows\System32\vmGuestLib.dll
C:\Windows\System32\vmGuestLibJava.dll
C:\Windows\System32\vmhgfs.dll
C:\Windows\System32\VMWSU.DLL
C:\Windows\System32\vsocklib.dll
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
C:\Windows\System32\drivers\vmnet.sys
C:\Windows\System32\drivers\vmmouse.sys
C:\Windows\System32\drivers\vmusb.sys
C:\Windows\System32\drivers\vmci.sys
C:\Windows\System32\drivers\vmhgfs.sys
C:\Windows\System32\drivers\vmmemctl.sys
C:\Windows\System32\drivers\vmx86.sys
C:\Windows\System32\drivers\vmrawdsk.sys
C:\Windows\System32\drivers\vmusbmouse.sys
C:\Windows\System32\drivers\vmkdb.sys
C:\Windows\System32\drivers\vmnetuserif.sys
C:\Windows\System32\drivers\vmnetadapter.sys
CreateFile
◆\\.\HGFS
,主机和虚拟机之间共享的文件系统
◆\\.\vmci
,虚拟机和主机之间的通信管道
GetAdaptersAddresses
、GetAdaptersInfo
、Netbios
◆00:50:56:XX:XX:XX
◆00:1C:14:XX:XX:XX
◆00:0C:29:XX:XX:XX
◆00:05:69:XX:XX:XX
RegOpenKeyEx
、RegQueryValueEx
HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System
中键值 “SystemBiosVersion” 包含 “VMware, Inc.”HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\BIOS
中包含键值“BIOSVendor” 为 “VMware, Inc.”
“BIOSVersion” 的起始字符串为 “VM.”
“SystemManufacturer” 为 “VMware, Inc.”
“SystemProductName” 包含 “VMware.”
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\SystemInformation
中也有类似的信息HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0
HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\Scsi\Scsi Port 1\Scsi Bus 0\Target Id 0\Logical Unit Id 0
HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\Scsi\Scsi Port 2\Scsi Bus 0\Target Id 0\Logical Unit Id 0
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Disk\Enum
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Enum\IDE
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Enum\SCSI
GetSystemFirmwareTable
GetSystemFirmwareTable
CreateToolhelp32Snapshot
、Process32First
、Process32Next
◆Vmtoolsd.exe
◆Vmwaretray.exe
◆Vmwareuser.exe
◆VGAuthService.exe
◆Vmacthlp.exec
SetupDiGetClassDevs
、SetupDiGetDeviceRegistryProperty
VOID CheckBIOSSerialNumberWMI()
{
IWbemServices* pSvc = NULL;
IWbemLocator* pLoc = NULL;
IEnumWbemClassObject* pEnumerator = NULL;
BOOL bFound = FALSE;
HRESULT hRes;
// Init WMI
if (!InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2")))
return;
// If success, execute the desired query
if (!ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_BIOS")))
return;
// Get the data from the query
IWbemClassObject* pclsObj = NULL;
ULONG uReturn = 0;
VARIANT vtProp;
while (pEnumerator)
{
hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
if (0 == uReturn)
break;
// Get the value of the Name property
VariantInit(&vtProp);
hRes = pclsObj->Get(_T("SerialNumber"), 0, &vtProp, 0, 0);
if (SUCCEEDED(hRes)) {
if (vtProp.vt == VT_BSTR) {
if (StrStrI(vtProp.bstrVal, _T("VMWare")) != 0)
{
bFound = TRUE;
VariantClear(&vtProp);
pclsObj->Release();
break;
}
}
VariantClear(&vtProp);
}
// release the current result object
pclsObj->Release();
}
// Cleanup
pSvc->Release();
pLoc->Release();
pEnumerator->Release();
CoUninitialize();
PrintResult(bFound, _T("Checking SerialNumber from BIOS using WMI"));
}
SELECT * FROM Win32_Fan // 风扇
SELECT * FROM Win32_CacheMemory //
SELECT * FROM Win32_VoltageProbe // 电压探针
SELECT * FROM Win32_PerfFormattedData_Counters_ThermalZoneInformation // 热区信息
SELECT * FROM CIM_Memory // 物理内存
SELECT * FROM CIM_Sensor // 传感器设备
SELECT * FROM CIM_NumericSensor // 数字传感器
SELECT * FROM CIM_TemperatureSensor // 温度传感器
SELECT * FROM CIM_VoltageSensor // 电压传感器
二
基于指令的检测
bool isVmwarePresent()
{
__try {
_asm {
mov eax, 0x564d5868 // 'VMXh'
mov ebx, 0
mov cx, 1
mov dx, 0x5658 // 'VX'
in eax, dx
}
return true;
}
__except (GetExceptionCode() == EXCEPTION_PRIV_INSTRUCTION) {
return false;
}
}
BOOL CheckCPUIDVendor()
{
INT CPUInfo[4] = { -1 };
CHAR szHypervisorVendor[0x40];
__cpuid(CPUInfo, 0x40000000);
SecureZeroMemory(szHypervisorVendor, sizeof(szHypervisorVendor));
memcpy(szHypervisorVendor, CPUInfo + 1, 12);
if (_strcmpi(szHypervisorVendor, "VMwareVMware") == 0)
return TRUE;
return FALSE;
}
BOOL CheckCPUIDVendor()
{
INT CPUInfo[4] = { -1 };
__cpuid(CPUInfo, 1);
if ((CPUInfo[2] >> 31 ) & 1)
return TRUE;
return FALSE;
}
BOOL rdtsc_diff_vmexit()
{
ULONGLONG tsc1 = 0;
ULONGLONG tsc2 = 0;
ULONGLONG avg = 0;
INT cpuInfo[4] = {};
// Try this 10 times in case of small fluctuations
for (INT i = 0; i < 10; i++)
{
tsc1 = __rdtsc();
__cpuid(cpuInfo, 0);
tsc2 = __rdtsc();
// Get the delta of the two RDTSC
avg += (tsc2 - tsc1);
}
// We repeated the process 10 times so we make sure our check is as much reliable as we can
avg = avg / 10;
return (avg < 1000 && avg > 0) ? FALSE : TRUE;
}
bool IsVmcpuidSupported()
{
bool supported = true;
void* mempool;
char vmcpuid[] = "\x0F\xC7\xC8\x01\x00"; // VMCPUID OPCODE
mempool = malloc(sizeof(vmcpuid));
memcpy(mempool, &vmcpuid, sizeof(vmcpuid));
DWORD prevAccess;
VirtualProtect(mempool, sizeof(vmcpuid), PAGE_EXECUTE_READ, &prevAccess);__try {
((void(*)())mempool)();
}
__except(EXCEPTION_EXECUTE_HANDLER) {
supported = false;
}
return supported;
}
CMPXCHG8B EAX
ADD DWORD PTR DS:[EAX],EAX
三
其他检测方法
function Get-AntiVMwithTemperature {
$t = Get-WmiObject MSAcip_ThermalZoneTemperature -Namespace "root/wmi"$valorTempKelvin = $t.CurrentTemperature / 10
$valorTempCelsius = $valorTempKelvin - 273.15$valorTempFashrenheit = (9/5) * $valorTempCelsius + 32
return $valorTempCelsius.ToString() + " C : " + valorTempFashrenheit.ToString() + \
" F : " + $valorTempKelvin.ToString() + "K"
}
◆GetTickCount函数调用两次,间隔20秒休眠。如果GetTickCount值没有改变(即时间已经加速),恶意软件将终止自身。
◆连续两次调用GetCursorPos函数。如果鼠标在X轴上的位置发生了变化(即鼠标位置是随机生成的),恶意软件将终止自身。
◆调用GetGlobalMemoryStatusEx。如果实际物理内存的数量小于1.5GB,恶意软件将终止自身
◆只有左键(物理)鼠标按钮按下至少三次后(在无限循环中查询GetAsyncKeyState),负载才开始。