Как узнать виртуальная машина или нет windows

[Решение найдено!] Если это Windows, просто взгляните на аппаратные экраны. У него будет миллиард пять виртуальных устройств под…

Как узнать, работаю ли я на виртуальной машине или нет?


Есть ли способ узнать, является ли машина с Windows, на которой я работаю, виртуальной или физической? (Я подключаюсь с помощью RDP к машине. Если это виртуальная машина, она работает и обрабатывается VMWare).


Ответы:


Если это Windows, просто взгляните на аппаратные экраны. У него будет миллиард пять виртуальных устройств под маркой VMWare.







В окне CMD введите:

SYSTEMINFO

Вы найдете строку со следующим текстом (или аналогичным):

System Manufacturer:       VMware, Inc.
System Model:              VMware Virtual Platform



Если это обрабатывается VMware, это не так уж сложно в настоящий момент. Это может измениться в будущем.

# dmidecode -s system-manufacturer
VMware, Inc.






В Windows из CMD:

Systeminfo | findstr /i model

возвращает что-то вроде:

System Model:              VMware Virtual Platform
                           [01]: Intel64 Family 6 Model 26 Stepping 5 GenuineInt


В Linux запустите это:

$ dmesg |grep -i hypervisor
 Hypervisor detected: KVM




Если вы находитесь в Windows, как говорит Castrocra , вы можете запустить systeminfoкоманду из командной оболочки cmd , а затем искать «версию BIOS».

Вероятно, это настоящие машины:

BIOS Version:              Dell Inc. A03, 06/12/2010
BIOS Version:              Phoenix Technologies, LTD MS7254 1.08, 08/03/2007

С другой стороны, это почти наверняка виртуальная машина:

BIOS Version:              VMware, Inc. VMW71.00V.0.B64.1201040214, 04/01/2012





На него уже дан ответ, но FWIW вы можете сделать это в powershell:

gwmi -q "select * from win32_computersystem"

«Производитель» будет «Корпорация Microsoft», а «Модель» будет «Виртуальная машина», если это виртуальная машина, или в противном случае должна отображаться обычная информация о производителе, например «Dell Inc.» и «PowerEdge R210 II» соответственно.






Если это Unix VM, используйте imvirt . Это скрипт на Perl, который обнаруживает VMWare, Xen и некоторые другие.



Один (относительно) простой способ обнаружения ключевой информации о виртуализации — через WMI / WBEM. Вы можете использовать пространство имен root CIM2 и получить доступ к классу Baseboard (полному интересной информации BIOS), чтобы получить описание «физической» системы. Этот класс часто включает информацию о материнской плате и шасси — производство, модель, серийный номер, другое.

Запустите следующую команду из командной строки или сеанса PowerShell:

wmic baseboard get manufacturer, product, Serialnumber, version


Еще проще — wmic / node: bios получает серийный номер

Все, что возвращает серийный номер в стиле Dell, является физическим.

Он также выдаст «VMware-42 22 26 a8 dd 6e e3 b3-2e 03 fc 2c 92 ae 2e 89», если это виртуальная машина.


У меня был тот же вопрос, и я обнаружил, что существует много процессов с именем «VM», например VMWareTray.exe.



nbtstat -a Результат покажет вам, что виртуальные машины имеют специальный префикс 00-50-56-XX-XX-XX. Есть также другой префикс, который он использует, но я не могу вспомнить в верхней части головы, но я помню, что Vcenter использует 00-50-56-XX-XX-XX, так что это тот, который я проверяю только.

Я думаю, что это лучший способ, лично.



8 ответов

Вы можете попытаться использовать следующий PowerShell script, он использует WMI, чтобы узнать, является ли машина виртуальной машиной или физической машиной.


gwmi -q "select * from win32_computersystem"

Certainly, you can use C# code to query WMI too. The output of script above will be like following:

Domain:   ...
Manufacturer: Microsoft Corporation
Model: Virtual Machine
Name : .....
....

user2151805
18 март 2013, в 22:07

Поделиться

Чтобы проверить это из командной строки, вы можете запустить это: systeminfo | find "System"

Пример вывода для виртуального сервера:

System Manufacturer:       Microsoft Corporation    
System Model:              Virtual Machine    
System Type:               x64-based PC

Пример вывода для физического сервера:

System Manufacturer:       HP
System Model:              ProLiant BL460c G6
System Type:               x64-based PC

Mattias Lindberg
08 авг. 2013, в 12:09

Поделиться

Насколько я знаю, нет простого способа сделать это.

Есть несколько обходных решений, но есть, по крайней мере, насколько я знаю, не одноразовое решение.

Бен Армстронг написал сообщение о Обнаружение виртуальных машин Microsoft и там трюк низкого уровня, который может определить, работаете ли вы в Virtual PC или VMWare, но это все равно не оставляет VirtualBox и других.

Трюк, который вы можете попробовать, это определить, установлены ли инструменты VMWare или VirtualBox Tools. В большинстве случаев они устанавливаются на гостевой ОС для обеспечения необходимых функций, но будет сложно поддерживать различные установки GUIDS на вашем конце, чтобы это не идеальное решение.

— Кроме того, если виртуальная машина работает в среде Linux KVM, вывод будет таким же
Изображение 145624

Jensen
18 март 2013, в 21:07

Поделиться

Нет простого способа узнать, работаете ли вы в голом металле или на виртуальном компьютере, самое лучшее, что вы можете сделать, это получить некоторую информацию об оборудовании и сделать обоснованное предположение, например, если машина сетевой адаптер, который содержит Microsoft, VMware, Oracle, Hyper-V, Virtual или VirtualBox, скорее всего, это виртуальная машина, учитывая, что ни Microsoft, ни Oracle, ни VMware не создают сетевые карты.

Как вы используете С#, класс для получения этой и другой информации об оборудовании ManagementClass, также есть этот приятный project, который позволяет извлекать тонны информации с вашего компьютера с помощью ManagementClass.

Rafael
18 март 2013, в 20:58

Поделиться

Запустите командную строку командной строки systeminfo, чтобы просмотреть детали системы системы. Там вы найдете информацию о виртуле и физической машине.

Ajay Yadav
02 апр. 2013, в 19:36

Поделиться

вы можете использовать эту команду в cmd или powershell

Systeminfo

Вы найдете строку со следующим текстом (или подобным):

Производитель системы: VMware, Inc.
Модель системы: виртуальная платформа VMware

Hamid KhanZadeh
23 дек. 2017, в 06:52

Поделиться

Попробуйте следующее:

FOR /F "tokens=*" %a IN ('wmic bios get bioscharacteristics^|find /c "33"') DO set USBlegacy=%a

Это возвращает «1» для ограниченного диапазона рабочих столов и ноутбуков в моей среде и «0» для рабочих станций VMWare 9, ESX 5.5 и Citrix 6.5 и 7.6. BIOSCharacteristic «50» (один «зарезервирован для системного поставщика» ) Я нашел только в четырех виртуальных средах, чтобы работать в обратном порядке.

Изменить: или там:

FOR /F "tokens=*" %a IN ('wmic path win32_pnpentity get ^|find /c "ACPI Fan"') DO set ACPIfan=%a

Возвращает «5» на рабочем столе HP «0» на рабочей станции VMware 9 и ESX 5.5, а не проверяется другими.

AndyKn
14 июль 2015, в 15:12

Поделиться

Единственный * программный * способ, которым я знаю это надежно:

  • Напишите приложение, которое сканирует вашу сеть (или диапазон IP), чтобы получить список машин.
  • Покажите эти машины человеку и попросите их установить флажок, если это VM…
  • Распечатайте отчет.

NotMe
18 март 2013, в 21:29

Поделиться

