Как я могу обнаружить (.NET или Win32), если мое приложение запущено на виртуальной машине?
Как определить, работает ли мое приложение на виртуальной машине?
Ответ 1
В соответствии с Виртуальный компьютерный парень в блоге" Обнаружение виртуальных машин Microsoft ", вы можете использовать WMI для проверки производителя материнской платы. В PowerShell:
(gwmi Win32_BaseBoard).Manufacturer -eq "Microsoft Corporation"
Ответ 2
Это то, что я использую:
using (var searcher = new System.Management.ManagementObjectSearcher("Select * from Win32_ComputerSystem"))
{
using (var items = searcher.Get())
{
foreach (var item in items)
{
string manufacturer = item["Manufacturer"].ToString().ToLower();
if ((manufacturer == "microsoft corporation" && item["Model"].ToString().ToUpperInvariant().Contains("VIRTUAL"))
|| manufacturer.Contains("vmware")
|| item["Model"].ToString() == "VirtualBox")
{
return true;
}
// Check "HypervisorPresent" property, which is available in some cases.
var hypervisorPresentProperty
= item.Properties
.OfType<PropertyData>()
.FirstOrDefault(p => p.Name == "HypervisorPresent");
if ((bool?)hypervisorPresentProperty?.Value == true)
{
return true;
}
}
}
}
return false;
Изменить 2014-12-02. Обновлен код, чтобы он больше не обнаруживал Microsoft Surface Pro как виртуальную машину. Спасибо Эрику Функенбушу за это.
Изменить 2017-06-29: обновлен код, чтобы он также проверял значение свойства HypervisorPresent
.
Ответ 3
Вот пример одного из способов сделать это. Он работает только с Microsoft Virtual PC и VMWare, но это старт: http://www.codeproject.com/KB/system/VmDetect.aspx
Ответ 4
Jay Abuzi показал решение в powershell. Здесь же, как функция С#:
/// <summary>
/// Detect if this OS runs in a virtual machine
///
/// http://blogs.msdn.com/b/virtual_pc_guy/archive/2005/10/27/484479.aspx
///
/// Microsoft themselves say you can see that by looking at the motherboard via wmi
/// </summary>
/// <returns>false</returns> if it runs on a fysical machine
public bool DetectVirtualMachine()
{
bool result = false;
const string MICROSOFTCORPORATION ="microsoft corporation";
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2","SELECT * FROM Win32_BaseBoard");
foreach (ManagementObject queryObj in searcher.Get())
{
result = queryObj["Manufacturer"].ToString().ToLower() == MICROSOFTCORPORATION.ToLower();
}
return result;
}
catch (ManagementException ex)
{
return result;
}
}
Ответ 5
Эта функция C обнаружит гостевую ОС VM: (Протестировано в Windows, скомпилировано с помощью Visual Studio)
#include <intrin.h>
bool isGuestOSVM()
{
unsigned int cpuInfo[4];
__cpuid((int*)cpuInfo,1);
return ((cpuInfo[2] >> 31) & 1) == 1;
}
Ответ 6
Для тестов нижнего уровня я рекомендую посмотреть ScoopyNG [1]. Это набор известных низкоуровневых, хорошо работающих методов обнаружения vm, хотя и немного устаревший.
Если вы действительно хотите полагаться на другие вещи, такие как установленные инструменты (дополнения VM *), их гораздо легче "подделать".
В этой статье [2] Blog Post также есть довольно хороший обзор, из материала с низким уровнем asm, проверка определенных DLL, файлов и ключей реестра для проверки.
[1] http://trapkit.de/research/vmm/scoopyng/index.html
[2] http://securitykitten.github.io/vm-checking-and-detecting/
Ответ 7
Самый простой способ выяснить, работает ли мое приложение С# на VMware vmware или нет, - это проверить MAC-адрес карты (-ов) NIC. Если это VMware VM, это всегда будет: 00: 50: 56: XX: YY: ZZ
Вы можете перечислить через сетевые карты как это разрешено здесь.
Ответ 8
public static bool isVirtualMachine()
{
const string MICROSOFTCORPORATION = "microsoft corporation";
const string VMWARE = "vmware";
foreach (var item in new ManagementObjectSearcher("Select * from Win32_ComputerSystem").Get())
{
string manufacturer = item["Manufacturer"].ToString().ToLower();
// Check the Manufacturer (eg: vmware, inc)
if (manufacturer.Contains(MICROSOFTCORPORATION) || manufacturer.Contains(VMWARE))
{
return true;
}
// Also, check the model (eg: VMware Virtual Platform)
if (item["Model"] != null)
{
string model = item["Model"].ToString().ToLower();
if (model.Contains(MICROSOFTCORPORATION) || model.Contains(VMWARE))
{
return true;
}
}
}
return false;
}
Ответ 9
этот код на С++ обнаружит Vmware-продукты, такие как express, esx, fusion или workstation
// VMWareDetector.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "windows.h"
#include <conio.h>
void CheckVM(void);
int main()
{
CheckVM();
_getch();
return 0;
}
void CheckVM(void)
{
unsigned int a, b;
__try {
__asm {
// save register values on the stack
push eax
push ebx
push ecx
push edx
// perform fingerprint
mov eax, 'VMXh' // VMware magic value (0x564D5868)
mov ecx, 0Ah // special version cmd (0x0a)
mov dx, 'VX' // special VMware I/O port (0x5658)
in eax, dx // special I/O cmd
mov a, ebx // data
mov b, ecx // data (eax gets also modified
// but will not be evaluated)
// restore register values from the stack
pop edx
pop ecx
pop ebx
pop eax
}
}
__except (EXCEPTION_EXECUTE_HANDLER) {}
printf("\n[+] Debug : [ a=%x ; b=%d ]\n\n", a, b);
if (a == 'VMXh') { // is the value equal to the VMware magic value?
printf("Result : VMware detected\nVersion : ");
if (b == 1)
printf("Express\n\n");
else if (b == 2)
printf("ESX\n\n");
else if (b == 3)
printf("GSX\n\n");
else if (b == 4)
printf("Workstation\n\n");
else
printf("unknown version\n\n");
}
else
printf("Result : Not Detected\n\n");
}