Обнаружение VMM в Linux - PullRequest
       1

Обнаружение VMM в Linux

1 голос
/ 08 сентября 2010

Я пытаюсь определить, работаю ли я в виртуальной среде (vmware, virtualbox и т. Д.)
В Windows я использую несколько ASM, но не могу использовать их в Linux, в основном потому, что код можетбыть скомпилированным и работать в 32- или 64-битной Linux.

Следующий код работает как в Windows 32, так и в 64-х и был протестирован на VMWare, virtualbox и других виртуальных машинах:

#include <stdio.h> 

int idtCheck () 
{ 
    unsigned char m[2]; 
    __asm sidt m; 
    printf("IDTR: %2.2x %2.2x\n", m[0], m[1]); 
    return (m[1]>0xd0) ? 1 : 0; 
} 

int gdtCheck() 
{ 
    unsigned char m[2]; 
    __asm sgdt m; 
    printf("GDTR: %2.2x %2.2x\n", m[0], m[1]);
    return (m[1]>0xd0) ? 1 : 0; 
} 

int ldtCheck() 
{ 
    unsigned char m[2]; 
    __asm sldt m; 
    printf("LDTR: %2.2x %2.2x\n", m[0], m[1]); 
    return (m[0] != 0x00 && m[1] != 0x00) ? 1 : 0; 
} 

int main(int argc, char * argv[]) 
{ 
    idtCheck(); 
    gdtCheck(); 

    if (ldtCheck()) 
        printf("Virtual Machine detected.\n"); 
    else 
        printf("Native machine detected.\n"); 

    return 0; 
}

сейчасGCC жалуется на __asm ​​для всех функций.Я пробовал с asm (), asm и другими формами, которые я использовал в прошлом, но ни одна из них не работает.Есть идеи?

1 Ответ

4 голосов
/ 08 сентября 2010

Ну, я не разбирал машинный код там, но вот версия с использованием встроенного ассемблера GCC:

int redpill()
{
        unsigned char idt_addr[(sizeof(long)==8)?10:6];
        __asm__("SIDT (%[ptr])"
                        : "=m" (idt_addr)
                        : [ptr] "r" (&idt_addr));
        // examine high order byte
        return idt_addr[(sizeof(long)==8)?9:5] > 0xd0;
}

Это должно 'работать' даже для 64-битных, но я там не проверял.

ОДНАКО!Это не гарантирует, что вы получите желаемый результат, на всех .Во-первых, он не будет работать с аппаратной виртуализацией, так как вы не видите истинную IDT.Во-вторых, он опирается на детали реализации VMWare и Virtual PC, которые, вероятно, могут быть изменены довольно легко.Это может даже вызвать ложную тревогу, если ваша ОС решит поставить свою IDT на высокий адрес.Поэтому я не рекомендую этот подход вообще.

Для виртуальных машин, использующих аппаратную поддержку VMX, вероятно, лучше всего было бы сделать что-то, что должно быть быстрым в оборудовании, но требует ловушки в виртуальной машине,и проверьте время.Что-то вроде CPUID было бы хорошей ставкой;сравните его на виртуальной машине и на реальном оборудовании (по сравнению с фиктивным циклом, который выполняет ADD или что-то, что имеет дело с различными тактовыми частотами), и посмотрите, какой профиль тестируемой машины более точно соответствует.Поскольку каждый CPUID должен будет выходить из виртуальной машины, чтобы спросить ядро ​​хоста о том, какие возможности он хочет предоставить, потребуется гораздо больше времени, чем на реальном оборудовании.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...