Ещё вопросы

  • 0CSS: неверно работает по-другому в Chrome v. FF?
  • 0Какой файл настраивает кэширование в Windows Embedded Compact 7.0?
  • 1Являются ли точки за пределами усиков?
  • 0Слайдер / мастер, который ведет к определенной странице на основе сделанного выбора
  • 0AngularJS тестирует фабрику с мокко
  • 1Как расширить ListView при заполнении элемента списка?
  • 0Преобразование «Значений» из длинного текстового столбца в формат даты
  • 0Как добавить функцию удаления в JQuery с PHP?
  • 1модульное тестирование атрибутов валидатора dataannotations
  • 1Нужно ли синхронизировать доступ к аргументам и локальным методам при одновременном вызове метода?
  • 1Как найти совпадение одинаковых значений в двух разных столбцах набора данных в Python
  • 1Проверка содержимого EditText, как только пользователь вводит данные
  • 0Исчезают шаблоны руля загрузки файлов jQuery
  • 1TCP слушатель получает только первое сообщение
  • 0Запись данных с офсетной C ++
  • 0Как применить темы к HTML внутри метода append ()
  • 1Discord.py как проверить, есть ли у ввода десятичное число
  • 1Сдвиг значений для очистки нулевых пробелов в массиве
  • 1Одновременное завершение дочерних процессов и выполнение обещаний
  • 1Объединение двух списков диктов в Python, когда некоторые диктанты являются дубликатами
  • 1Нужно регулярное выражение, совпадающее с текстовой строкой, которая может слегка отличаться в интервале
  • 1Как случайным образом раскрасить сетку (каждая строка случайным цветом)
  • 0Загрузка файла не работает обновление страницы
  • 1Невозможно запустить мое приложение Spring на tcServer из SpringTools
  • 0Используя область родительского div
  • 0Нет ли возможной потери данных при преобразовании из строки в строку с помощью строкового конструктора?
  • 0PHP / MySQL n-ая строка с DATE_SUB и т. Д.
  • 0Как получить имена полей $ _POST
  • 0angular-translate не работает с шаблонами
  • 0Отображение тегов DIV: встроенный блок;
  • 1Ошибка компилятора с массивами void [n]?
  • 0Как вернуть ответ JSON от REST API Laravel 4?
  • 1определить, где на экране произошло событие
  • 0Как использовать ng-repeat в сетке
  • 0хочу всегда держать позицию веб-страницы включенной после перезагрузки
  • 0MySQL Cursor не может выбрать переменную извлечения
  • 1Node.js: как вернуть отклоненное обещание, не получая UnhandledPromiseRejectionWarning
  • 0PHP array_slice ИЛИ array_pop не del?
  • 0мой setTimeout не работает правильно
  • 0Как использовать свойство fadeOut jQuery с Javascript Text Snippet
  • 1Python: вложенные циклы не работают во втором цикле
  • 1Как сделать интерфейс в JavaScript и вызвать метод Android?
  • 1Обновлять словарь за итерацию, а не за весь
  • 0угловой JavaScript не будет применяться к вставленному элементу пользовательского интерфейса
  • 0Реализация развертывания и свертывания в представлениях Rails
  • 0Приложение MeanJS не может создать модуль AngularJS после нажатия
  • 0Поместите Div поверх видео, используя JavaScript
  • 1Javascript действует по-разному в inappbrowser и Chrome — неопределенные глобальные переменные
  • 0Получить значения из элемента из функции со строковым параметром
  • 0Проверьте форму перед вызовом модального

Содержание

  • Как узнать, какие у меня окна виртуальные или физические?
  • Можете ли вы идентифицировать виртуальную машину?
  • Windows Server — это виртуальная машина?
  • Есть ли в Windows 10 виртуальная машина?
  • Как скрыть виртуальную машину?
  • Как узнать, является ли сервер AIX виртуальным или физическим?
  • Может ли браузер LockDown обнаруживать виртуальную машину?
  • Может ли Javascript обнаружить виртуальную машину?
  • Что такое трюк с Cpuid?
  • Что лучше Hyper-V или VMware?
  • Выпускает ли Microsoft Windows 11?
  • Какая виртуальная машина лучше всего подходит для Windows 10?
  • Hyper-V — тип 1 или тип 2?
  • Как открыть BIOS в Windows 10?

Как узнать, какие у меня окна виртуальные или физические?

Если вы хотите узнать, является ли машина, к которой вы подключены, виртуальной или физической, есть несколько способов сделать это.

  1. Проверьте системный лоток. …
  2. Проверьте «Программы и компоненты» на панели управления. …
  3. Проверьте системную информацию. …
  4. Используйте Powershell или командную строку. …
  5. Отметьте все серверы в домене.

Можете ли вы идентифицировать виртуальную машину?

Нет. Это невозможно обнаружить с полной точностью.. Некоторые системы виртуализации, такие как QEMU, эмулируют всю машину до аппаратных регистров.

Windows Server — это виртуальная машина?

Windows Server 2019 почти так же прост в установке, как и Windows 10. В этой статье я расскажу вам пошагово процесс установки Windows Server 2019 на виртуальной машине (ВМ) Hyper-V.

Одним из самых мощных инструментов Windows 10 является встроенная платформа виртуализации, Hyper-V. Используя Hyper-V, вы можете создать виртуальную машину и использовать ее для оценки программного обеспечения и услуг, не рискуя целостностью или стабильностью вашего «настоящего» ПК. … Windows 10 Домашняя не включает поддержку Hyper-V.

Как скрыть виртуальную машину?

Чтобы отозвать доступ и сделать виртуальную машину невидимой, вам просто нужно назначить объекту виртуальной машины роль «Нет доступа».

  1. Перейдите к виртуальной машине.
  2. Откройте вкладку «Разрешения».
  3. Щелкните правой кнопкой мыши и выберите Добавить разрешения …
  4. Назначьте роль без доступа пользователю, от которого вы хотите скрыть виртуальную машину.
  5. Нажмите ОК.

Как узнать, является ли сервер AIX виртуальным или физическим?

В Aix попробуйте использовать lscfg на известная виртуальная машина и вы можете обнаружить, что информация о процессоре указывает на то, что компьютер виртуальный.

Может ли браузер LockDown обнаруживать виртуальную машину?

Чтобы сохранить академическую честность экзамена, студентам не разрешается бегать LockDown Browser Student Edition при обнаружении виртуальной машины в системе. … Антивирусное ПО может иногда приводить к такому типу ошибок при запуске небольших виртуальных машин «песочницы».

Может ли Javascript обнаружить виртуальную машину?

3 ответа. Веб-серверы могут сообщать сведения только о веб-браузерах. через строку их пользовательского агента. Если вы не используете специальный веб-браузер (что маловероятно), который обнаруживает, что он работает на виртуальной машине, тогда веб-сервер не должен знать.

Что такое трюк с Cpuid?

CPUID — это метод обнаружения на уровне инструкций и такие методы действительно трудно обнаружить, поскольку вы знаете, что для перехвата каждого выполнения CPUID вам следует либо выполнять инструкции шаг за шагом (что очень медленно и почти невозможно), либо инструментировать целевую программу.

Что лучше Hyper-V или VMware?

Если вам требуется более широкая поддержка, особенно для старых операционных систем, VMware — это хороший выбор. Если вы работаете в основном с виртуальными машинами Windows, Hyper-V — подходящая альтернатива. … Например, в то время как VMware может использовать больше логических ЦП и виртуальных ЦП на узел, Hyper-V может разместить больше физической памяти на узел и виртуальную машину.

Выпускает ли Microsoft Windows 11?

Его выпуск будет сопровождаться бесплатным обновлением для совместимых устройств с Windows 10 через Центр обновления Windows. 28 июня Microsoft объявила о выпуске первой предварительной сборки и SDK Windows 11 для участников программы предварительной оценки Windows. 31 августа 2021 года Microsoft объявила, что выпуск Windows 11 запланирован на 5 октября 2021 г..

Какая виртуальная машина лучше всего подходит для Windows 10?

Лучшая виртуальная машина для Windows 10

  • Virtualbox.
  • VMware Workstation Pro и Workstation Player.
  • VMware ESXi.
  • Microsoft Hyper-V.
  • VMware Fusion Pro и Fusion Player.

Hyper-V — тип 1 или тип 2?

Hyper-V. Гипервизор Microsoft называется Hyper-V. Это Гипервизор 1-го типа его обычно принимают за гипервизор 2-го типа. Это связано с тем, что на хосте работает операционная система, обслуживающая клиентов.

Как открыть BIOS в Windows 10?

Чтобы войти в BIOS из Windows 10

  1. Нажмите -> Настройки или нажмите Новые уведомления. …
  2. Щелкните Обновление и безопасность.
  3. Нажмите «Восстановление», а затем «Перезагрузить сейчас».
  4. После выполнения вышеуказанных процедур появится меню параметров. …
  5. Выберите Дополнительные параметры.
  6. Щелкните Настройки прошивки UEFI.
  7. Выберите «Перезагрузить».
  8. Это отображает интерфейс утилиты настройки BIOS.

