Народ, кто сталкивался с такой проблемой - нужно опознать что винда запущена не под HyperV. В принципе опознать виртуалку по замеру времени исполнения cpuid - это не проблема, пока дело не касается HyperV. Фишка вот в чем: если мы запущены на реальном компе на котором стоит HyperV то 1) Всегда CPUID.1.ECX.31 =1 (т.е. мы в hypervisor) 2) Всегда замены времени cpuid показывают превышение. 3) Всегда CPUID.0x40000000 указывает на имя гипервизова (в частности HyperV) Так как же тогда опознать - мы внутри HyperV или просто он установлен на этом компе ?
* Можно просто прочекать железо. Под VM сомнительно что кто-то назовет видяху Радеоном. Вывод CPUID под гипервизором может быть изменен же вроде, т.ч. х/з. * Если дело касается ОСи - то скорее всего имеется ввиду промышленная VM типа Варьки. А у нее где-то был вполне официальный кодес для детекта. Есть предположение что то же самое должны предоставлять и Ораклы ибо Венде это знание не будет лишним. В общем-то если VM пытается скрыться - универсального метода вроде-бы нет. Если не скрывается - она везде сует свои устройства и надписи где надо и где не очень. Можно просто прочекать пару мест для верности. Это некрасивый хардкод конечно, придется тестить все поддерживаемые VM, но... как иначе - х/з. У аверов постилась в разное время обширная матчасть по детекту. Им тоже всегда приятно знать на реальном они PC или под VM. С CPUID как-то сильно просто получается... Авторы там могут написать все что хочешь и детект просто обломится. Замеры времени cpuid тоже х/з как сравнивать. По сравнению с чем cpuid выполняется дольше ? Есть у Симантеков занятный ман по сабжу, много буков чтобы читать - но может чего там и найдешь: http://www.symantec.com/avcenter/reference/Virtual_Machine_Threats.pdf
Да, кстати если тестить на железо - то название железа и его содержимое тоже можно попробовать прочекать на соответствие. Т.е. одно дело изменить одну текстовую строку на Radeon, и совсем другое дело еще и драйвер корректно запилить. Это сильно круто и в среднем никому такая дотошность не нужна. Напейсателям малвари и подавно. Я думаю никто особо с этим не запаривается. Да и коль так глубоко полезли - значит задетектят без шансов UPD: кстати нашел. Эта штука с cpuid описывается под VMWare: https://kb.vmware.com/s/article/1009458 Если работает под VirtualPC - это конечно хорошо, но это же не означает что будет работать везде. Т.ч. обратно - видимо так не выйдет. Обратно можно тогда сказать только что "я не под Варей и не под VirtualPC, все остальное - возможно"
Простой пример: Есть компьютер в офисе - чистенький, со встроенной видюхой, только 1С к примеру Есть сервер с HyperV на котором стоит виртуалка и там та же хрень и удаленный рабочий стол на такую винду. И вот тут уже нельзя чтобы прога запускалась т.е. лицензией запрещено использовать на виртуалках. Самый действенный способ опознать такое - замерить время исполнения cpuid. Если вы не знали, то cpuid при исполнении в виртуальной среде всегда приводит к VMEXIT и уже гипервизор занимается её обработкой. При этом счетчик тактов CPU не прерывается. Именно по этой причине замеры количества тактов за которые исполняется cpuid может косвенно свидетельствовать о том, что мы в виртуальной среде. Причем разница может доходить до 10 раз в отличии от реального компа. И как не старайся, какие настройки не делай в виртуалке - всё равно никак нельзя противодействовать данному способу. Было одно изыскание по этому поводу, даже был сделан форк XENa в котором при cpuid на лету проверялось что идет дальше и если там команд rdtsc то эмулировали её работу с подправкой времени. Но там тоже можно было обойти такой механизм. По этому данный способ дает 100% результат, но могут быть ложные срабатывания. Вот как раз HyperV дает ложные срабатывания.
Вот к примеру: Code: DWORD64 tStart; DWORD64 tStop; DWORD64 Ticks; int Buf[4]; tStart = __rdtsc(); __cpuid(Buf, 0); tStop = __rdtsc(); Ticks = tStop - tStart; На реальных компах среднее значение Ticks будет меньше 256, а вот в виртуализации более 1000. Может доходить до 2000 даже.
Угу. Нашел ( * ): "Поговорим о том, как изменяется CPUid в Hyper-V. Дело в том, что когда вы устанавливаете роль Hyper-V на Windows Server 2008/R2, между процессором и операционной системой появляется прослойка – гипервизор. Гипервизор маскирует некие свойства процессора для самой хост системы. Также он маскирует свойства процессора для виртуальных машин. Посмотрим, как меняются первые регистры CPUid при установке роли Hyper-V"
Протестить мне не на чем... Перелез на Линух - Линух знаю на уровне пользователя. Даже норм откомпилить не особо выходит Hyper-V внутри ВМ стоять же не может вроде (имеется ввиду внутри VM серверная венда с включенной ролью - сомнительно что будет работать)? Может просто достаточно будет его задетектить... Х/з. Там надо смотреть а не представлять в уме
Короче нашел тему - HyperV не пробрасывает датчики температуры в гостевую систему. По этому даже в cpuid убирает флаг об их наличии. А вот в настоящее время нет x86 процессоров с аппаратной виртуализацией и без датчиков температуры.
Вот тут человек предлагает детектить через WMI: https://blogs.technet.microsoft.com/tonyso/2009/08/20/hyper-v-how-to-detect-if-you-are-inside-a-vm/ Думаю это более надежный метод, чем трики
WMI по факту это чисто программная вещь. И видит он то что было в настройках виртуалки. К примеру XEN можно настроить до такого уровня что ни одна софтина не поймет что она в виртуализации. Кроме замера времени cpuid
Не отрицаю, а еще можно пропатчить всевозможные константы, по которым палятся виртуалки. Но как я понял, мы говорим о рядовой Hyper-V машине.
Вообще вся суть в том что без спец лицензии не допускать работу программы в виртуальной среде. Если с обычным виртуалками можно бороться через замер времени, то вот HyperV дает ложные срабатывания. По этому и нужен был метод чтобы отделить реальный комп с hyperv от виртуалки.
VMX и задумано в целом для виртуализации, какбэ. и задержками ты их не сравнишь потому что их почти нет. а узнать ты сможешь если попробуешь грузануть свой монитор - если не вышло - либо проц не держит либо оно уже запущено