0

I am beginners in the world of virtual machines and have a small question. if a software is running on a VM (eg. VMware Player) how does it know that it is installed on a VM? Does the software get the information from the operating system or is there a direct communication between the software and the hardware (VMware Player)? thank you in advance

user7396065
  • 39
  • 1
  • 7

2 Answers2

3

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).

Adriano Repetti
  • 65,416
  • 20
  • 137
  • 208
  • many thanks for the detailed response. Background of my question is that I have an Android virtual machine (VMware Player). Whatsapp recognizes apparently somehow that it is a virtual environment and therefore comes in Play Store the message "Your device is not compatible with this version". I want to manipulate the VM so that Whatsapp thinks this is a real machine. Do I need to manipulate Android or VMware Player? should i change CPUID(unset bit 31: hypervisor) as i read in internet? I need urgent help. Thank you again – user7396065 Sep 08 '17 at 12:03
  • 1
    That makes a completely different question and answer is...experiment. WhatsUp is closed source and we do not know _how_ it's detecting the VM (in my answer I assumed you were running under Windows/Linux). Given that you CANNOT legally hack anything on WhatsUp then you're out of luck until you understand what's the used technique (I list some of them in my edited answer). Feel free to download Android, recompile and experiment with that... – Adriano Repetti Sep 08 '17 at 12:21
  • thank you again for the quick response. Do you know how to manipulate the hypervisor present bit (CPUID)? That would be one of the ways how Whatsapp can find out if a virtual environment is running. I have googled but could not understand how that goes if at all. Did you deal with something like that?? – user7396065 Sep 08 '17 at 13:15
  • I had to deal exactly with the opposite task. Don't be so optimistic, if they put in place this check then I'm pretty sure they did it well. AFAIK `cpuid` is a native library, you may hexedit that file or recompile from original source code. Note that there might be something to change this setting in your emulator (check its documentation). – Adriano Repetti Sep 08 '17 at 13:21
  • thank you for the info Adriano – user7396065 Sep 11 '17 at 09:12
  • I found this page yesterday: https://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 I believe whatsapp checks this hypervisor present bit. I will try to manipulate it so that Whatsapp no longer recognizes the hypervisor , but have no idea how that can be done – user7396065 Sep 11 '17 at 09:19
0

I don't think that it does matter for the software where it is running as long as it works properly.

If you really want to check if you are running (or if your self-written code) is running on VM. In Windows case it is possible to check the hardware in device manager (Windows case), because VM apps create some virtual hardware. For example VMWare will create some hardware named VMware... devices.

Mohammed Noureldin
  • 14,913
  • 17
  • 70
  • 99