Интересные материалы:

Как вы играете в мультиплеер на Multicraft?
Как вы играете в НХЛ 2009?
Как вы играете в Pokemon go home?
Как вы играете в прятки онлайн?
Как вы играете в Призрака?
Как вы играете в противостояние?
Как вы играете в Shadow Fight?
Как вы играете в солончак и святилище?
Как вы играете в Судный день в последнем убежище?
Как вы играете в угадывание объекта?

Одним жуть каким прохладным январским утром от знакомого прилетел вопрос — как на C# определить, не запущена ли программа в ОС (оконное приложение в ОС Windows 7 или новее) на виртуальной машине.

Требования к такому детектору были достаточно жёсткими:

  1. Должен быть полностью в исходных кодах,
  2. Должен собираться с помощью Visual Studio,
  3. Должен работать из-под аккаунта непривилегированного пользователя (нельзя использовать методы, требующие, к примеру, установки драйверов устройств, или иных операций, для которых нужны права администратора),
  4. Разрешено использовать .NET Framework 4.5 и никаких лишних зависимостей (типа Visual C++ Redistributable Package).

Под катом описание реализованного детектора на C# (в следующей части — с некоторыми элементами C++) и приличным количеством неприличного кода с использованием Visual Studio 2015 Community.

Структура публикации

  • 1 уровень. Изучение матчасти и простейших существующих решений:
    • немного теории касательно виртуализации,
    • реализация проверки ВМ с помощью данных из Windows Management Instrumentation (WMI).
  • 2 уровень. Поиск статей и публикаций про детектирование запуска в виртуальных машинах:
    • допиливаем реализацию с WMI,
    • работа с инструкцией CPUID.
  • 3 уровень. Поиск материалов с хакерских конференций:
    • допиливаем работу с CPUID,
    • делаем сводную таблицу параметров и результатов тестирования.

1 уровень. Изучение матчасти и существующих решений

Немного теории касательно виртуализации

Прежде, чем пытаться писать детектор сферического коня в вакууме виртуальной машины, следует кратко обозначить, как в рамках задачи мы понимаем термин «виртуальная машина».

Понятие виртуализации можно поделить на две категории (1):

  • Первая — виртуализация ресурсов. Рассмотрим на живом примере, почему принцип работы сервиса хранения файлов Dropbox можно трактовать как виртуализацию ресурсов:
    1. Мы точно знаем, как загружать/выгружать файлы, и как взаимодействовать с сервисом, но как это всё работает внутри мы с уверенностью сказать не можем => инкапсуляция.
    2. У каждого пользователя есть свой уникальный аккаунт, у каждого аккаунта установлена квота на размер сохраняемых файлов, для каждого аккаунта можно настраивать разрешения на доступ индивидуально (хотя по факту данные разных пользователей вполне могут храниться на одном и том же носителе информации) => разделение ресурсов.
    3. Скорее всего, под капотом Dropbox находится не один и не два компьютера, а как минимум пара сотен серверов, функционирующих и обрабатывающих команды от клиентов в рамках системы Dropbox как единое целое => кластеризация.
  • Вторая — виртуализация платформ — создание программных систем на основе существующих аппаратно-программных комплексов, зависящих или независящих от них (1).

Во второй категории сразу введём два термина: система, предоставляющая аппаратные ресурсы и ПО для виртуализации (хостовая система, host) и эмулируемая система (гостевая система, guest).

При этом в реальности в роли «гостевой системы» могут выступать:

  1. Абсолютно всё аппаратное и программное обеспечение эмулируемой системы — такой тип виртуализации называется полной эмуляцией или симуляцией. Примеры программ, обеспечивающих такой тип виртуализации: Bochs, QEMU.
  2. Всё программное обеспечение и только часть аппаратного (часть достаточная для обеспечения изоляции гостевой системы) — такой тип виртуализации назовём частичной эмуляцией или нативной виртуализацией. Примеры программ, обеспечивающих такой тип виртуализации: VMWare Workstation, VMWare ESXi, Microsoft Hyper-V, Oracle VirtualBox.
  3. Также существуют частичная виртуализация, паравиртуализация, виртуализация уровня операционной системы и виртуализация уровня приложений. Во всех трёх случаях физически ОС у нас одна, а гостевыми системами считаются либо отдельные процессы, либо отдельные группы процессов (например, user-mode процессы).

Итог сего экскурса: в рамках статьи и создания детектора виртуальной машины нас будут интересовать только нативная виртуализация платформ (то есть проверять мы будем только запуск в окружении Hyper-V, VirtualBox или других программ, использующих нативную виртуализацию). При этом далее термин «виртуальная машина» мы будем трактовать согласно определению с сайта VMWare: «это строго изолированный контейнер ПО, содержащий операционную систему и приложения» (2).

Реализация проверки ВМ с помощью данных из Windows Management Instrumentation (WMI)

После того, как цель (определение факта работы программы в окружении с частичной эмуляцией) была более-менее уточнена, найдём самые известные виртуальные машины этого типа (далее для краткости ВМ) и способы отличить запуск ОС на реальном железе от запуска в окружении этих ВМ.

Прочитав замечательно свёрстанные рекламные страницы разработчиков популярных программ виртуализации, в голове вырисовывается некая общая схема их работы (разумеется схема работы программ, а не разработчиков):

  • Есть хостовая ОС. Не ограничивая общности будем считать, что она одна.
  • На хостовой ОС установлена программа для обеспечения виртуализации (далее гипервизор).
  • Гипервизор предоставляет интерфейс для установки и последующей работы гостевой ОС.

Примечание

: имеют место случаи, когда хостовая ОС и гипервизор есть единое тонкое целое, что позволяет уменьшить расходование ресурсов компьютера по сравнению с использованием хостовой ОС и гипервизора по отдельности (примеры: VMWare ESXi или Windows Hyper-V Server).

Вот только на практике почти в каждом гипервизоре имеется возможность установить «гостевые дополнения» (guest additions) — специальный набор программ и драйверов, дающих гипервизору
расширенный контроль за функциями гостевой ОС (проверка, а не зависла ли гостевая ОС, динамическое изменение доступной ОС оперативной памяти, «общая» мышка для хостовой и гостевой ОС). Однако, как же реализуют такое действо, если, согласно рекламе, «ВМ — это строго изолированный контейнер ПО»?

Получается, что гостевые дополнения, устанавливаемые на гостевую ОС, каким-то строго определённым образом взаимодействуют напрямую с гипервизором, запущенным в хостовой ОС. То есть если программа определения ВМ сможет воспользоваться таким взаимодействием — она докажет, что ОС запущена на ВМ! Правда, по условиям задачи доказательство надо проводить из-под User-Mode без использования собственных драйверов…

Сразу вырисовываются следующие места для проверки:

  • Поиск определённого оборудования в системе, которого на физической машине просто не может быть.
  • Поиск аппаратных интерфейсов, которые реализованы только в ВМ (или наоборот, только на физической машине).

Собственно, если ввести в поисковой строке «detect hyper-v C#» или «detect vmware C#», примерно на это и натыкаешься, осталось только обобщить.

Наиболее полное описание различных критериев проверки было найдено в статье 2013 года в журнале Хакер (3),— возьмём статью за основу. А для получения соответствующих данных об оборудовании и процессах ОС воспользуемся механизмом Windows Management Instrumentation (WMI) — дословно «инструментарием управления Windows». В частности, через WMI можно несложно, быстро и без прав администратора получить большое количество информации об оборудовании, которое видит ОС.

Для получения данных через WMI нам понадобится построить запрос на языке WQL (WMI Query Language), который по сути является сильно упрощённым SQL. Например, если мы хотим получить через WMI имеющуюся в ОС информацию о процессорах, требуется выполнить следующий запрос:

SELECT * FROM Win32_Processor

Ответ на этот запрос — набор объектов типа Win32_Processor с заранее известными названиями полей (подробный список доступных полей и классов см. в 4). Разумеется, если нам не требуются все-все поля, вместо * можно перечислить через запятую только необходимые. В WQL-операторе SELECT, по аналогии с SQL, также поддерживается условие WHERE, позволяющее делать выборку только по объектам, значения в полях которых удовлетворяют указанным условиям.

Для «затравки» научимся получать следующие данные из WMI-объектов следующих типов (данные и ожидаемые в ВМ значения взяты из 3):

WMI-объект и его свойства Условие на WQL-запрос объектов Как использовать
Win32_Processor  
     Manufacturer   В случае VirtualBox равен ‘VBoxVBoxVBox’, в случае VMWare — ‘VMwareVMware’, в случае Parallels — ‘prl hyperv ‘.
Win32_BaseBoard  
     Manufacturer   В случае Hyper-V равен ‘Microsoft Corporation’ при том, что Microsoft материнские платы не выпускает (интересно, а что показывает этот параметр на планшетах Microsoft Surface?).
Win32_DiskDrive  
     PNPDeviceID   В случае VirtualBox содержит ‘VBOX_HARDDISK’, в случае VMWare содержит ‘VEN_VMWARE’.
Win32_NetworkAdapter  
     MACAddress PhysicalAdapter=1 Известно, что по трём старшим байтам MAC-адреса можно определить производителя — и производители виртуальных машин не исключение (то есть если адаптер с признаком PhysicalAdapter=1 но имеет MAC-адрес из пула VMWare — то с высокой вероятностью программа была запущена на ВМ).
Win32_Process  
     Name   При установке гостевых дополнений на ВМ в системе появляются дополнительные процессы с известными именами.

Реализуем получение данных об оборудовании через WMI в отдельном проекте в виде библиотеки TTC.Utils.Environment.

Структурируем проект следующим образом:

  1. Entities — объекты с данными (сущности), полученными от WMI.
  2. Services — сервисы; например, служба, инкапсулирующая взаимодействие с WMI-обёрткой .NET.
  3. Interfaces — интерфейсы; например, интерфейс сервиса работы с WMI.
  4. Queries — объекты, содержащие параметры запросов к WMI, с помощью которых извлекаются заданные типы сущностей.

Хочется, чтобы пользователь данной библиотеки мог написать примерно такой код:

var bios = wmiService.QueryFirst<WmiBios>(new WmiBiosQuery());
var processors = wmiService.QueryAll<WmiProcessor>(new WmiProcessorQuery());

и не волновался по поводу механизма взаимодействия с WMI, построения запроса или преобразования ответа в строго типизированный класс языка C#.

Что ж, реализовать такое на самом деле не очень сложно.

Сначала подключим к проекту ссылку на библиотеку System.Management (именно в ней находятся классы .NET для доступа к WMI). Далее опишем интерфейс сервиса IWmiService (реализация этого интерфейса будет извлекать данные и преобразовывать их в строго типизированные объекты):

Код IWmiService.cs

/// <summary>
/// Интерфейс сервиса получения данных Windows Management Instrumentation (WMI).
/// </summary>
public interface IWmiService
{
    /// <summary>
    /// Получение первой записи из указанного запроса к WMI.
    /// </summary>
    /// <typeparam name="TResult">Тип сущности, в которую выгружаются результаты запроса.</typeparam>
    /// <param name="wmiQuery">Объект, содержащий параметры WMI-запроса.</param>
    /// <returns>Сущность с результатами запроса.</returns>
    TResult QueryFirst<TResult>(WmiQueryBase wmiQuery)
        where TResult : class, new();

    /// <summary>
    /// Получение набора записей из указанного запроса к WMI.
    /// </summary>
    /// <typeparam name="TResult">Тип сущности, в которую выгружаются результаты запроса.</typeparam>
    /// <param name="wmiQuery">Объект, содержащий параметры WMI-запроса.</param>
    /// <returns>Коллекция сущностей с результатами запроса.</returns>
    IReadOnlyCollection<TResult> QueryAll<TResult>(WmiQueryBase wmiQuery)
        where TResult : class, new();
}

Теперь установим как будут выглядеть сущности в нашем проекте. Предположим для детектирования нам потребуются следующие поля из WMI-объектов типа Win32_BaseBoard:

Код WmiBaseBoard.cs — до

public class WmiBaseBoard
{
    public string Manufacturer { get; private set; }

    public string Product { get; private set; }

    public string SerialNumber { get; private set; }
}

В идеале надо писать DTO, чтобы с его помощью транслировать данные из результата WML-запроса в вышеуказанную сущность, но если постулировать, что свойства сущностей в проекте будут 1 к 1 соответствовать полям объектов из результатов WML-запроса, то делать DTO на каждую сущность значит писать достаточно много однообразного кода.

Воспользуемся главным свойством любого программиста (ленью) и вместо создания полноценной DTO просто отметим атрибутом каждое свойство следующим атрибутом, позволяющим связать свойство и поле результата WML-запроса:

Код WmiResultAttribute.cs

/// <summary>
/// Указание, какому свойству сущности соответствует поле объекта WMI.
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class WmiResultAttribute : Attribute
{
    public WmiResultAttribute(string propertyName)
    {
        PropertyName = propertyName;
    }

    /// <summary>
    /// Имя поля в объекте WMI.
    /// </summary>
    public string PropertyName { get; }
}

Разметив свойства сущности указанными атрибутами, получим:

Код WmiBaseBoard.cs — после

public class WmiBaseBoard
{
    internal const string MANUFACTURER = "Manufacturer";
    internal const string PRODUCT = "Product";
    internal const string SERIAL_NUMBER = "SerialNumber";

    // ReSharper disable UnusedAutoPropertyAccessor.Local
    [WmiResult(MANUFACTURER)]
    public string Manufacturer { get; private set; }

    [WmiResult(PRODUCT)]
    public string Product { get; private set; }

    [WmiResult(SERIAL_NUMBER)]
    public string SerialNumber { get; private set; }
    // ReSharper restore UnusedAutoPropertyAccessor.Local
}

Осталось разобраться с объектом, который будет хранить запрос. Уверен, вы обратили внимание, что в предыдущем примере кода названия полей WQL-результатов запроса вынесены в internal-константы. Это было сделано специально чтобы не дублировать их в классе запроса. Кстати, получился интересный побочный эффект — с использованием такой модели вы не сможете прочесть из WMI данные поля некоторого WMI-объекта пока не укажете, в какое свойство какой сущности он должен извлекаться.

Код WmiQueryBase.cs

using System.Management;
/// <summary>
/// Базовый класс данных параметров запроса к WMI.
/// </summary>
public class WmiQueryBase
{
    private readonly SelectQuery _selectQuery;

    /// <summary>
    /// Конструктор запроса к WMI.
    /// </summary>
    /// <param name="className">Название таблицы, к которой производится запрос.</param>
    /// <param name="condition">Условие запроса.</param>
    /// <param name="selectedProperties">Результирующие столбцы запроса.</param>
    protected WmiQueryBase(string className, 
        string condition = null, string[] selectedProperties = null)
    {
        _selectQuery = new SelectQuery(className, condition, selectedProperties);
    }

    /// <summary>
    /// Объект со сформированным SELECT-запросом к WMI.
    /// </summary>
    internal SelectQuery SelectQuery
    {
        get { return _selectQuery; }
    }
}

Код WmiBaseBoardQuery.cs

using TTC.Utils.Environment.Entities;
public class WmiBaseBoardQuery : WmiQueryBase
{
    public WmiBiosQuery()
        : base("Win32_BaseBoard", null, new[]
        {
            WmiBios.MANUFACTURER,
            WmiBios.PRODUCT,
            WmiBios.SERIAL_NUMBER,
        })
    {
    }
}

При такой структуре классов *Query есть только одна неприятность: неудобно формировать параметры WHERE-части WML-запроса внутри класса. Приходится действовать по старинке и ручками формировать строку в зависимости от параметров:

Код WmiNetworkAdapterQuery.cs

using System.Text;
using TTC.Utils.Environment.Entities;
public class WmiNetworkAdapterQuery : WmiQueryBase
{
    private static readonly string[] COLUMN_NAMES =
        {
            WmiNetworkAdapter.GUID,
            WmiNetworkAdapter.MAC_ADDRESS,
            WmiNetworkAdapter.PNP_DEVICE_ID,
        };

    public WmiNetworkAdapterQuery(WmiNetworkAdapterType adapterType = WmiNetworkAdapterType.All)
        : base("Win32_NetworkAdapter", null, COLUMN_NAMES)
    {
        if (adapterType == WmiNetworkAdapterType.Physical)
            SelectQuery.Condition = "PhysicalAdapter=1";
        else if (adapterType == WmiNetworkAdapterType.Virtual)
            SelectQuery.Condition = "PhysicalAdapter=0";
    }
}

Хорошо: данные по сущностям раскидали, запросы писать с грехом-пополам научились, осталось только разобраться как будет выглядеть сервис, работающий с указанными классами:

Код WmiService.cs

/// <summary>
/// Сервис получения данных Windows Management Instrumentation (WMI).
/// </summary>
public class WmiService : IWmiService
{
    /// <summary>
    /// Извлечение заданных в запросе столбцов из полученных записей WMI с приведением типов.
    /// </summary>
    /// <typeparam name="TResult">Тип сущности, в которую выгружаются результаты запроса.</typeparam>
    /// <param name="managementObject">Объект, полученный в результате запроса WMI.</param>
    /// <returns>Сущность с результатами запроса.</returns>
    private static TResult Extract<TResult>(ManagementBaseObject managementObject)
        where TResult : class, new()
    {
        var result = new TResult();
        foreach (var property in typeof(TResult).GetProperties())
        {
            var wmiAttribute = (WmiResultAttribute)Attribute.GetCustomAttribute(property, typeof(WmiResultAttribute));
            if (wmiAttribute != null)
            {
                var sourceValue = managementObject.Properties[wmiAttribute.PropertyName].Value;
                var targetType = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;
                object targetValue;
                if (sourceValue == null)
                {
                    targetValue = null;
                }
                else if (targetType == typeof(DateTime))
                {
                    targetValue = ManagementDateTimeConverter.ToDateTime(sourceValue.ToString()).ToUniversalTime();
                }
                else if (targetType == typeof(Guid))
                {
                    targetValue = Guid.Parse(sourceValue.ToString());
                }
                else
                {
                    targetValue = Convert.ChangeType(
                        managementObject.Properties[wmiAttribute.PropertyName].Value, targetType);
                }
                property.SetValue(result, targetValue);
            }
        }
        return result;
    }

    /// <summary>
    /// Получение набора данных из указанного запроса к WMI.
    /// </summary>
    /// <param name="selectQuery">Запрос для получения данных.</param>
    /// <param name="searcher">Существующий объект для выполнения запросов к WMI.</param>
    /// <returns>Результирующая коллекция объектов в таблице.</returns>
    private ManagementObjectCollection QueryAll(SelectQuery selectQuery, ManagementObjectSearcher searcher = null)
    {
        searcher = searcher ?? new ManagementObjectSearcher();
        searcher.Query = selectQuery;
        return searcher.Get();
    }

    /// <summary>
    /// Получение первой строки данных из указанного запроса к WMI.
    /// </summary>
    /// <param name="selectQuery">Запрос для получения данных.</param>
    /// <param name="searcher">Существующий объект для выполнения запросов к WMI.</param>
    /// <returns>Результирующая коллекция объектов в таблице.</returns>
    private ManagementBaseObject QueryFirst(SelectQuery selectQuery, ManagementObjectSearcher searcher = null)
    {
        return QueryAll(selectQuery, searcher).Cast<ManagementBaseObject>().FirstOrDefault();
    }

    public TResult QueryFirst<TResult>(WmiQueryBase wmiQuery)
        where TResult : class, new()
    {
        var managementObject = QueryFirst(wmiQuery.SelectQuery);
        return managementObject == null ? null : Extract<TResult>(managementObject);
    }

    public IReadOnlyCollection<TResult> QueryAll<TResult>(WmiQueryBase wmiQuery)
        where TResult : class, new()
    {
        var managementObjects = QueryAll(wmiQuery.SelectQuery);
        return managementObjects?.Cast<ManagementBaseObject>()
            .Select(Extract<TResult>)
            .ToList();
    }
}

Пара слов касательно метода WmiService.Extract<TResult>.

У объектов WMI обычно достаточно большое количество свойств (причем многие поля могут иметь значение NULL). В предположении, что в рамках задачи выгружать из WMI мы будем только небольшое количество свойств объектов, логично начать маппинг данных с перебора свойств результирующей сущности. Далее, при наличии у свойства атрибута WmiResultAttribute мы считываем из объекта результата запроса значение свойства с указанным в атрибуте именем и выполняем преобразование типов. При этом, если свойство сущности имеет тип, с которым стандартный метод Convert.ChangeType не справится или преобразует тип не так, как нам хочется, мы легко можем передать управление на своё преобразование (как это сделано для типов System.DateTime и System.Guid).

Кстати, было бы ещё лучше разделить Extract на два метода: первый извлекает информацию из типа класса, второй заполняет экземпляры (иначе метод QueryAll для второго и последующих элементов выходной коллекции делает ненужную работу по повторному изучению структуры его типа). Но конкретно для целей детектирования виртуалки мы вряд ли будет ожидать более 10 объектов за один запрос, поэтому предлагаю списать эту задачу с пометкой «не реализовано, ибо природная лень». Но если у кого-то дойдут руки до такой модификации — с радостью приму вашу доработку.

Послесловие

Чтобы не заканчивать эту часть статьи только библиотекой, сделаем самое простое приложение, использующее возможности данной библиотеки для детектирования нескольких самых популярных виртуальных машин фирм VMWare, Microsoft, Parallels и Oracle на осове вышеизложенных критериев.

Создадим отдельный проект — консольное приложение TTC.Utils.VMDetect и создадим в нём такой класс DemoTrivialVmDetector:

Код WmiService.cs

/// <summary>
/// Тестовый класс для проверки запуска из-под ВМ.
/// </summary>
class DemoTrivialVmDetector
{
    private readonly IWmiService _wmiService;

    public DemoTrivialVmDetector(IWmiService wmiService)
    {
        _wmiService = wmiService;
    }

    public MachineType GetMachineType()
    {
        var wmiProcessor = _wmiService.QueryFirst<WmiProcessor>(new WmiProcessorQuery());
        if (wmiProcessor.Manufacturer != null)
        {
            if (wmiProcessor.Manufacturer.Contains("VBoxVBoxVBox"))
                return MachineType.VirtualBox;
            if (wmiProcessor.Manufacturer.Contains("VMwareVMware"))
                return MachineType.VMWare;
            if (wmiProcessor.Manufacturer.Contains("prl hyperv"))
                return MachineType.Parallels;
        }

        var wmiBaseBoard = _wmiService.QueryFirst<WmiBaseBoard>(new WmiBaseBoardQuery());
        if (wmiBaseBoard.Manufacturer != null)
        {
            if (wmiBaseBoard.Manufacturer.Contains("Microsoft Corporation"))
                return MachineType.HyperV;
        }

        var wmiDiskDrives = _wmiService.QueryAll<WmiDiskDrive>(new WmiDiskDriveQuery());
        if (wmiDiskDrives != null)
            foreach (var wmiDiskDrive in wmiDiskDrives)
            {
                if (wmiDiskDrive.PnpDeviceId.Contains("VBOX_HARDDISK"))
                    return MachineType.VirtualBox;
                if (wmiDiskDrive.PnpDeviceId.Contains("VEN_VMWARE"))
                    return MachineType.VMWare;
            }

        return MachineType.Unknown;
    }
}

Весь код, включая библиотеку и простейшее тестовое приложение, выложен в репозитории на github, отзывы и комментарии приветствуются.

В следующей части мы чутка структурируем работу с известными ВМ и с помощью ассемблерной инструкции CPUID попробуем детектировать уже неизвестные ВМ.

Источники

  1. Виртуализация: новый подход к построению IT-инфраструктуры
  2. Виртуализация при помощи VMWare
  3. Детектим виртуалки (xakep.ru)
  4. WMI: Win32 Provider (MSDN)

Как определить, что вы работаете под виртуальной машиной?



Существует ли способ определить из виртуальной машины, что ваш код выполняется внутри виртуальной машины?

Я полагаю, что существуют более или менее простые способы идентификации конкретных систем виртуальных машин, особенно если на виртуальной машине установлены расширения поставщика (например, для VirtualBox или VMWare). Но есть ли общий способ определить, что вы не работаете непосредственно на процессоре?


776  


12  

12 ответов:

Большая часть исследований по этому вопросу посвящена обнаружению так называемых атак «голубых таблеток», то есть вредоносного гипервизора, который активно пытается уклониться от обнаружения.

Классический трюк для обнаружения виртуальной машины состоит в том, чтобы заполнить ITLB, выполнить инструкцию, которая должна быть виртуализирована (что обязательно очищает такое состояние процессора, когда он дает управление гипервизору), а затем выполнить еще немного кода, чтобы определить, заполнен ли ITLB. Первая бумага на нем расположена здесь , а также довольно красочное объяснение из блога исследователя и альтернативная обратная ссылка на статью блога (Images broken).

Суть обсуждения этого вопроса заключается в том, что всегда есть способ обнаружить вредоносный гипервизор, и гораздо проще обнаружить тот, который не пытается скрыть.

Red Hat имеет программу, которая определяет, под каким (если таковые имеются) продуктом виртуализации она работает.: virt-what.

Использование стороннего поддерживаемого инструмента, такого как это-лучшая долгосрочная стратегия, чем попытка свернуть свою собственную логику обнаружения: больше глаз (тестирование против большего количества продуктов виртуализации) и т. д.

Более эмпирический подход заключается в проверке известных драйверов устройств виртуальной машины. Вы можете написать запросы WMI, чтобы найти, скажем, адаптер дисплея VMware, дисковод, сетевой адаптер и т. д. Это было бы удобно, если бы вы знали, что вам нужно беспокоиться только об известных типах узлов виртуальных машин в вашей среде. Вот пример выполнения этого в Perl, который может быть перенесен на язык по вашему выбору.

Это зависит от того, что вы ищете:

  • Если виртуальная машина не скрывается от вас специально, вы можете использовать какой-нибудь известный крючок. Например, поиск драйверов VmWare или наличие определенных строк в памяти или некоторых других контрольных знаков.

  • Если виртуальная машина действительно хочет, чтобы вы делали для нее специальные вещи, у нее будет какой-то очевидный крюк, например, изменение идентификатора процессора или добавление некоторых специальных регистров, к которым вы можете получить доступ, чтобы обнаружить его. Или особый устройство в известном месте в памяти (предполагая, что вы можете получить необработанный доступ к физическому пространству памяти вашего мира). Обратите внимание, что современные машины, такие как IBM Power6 и Sun UltraSparc T1/T2, всегда работают с гипервизором и никогда не работают непосредственно на необработанном оборудовании. Интерфейс к «аппаратному обеспечению», которое использует ОС, на самом деле является интерфейсом программного уровня гипервизора, без возможности обойти его. В этом случае обнаружение тривиально, так как это постоянное «да». Это наиболее вероятно будущее направление для всех компьютерных систем, которые могут позволить себе накладные расходы, посмотрите на поддержку в последних проектах, таких как Freescale qoriq p4080 chip, например (www.freescale.com/qoriq).

  • Если виртуальная машина намеренно пытается скрыться, а вы преследуете ее присутствие, это игра в кошки-мышки, где нарушение синхронизации и различный профиль производительности виртуальной машины почти всегда будут выдавать его. Очевидно, это зависит от того, как реализована виртуальная машина и сколько аппаратная поддержка существует в архитектуре (я думаю, что мэйнфрейм zSeries намного лучше скрывает присутствие виртуальной машины или стека виртуальных машин под вашей конкретной ОС, чем обычная x86-машина, например). См. http://jakob.engbloms.se/archives/97 для некоторого обсуждения этой темы. Можно попытаться спрятаться как виртуальная машина, но обнаружение, скорее всего, всегда выиграет, если оно будет достаточно сильно стараться.

В большинстве случаев, вы не должны пытаться. Вас не должно волновать, если кто-то запускает ваш код в виртуальной машине, за исключением нескольких конкретных случаев.

Если вам нужно, в Linux наиболее распространенным способом является просмотр /sys/devices/virtual/dmi/id/product_name, в котором будет указано имя ноутбука/материнской платы в большинстве реальных систем и гипервизора в большинстве виртуальных систем. dmidecode | grep Product — Еще один распространенный метод, но я думаю, что для этого Требуется root-доступ.

Один хороший пример-это, по-видимому, выполнение запроса WMI для производителя материнской платы, и если он возвращает «Microsoft», вы находитесь в виртуальной машине. Думал, я считаю, что это только для VMware. Есть, вероятно, различные способы сказать для каждого программного обеспечения узла виртуальной машины.

Эта статья здесь http://blogs.technet.com/jhoward/archive/2005/07/26/407958.aspx у есть несколько хороших предложений и ссылок на пару способов определить, находитесь ли вы в виртуальной машине (VMWare и VirtualPC, по крайней мере).

Вы можете определить, находитесь ли вы в виртуальной машине, посмотрев на MAC-адрес вашего сетевого подключения. Xen, например, обычно рекомендует использовать определенный диапазон адресов 00: 16: 3e: xx:xx: xx.

Это не гарантируется, поскольку администратор системы должен указать, какой MAC-адрес ему нравится.

Здесь есть (java + windows) решение для определения того, является ли базовая машина физической или виртуальной.

Примеры Виртуальных Машин:

Изготовитель

  • Xen
  • Корпорация Майкрософт
  • innotek GmbH
  • Красная Шляпа
  • [16]}VMware, Inc.

Модель

  • HVM domU
  • Виртуальная Машина
  • VirtualBox
  • KVM
  • VMware Virtual Платформа

    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.util.ArrayList;
    import java.util.List;
    
    public abstract class OSUtil {
    
    public static final List<String> readCmdOutput(String command) {
        List<String> result = new ArrayList<>();
    
        try {
            Process p=Runtime.getRuntime().exec("cmd /c " + command);
            p.waitFor();
            BufferedReader reader=new BufferedReader(
                    new InputStreamReader(p.getInputStream())
                    );
            String line;
            while((line = reader.readLine()) != null) {
                if(line != null && !line.trim().isEmpty()) {
                    result.add(line);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    
        return result;
    }
    
    public static final String readCmdOutput(String command, int lineNumber) {
        List<String> result = readCmdOutput(command);
        if(result.size() < lineNumber) {
            return null;
        }
    
        return result.get(lineNumber - 1);
    }
    
    public static final String getBiosSerial() {
        return readCmdOutput("WMIC BIOS GET SERIALNUMBER", 2);
    }
    
    public static final String getHardwareModel() {
        return readCmdOutput("WMIC COMPUTERSYSTEM GET MODEL", 2);
    }
    
    public static final String getHardwareManufacturer() {
        return readCmdOutput("WMIC COMPUTERSYSTEM GET MANUFACTURER", 2);
    }
    
    public static void main(String[] args) {
        System.out.println("BIOS Serial: " + getBiosSerial());
        System.out.println("Hardware Model: " + getHardwareModel());
        System.out.println("Hardware Manufacturer: " + getHardwareManufacturer());
    }
    }
    

Вы можете использовать выходные данные, чтобы решить, является ли это виртуальная машина или физическая машина:

Физический выход машины:

BIOS Serial: 2HC3J12
Аппаратная Модель: Inspiron 7570
Производитель Оборудования: Dell Inc.

Вывод виртуальной машины:

BIOS Serial: 0
Аппаратная Модель: Innotec GmBH
Производитель Оборудования: Virtual Box

Если виртуальная машина хорошо выполняет свою работу, она должна быть невидима для клиента, что она виртуализируется. Однако можно посмотреть и на другие подсказки.

Я бы предположил, что поиск известных драйверов или программного обеспечения, специфичных для среды виртуальной машины, был бы наилучшим возможным способом.

Например, на клиенте VMWare под управлением Windows, vmxnet.sys будет сетевым драйвером, отображаемым как VMware accelerated AMD PCNet Adapter.

I’m remoting desktop to windows servers in our Lab/datacenter. I have a requirement to figure out all our servers are virtual machines or physical servers programatically, certainly we have the environment sheet tell us which is which. But I need to write code to distinguish it. What technique I need to use? I didn’t find a .Net Assembly to do that. Looking for expert to share your knowledge or guidance, any research direction or link, anything will be appreciated!

D Stanley's user avatar

D Stanley

147k11 gold badges174 silver badges238 bronze badges

asked Mar 18, 2013 at 19:49

ljh's user avatar

You can try to use the following PowerShell script, it utilizes WMI to find out if machine is virtual machine or physical machine.


gwmi -q "select * from win32_computersystem"

Certainly, you can use C# code to query WMI too. The output of script above will be like following:

Domain:   ...
Manufacturer: Microsoft Corporation
Model: Virtual Machine
Name : .....
....

answered Mar 18, 2013 at 20:18

0

To check this from the command prompt you can run this: systeminfo | find "System"

Example output for virtual server:

System Manufacturer:       Microsoft Corporation    
System Model:              Virtual Machine    
System Type:               x64-based PC

Example output for physical server:

System Manufacturer:       HP
System Model:              ProLiant BL460c G6
System Type:               x64-based PC

answered Aug 8, 2013 at 10:49

Mattias Lindberg's user avatar

Mattias LindbergMattias Lindberg

2,0443 gold badges24 silver badges34 bronze badges

As far as I know there is no easy way to do this.

There are a few workarounds but there is, at least as far as I know, not a one-size-fits-all solution.

Ben Armstrong wrote a post about Detecting Microsoft virtual machines and there’s a low-level trick which can determine whether you are running within a Virtual PC or VMWare but that still leaves out VirtualBox and others.

A trick you might want to try is to detect whether VMWare Tools or VirtualBox Tools are installed. In most cases they are installed on the guest OS to provide needed features but it will be hard to maintain the different installation GUIDS on your end so it’s not an ideal solution.

— Also , if the VM is running in a Linux KVM environment, the output is like this one
enter image description here

Community's user avatar

answered Mar 18, 2013 at 20:02

Jensen's user avatar

JensenJensen

3,4502 gold badges25 silver badges42 bronze badges

0

There is no easy way to tell if you’re running in a bare metal or in a virtual computer, the best thing you can do is to get some hardware info and made an educated guess, for example, if the machine have a network adapter which contains Microsoft, VMware, Oracle, Hyper-V, Virtual or VirtualBox, most likely it’s a virtual machine given that neither Microsoft, Oracle, or VMware fabricate network cards.

As you use C#, the class for retrieving this and other hardware info is ManagementClass, also there is this nice project that let you retrieve tons of info from your computer using ManagementClass.

answered Mar 18, 2013 at 20:09

Rafael's user avatar

RafaelRafael

2,8171 gold badge16 silver badges17 bronze badges

0

Run the systeminfo command @ command prompt see the system menufacturer n system model details. There you can find the virtule and physical machine information.

answered Apr 2, 2013 at 18:08

Ajay Yadav's user avatar

0

Try this:

FOR /F "tokens=*" %a IN ('wmic bios get bioscharacteristics^|find /c "33"') DO set USBlegacy=%a

This returns «1» for the limited range of desktops and laptops in my environment and «0» for VMWare workstation 9, ESX 5.5, and Citrix 6.5 and 7.6. BIOSCharacteristic «50» (one «reserved for system vendor») I’ve only found in the four virtual environments so that would work in reverse.

Edit: or there’s this:

FOR /F "tokens=*" %a IN ('wmic path win32_pnpentity get ^|find /c "ACPI Fan"') DO set ACPIfan=%a

Returns «5» on an HP Desktop, «0» on VMware workstation 9 and ESX 5.5, not tested on the others.

answered Jul 14, 2015 at 13:37

AndyKn's user avatar

3

you can use this command in cmd or powershell

SYSTEMINFO

You will find a line with the following text (or similar):

System Manufacturer: VMware, Inc.
System Model: VMware Virtual Platform

answered Dec 23, 2017 at 6:44

Hamid KhanZadeh's user avatar

The only *programmatic* way I know of doing this reliably is:

  1. Write an app that crawls your network (or IP range) to get a list of machines.
  2. Display those machines to a person and ask them to check a box if it’s a VM…
  3. Print the report.

answered Mar 18, 2013 at 20:17

NotMe's user avatar

NotMeNotMe

86.9k27 gold badges172 silver badges244 bronze badges

I’m remoting desktop to windows servers in our Lab/datacenter. I have a requirement to figure out all our servers are virtual machines or physical servers programatically, certainly we have the environment sheet tell us which is which. But I need to write code to distinguish it. What technique I need to use? I didn’t find a .Net Assembly to do that. Looking for expert to share your knowledge or guidance, any research direction or link, anything will be appreciated!

D Stanley's user avatar

D Stanley

147k11 gold badges174 silver badges238 bronze badges

asked Mar 18, 2013 at 19:49

ljh's user avatar

You can try to use the following PowerShell script, it utilizes WMI to find out if machine is virtual machine or physical machine.


gwmi -q "select * from win32_computersystem"

Certainly, you can use C# code to query WMI too. The output of script above will be like following:

Domain:   ...
Manufacturer: Microsoft Corporation
Model: Virtual Machine
Name : .....
....

answered Mar 18, 2013 at 20:18

0

To check this from the command prompt you can run this: systeminfo | find "System"

Example output for virtual server:

System Manufacturer:       Microsoft Corporation    
System Model:              Virtual Machine    
System Type:               x64-based PC

Example output for physical server:

System Manufacturer:       HP
System Model:              ProLiant BL460c G6
System Type:               x64-based PC

answered Aug 8, 2013 at 10:49

Mattias Lindberg's user avatar

Mattias LindbergMattias Lindberg

2,0443 gold badges24 silver badges34 bronze badges

As far as I know there is no easy way to do this.

There are a few workarounds but there is, at least as far as I know, not a one-size-fits-all solution.

Ben Armstrong wrote a post about Detecting Microsoft virtual machines and there’s a low-level trick which can determine whether you are running within a Virtual PC or VMWare but that still leaves out VirtualBox and others.

A trick you might want to try is to detect whether VMWare Tools or VirtualBox Tools are installed. In most cases they are installed on the guest OS to provide needed features but it will be hard to maintain the different installation GUIDS on your end so it’s not an ideal solution.

— Also , if the VM is running in a Linux KVM environment, the output is like this one
enter image description here

Community's user avatar

answered Mar 18, 2013 at 20:02

Jensen's user avatar

JensenJensen

3,4502 gold badges25 silver badges42 bronze badges

0

There is no easy way to tell if you’re running in a bare metal or in a virtual computer, the best thing you can do is to get some hardware info and made an educated guess, for example, if the machine have a network adapter which contains Microsoft, VMware, Oracle, Hyper-V, Virtual or VirtualBox, most likely it’s a virtual machine given that neither Microsoft, Oracle, or VMware fabricate network cards.

As you use C#, the class for retrieving this and other hardware info is ManagementClass, also there is this nice project that let you retrieve tons of info from your computer using ManagementClass.

answered Mar 18, 2013 at 20:09

Rafael's user avatar

RafaelRafael

2,8171 gold badge16 silver badges17 bronze badges

0

Run the systeminfo command @ command prompt see the system menufacturer n system model details. There you can find the virtule and physical machine information.

answered Apr 2, 2013 at 18:08

Ajay Yadav's user avatar

0

Try this:

FOR /F "tokens=*" %a IN ('wmic bios get bioscharacteristics^|find /c "33"') DO set USBlegacy=%a

This returns «1» for the limited range of desktops and laptops in my environment and «0» for VMWare workstation 9, ESX 5.5, and Citrix 6.5 and 7.6. BIOSCharacteristic «50» (one «reserved for system vendor») I’ve only found in the four virtual environments so that would work in reverse.

Edit: or there’s this:

FOR /F "tokens=*" %a IN ('wmic path win32_pnpentity get ^|find /c "ACPI Fan"') DO set ACPIfan=%a

Returns «5» on an HP Desktop, «0» on VMware workstation 9 and ESX 5.5, not tested on the others.

answered Jul 14, 2015 at 13:37

AndyKn's user avatar

3

you can use this command in cmd or powershell

SYSTEMINFO

You will find a line with the following text (or similar):

System Manufacturer: VMware, Inc.
System Model: VMware Virtual Platform

answered Dec 23, 2017 at 6:44

Hamid KhanZadeh's user avatar

The only *programmatic* way I know of doing this reliably is:

  1. Write an app that crawls your network (or IP range) to get a list of machines.
  2. Display those machines to a person and ask them to check a box if it’s a VM…
  3. Print the report.

answered Mar 18, 2013 at 20:17

NotMe's user avatar

NotMeNotMe

86.9k27 gold badges172 silver badges244 bronze badges

Unfortunately there is not an unique answer. Each virtual machine has a sort of bridge you can use but you have to write specific checks for each VM you want to detect (examples are VC++ specific but you can easily adapt them to your compiler). Note that in theory you should not be able to determine if you’re running under a VM or not.

VMWare

VMWare uses IN instruction to handle guest to host communication. Normally this instruction is not available in user-mode and it throws an exception but VM handles it. If we catch the exception then we know we are not running under VMWare (or we are privileges to execute IN instruction). Second test to determine if we have privileges or we are running under WMWare is almost useless but that’s standard detect code and I write it here for completeness (we just check for an expected string VMXh in EBX register, note we had to initialize some registers with required values.)

bool IsRunningInsideVmWare()
{
    bool flag = true;

    __try
    {
        __asm
        {
            push    edx
            push    ecx
            push    ebx

            mov     eax, 'VMXh'
            mov     ebx, 0
            mov     ecx, 10
            mov     edx, 'VX'

            in      eax, dx
            cmp     ebx, 'VMXh'
            setz    [flag]

            pop     ebx
            pop     ecx
            pop     edx
        }
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        flag = false;
    }

    return flag;
}

Virtual PC

Guests can use a non-existing instruction 0f3f070b to communicate with host, what you can do is then emit such instruction, VM will correctly interpret it but physical CPUs will throw an exception (which you can catch and jump over offending instruction). In this example we set EBX to a known value in the exception handler and then we can detect this scenario.

DWORD __forceinline VpcExceptionFilter(LPEXCEPTION_POINTERS ep)
{
    ep->ContextRecord->ctx->Ebx = -1;
    ep->ContextRecord->ctx->Eip += 4;

    return EXCEPTION_CONTINUE_EXECUTION;
}

bool IsRunningInsideVpc()
{
    bool flag = false;

    __try
    {
        _asm
        {
            push    ebx

            mov     eax, 1
            mov     ebx, 0 

            __emit  0Fh
            __emit  3Fh
            __emit  07h
            __emit  0Bh

            test    ebx, ebx
            setz    [flag]

            pop     ebx
        }
    }
    __except(VpcExceptionFilter(GetExceptionInformation()))
    {
    }

    return flag;
}

VirtualBox

To detect VirtualBox is extremely simple, you just need to check if a pseudo-device \.VBoxMiniRdrDN exists:

bool IsRunningInsideVirtualBox()
{
    HANDLE handle = CreateFile("\\.\VBoxMiniRdrDN", GENERIC_READ, FILE_SHARE_READ, 
        NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    if (handle != INVALID_HANDLE_VALUE)
    {
        CloseHandle(handle);
        return true;
    }

    return false;
}

Something little bit more generic can be done (assumption: you’re running on Windows) using WMI and the following queries:

  • In Win32_BaseBoard matchName against (?i)(Hyper-V|Virtual Machine|Microsoft|VMware|VirtualBox|Parallels Virtual).
  • In Win32_ComputerSystem match Model and Manufacturer against (?i)(Hyper-V|Virtual Machine|VMware|VirtualBox).
  • In Win32_VideoController match Name against (?i)Hyper-V.

CPUID instructions can also help you (when those values are supported).

With EAX set to 0 (Get vendor ID) you get in EBX, EDX and ECX an ASCII string with CPU vendor name (see Wikipedia for list). Of course a VM can return a false name or it may be an unknown VM.

With EAX set to 1 (Processor Info and Feature Bits) bit 31 of ECX (hypervisor) is set to 1 if you’re running under a VM. Again a VM may return a false result (and some VMs don’t honor this bit).


When I had to play with this issue I tried also to check for hardware tricks/features which are not supported in a VM (for example to USB Legacy support) but I found it’s not reliable enough to be used in production.


In comment you said you’re running on Android. That’s a completely different story but common techniques are similar to what I said about WMI (or a combination of the above). A common way is to check the device name string for well-known emulators, from Android 7 there is a specific flag ro.kernel.qemu.

Can you fake those values? Yes, see for example Is there a way to set ro.kernel.qemu to 0 in a emulator?. Note that any decent application which cares to stop you to use it under emulation will also use multiple detection techniques (see also Android: Get Hardware Information Programmatically).

Unfortunately there is not an unique answer. Each virtual machine has a sort of bridge you can use but you have to write specific checks for each VM you want to detect (examples are VC++ specific but you can easily adapt them to your compiler). Note that in theory you should not be able to determine if you’re running under a VM or not.

VMWare

VMWare uses IN instruction to handle guest to host communication. Normally this instruction is not available in user-mode and it throws an exception but VM handles it. If we catch the exception then we know we are not running under VMWare (or we are privileges to execute IN instruction). Second test to determine if we have privileges or we are running under WMWare is almost useless but that’s standard detect code and I write it here for completeness (we just check for an expected string VMXh in EBX register, note we had to initialize some registers with required values.)

bool IsRunningInsideVmWare()
{
    bool flag = true;

    __try
    {
        __asm
        {
            push    edx
            push    ecx
            push    ebx

            mov     eax, 'VMXh'
            mov     ebx, 0
            mov     ecx, 10
            mov     edx, 'VX'

            in      eax, dx
            cmp     ebx, 'VMXh'
            setz    [flag]

            pop     ebx
            pop     ecx
            pop     edx
        }
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        flag = false;
    }

    return flag;
}

Virtual PC

Guests can use a non-existing instruction 0f3f070b to communicate with host, what you can do is then emit such instruction, VM will correctly interpret it but physical CPUs will throw an exception (which you can catch and jump over offending instruction). In this example we set EBX to a known value in the exception handler and then we can detect this scenario.

DWORD __forceinline VpcExceptionFilter(LPEXCEPTION_POINTERS ep)
{
    ep->ContextRecord->ctx->Ebx = -1;
    ep->ContextRecord->ctx->Eip += 4;

    return EXCEPTION_CONTINUE_EXECUTION;
}

bool IsRunningInsideVpc()
{
    bool flag = false;

    __try
    {
        _asm
        {
            push    ebx

            mov     eax, 1
            mov     ebx, 0 

            __emit  0Fh
            __emit  3Fh
            __emit  07h
            __emit  0Bh

            test    ebx, ebx
            setz    [flag]

            pop     ebx
        }
    }
    __except(VpcExceptionFilter(GetExceptionInformation()))
    {
    }

    return flag;
}

VirtualBox

To detect VirtualBox is extremely simple, you just need to check if a pseudo-device \.VBoxMiniRdrDN exists:

bool IsRunningInsideVirtualBox()
{
    HANDLE handle = CreateFile("\\.\VBoxMiniRdrDN", GENERIC_READ, FILE_SHARE_READ, 
        NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    if (handle != INVALID_HANDLE_VALUE)
    {
        CloseHandle(handle);
        return true;
    }

    return false;
}

Something little bit more generic can be done (assumption: you’re running on Windows) using WMI and the following queries:

  • In Win32_BaseBoard matchName against (?i)(Hyper-V|Virtual Machine|Microsoft|VMware|VirtualBox|Parallels Virtual).
  • In Win32_ComputerSystem match Model and Manufacturer against (?i)(Hyper-V|Virtual Machine|VMware|VirtualBox).
  • In Win32_VideoController match Name against (?i)Hyper-V.

CPUID instructions can also help you (when those values are supported).

With EAX set to 0 (Get vendor ID) you get in EBX, EDX and ECX an ASCII string with CPU vendor name (see Wikipedia for list). Of course a VM can return a false name or it may be an unknown VM.

With EAX set to 1 (Processor Info and Feature Bits) bit 31 of ECX (hypervisor) is set to 1 if you’re running under a VM. Again a VM may return a false result (and some VMs don’t honor this bit).


When I had to play with this issue I tried also to check for hardware tricks/features which are not supported in a VM (for example to USB Legacy support) but I found it’s not reliable enough to be used in production.


In comment you said you’re running on Android. That’s a completely different story but common techniques are similar to what I said about WMI (or a combination of the above). A common way is to check the device name string for well-known emulators, from Android 7 there is a specific flag ro.kernel.qemu.

Can you fake those values? Yes, see for example Is there a way to set ro.kernel.qemu to 0 in a emulator?. Note that any decent application which cares to stop you to use it under emulation will also use multiple detection techniques (see also Android: Get Hardware Information Programmatically).

Понравилась статья? Поделить с друзьями:
  • Как узнать версию биос windows 10 на компьютере
  • Как узнать видеопамять на ноутбуке windows 10
  • Как узнать версию microsoft net framework в windows 10
  • Как узнать версию аудио драйвера windows 10
  • Как узнать видеопамять компьютера windows 7