Detect virtual OS from application?

I need to determine if my application is running in a virtual OS instance or not.

I found an article with useful information on this topic. The same article appears in several places, I'm not sure about the source. VMware implements a certain invalid x86 instruction to return information about itself, while VirtualPC uses a magic number and an I / O port with an IN instruction.

This is workable, but in both cases it looks undocumented. I believe that a future release of VMWare or VirtualPC may change the mechanism. Is there a better way? Is there a supported mechanism for any product?

Similarly, is there a way to detect Xen or VirtualBox ?

I'm not interested in cases where the platform intentionally tries to hide itself. For example, decoys use virtualization, but sometimes hide the mechanisms that the malware will use to detect it. I don’t care that my application will think that it is not virtualized in these baits, I’m just looking for a “better effort” solution.

The application is mostly Java, although I expect to use native code plus JNI for this particular function. Support for Windows XP / Vista is most important, although the mechanisms described in this article are common x86 functions and are not dependent on any particular OS.

+60
virtualbox vmware xen virtual-pc
Sep 30 '08 at 17:42
source share
14 answers

Have you heard of the blue pill, the red pill? . This is the method used to check if you are working in a virtual machine or not. The origin of the term is related to the matrix film , where Neo is offered a blue or red pill (stay inside the matrix = blue or enter the "real" world = red).

Below is the code that will determine what you use inside the "matrix" or not:
(code borrowed from this site , which also contains some nice information about this topic):

int swallow_redpill () { unsigned char m[2+4], rpill[] = "\x0f\x01\x0d\x00\x00\x00\x00\xc3"; *((unsigned*)&rpill[3]) = (unsigned)m; ((void(*)())&rpill)(); return (m[5]>0xd0) ? 1 : 0; } 

The function will return 1 when you start inside the virtual machine, and 0 otherwise.

+65
Sep 30 '08 at 17:59
source share

On Linux, I used the command: dmidecode (I have both on CentOS and Ubuntu)

from person:

dmidecode is a tool to reset a DMI computer (some say SMBIOS) table of contents in a human-readable format.

So, I looked at the output and discovered it was probably Microsoft Hyper-V

 Handle 0x0001, DMI type 1, 25 bytes System Information Manufacturer: Microsoft Corporation Product Name: Virtual Machine Version: 5.0 Serial Number: some-strings UUID: some-strings Wake-up Type: Power Switch Handle 0x0002, DMI type 2, 8 bytes Base Board Information Manufacturer: Microsoft Corporation Product Name: Virtual Machine Version: 5.0 Serial Number: some-strings 

Another way is to find out which manufacturer the MAC address of eth0 belongs to: http://www.coffer.com/mac_find/

If he returns Microsoft, vmware, etc., then this is probably a virtual server.

+23
Nov 28 '10 at
source share

I think that moving forward relying on tricks such as broken SIDT virtualization will not really help, as the equipment plugs in all the holes that left the strange and dirty x86 architecture. It would be best to lobby for Vm providers for a standard way of saying that you are on a virtual machine - at least for the case where the user has explicitly allowed this. But if we assume that we explicitly allow virtual machine detection, we can also place visible tokens there, right? I would suggest just updating the disk on your virtual machines with a file telling you that you are on the virtual machine - a small text file in the root of the file system, for example. Or check the MAC address of ETH0 and set it for this known string.

+11
02 Oct '08 at 6:58
source share

VMware has Mechanisms to determine if software is running on a VMware virtual machine. A knowledge base article in which there is source code.

Microsoft also has a page on "Determining if Hypervisor is Installed . " MS explains this hypervisor requirement in the IsVM TEST section of "Verifying Server Validation"

VMware and MS documents mention the use of the CPUID command to check for a bit present in the hypervisor (bit 31 of the ECX register)

Bugtracker RHEL has one for "must set the ISVM bit (ECX: 31) for the CPUID sheet 0x00000001" to set bit 31 of the ECX register under the Xen core.

Thus, without going into the vendor specification, it looks like you can use the CPUID check to know if you are practically working or not.

+11
Aug 16 '10 at 18:32
source share

No. This cannot be detected with complete accuracy. Some virtualization systems, such as QEMU , emulate the entire machine to hardware registers. Let it turn: what are you trying to do? Maybe we can help with this.

+10
Sep 30 '08 at 17:52
source share

In a virtual box, assuming you have control over the guest VM and you have dmidecode, you can use this command:

 dmidecode -s bios-version 

and he will return

 VirtualBox 
+7
Apr 30 '14 at 15:41
source share

On Linux, you can report / proc / cpuinfo. If it is in VMware, it usually occurs differently than if it was on bare metal, but not always. Virtuozzo features end-to-end access to basic hardware.

+5
Sep 30 '08 at 17:45
source share

I would recommend a document published in Usenix HotOS '07, "Resistance is not transparency: myths about myths and realities of VMM", which contain several methods to determine if an application works in a virtualized environment.

For example, use the sidt command as redpill (but this instruction can also be made transparent by dynamic translation) or compare the cpuid runtime with other non-virtualized instructions.

+5
May 28 '09 at 13:21
source share

When installing a Ubuntu newbie, I discovered a package called imvirt. Look at it http://micky.ibh.net/~liske/imvirt.html

+5
Jan 14
source share

Try reading SMBIOS structures, especially BIOS structures.

On Linux, you can use the dmidecode utility to view information.

+4
Sep 30 '08 at 17:48
source share

Check out the virt-what tool. It uses the previously mentioned dmidecode to determine if you are on a virtualized host and type.

+4
Aug 09 2018-12-12T00:
source share

This C function will detect the VM guest OS:

(Tested on Windows, compiled using Visual Studio)

 #include <intrin.h> bool isGuestOSVM() { unsigned int cpuInfo[4]; __cpuid((int*)cpuInfo,1); return ((cpuInfo[2] >> 31) & 1) == 1; } 
+4
Aug 14 '15 at 14:39
source share

I use this C# class to determine if the guest OS is working inside a virtual environment ( windows only ):

sysInfo.cs

 using System; using System.Management; using System.Text.RegularExpressions; namespace ConsoleApplication1 { public class sysInfo { public static Boolean isVM() { bool foundMatch = false; ManagementObjectSearcher search1 = new ManagementObjectSearcher("select * from Win32_BIOS"); var enu = search1.Get().GetEnumerator(); if (!enu.MoveNext()) throw new Exception("Unexpected WMI query failure"); string biosVersion = enu.Current["version"].ToString(); string biosSerialNumber = enu.Current["SerialNumber"].ToString(); try { foundMatch = Regex.IsMatch(biosVersion + " " + biosSerialNumber, "VMware|VIRTUAL|AMI|Xen", RegexOptions.IgnoreCase); } catch (ArgumentException ex) { // Syntax error in the regular expression } ManagementObjectSearcher search2 = new ManagementObjectSearcher("select * from Win32_ComputerSystem"); var enu2 = search2.Get().GetEnumerator(); if (!enu2.MoveNext()) throw new Exception("Unexpected WMI query failure"); string manufacturer = enu2.Current["manufacturer"].ToString(); string model = enu2.Current["model"].ToString(); try { foundMatch = Regex.IsMatch(manufacturer + " " + model, "Microsoft|VMWare|Virtual", RegexOptions.IgnoreCase); } catch (ArgumentException ex) { // Syntax error in the regular expression } return foundMatch; } } } 



Application:

  if (sysInfo.isVM()) { Console.WriteLine("VM FOUND"); } 
+1
Sep 07 '15 at 2:22
source share

I tried a different approach suggested by my friend. Virtual machines running on VMWARE do not have the CPU TEMPERATURE property. ie They do not show the temperature of the processor. I am using a processor thermometer application to check the temperature of the processor.

(Windows Running In VMWARE) enter image description here

(Windows runs on a real processor) enter image description here

So I am coding a Small C program to detect a temperature sensor

 #include "stdafx.h" #define _WIN32_DCOM #include <iostream> using namespace std; #include <comdef.h> #include <Wbemidl.h> #pragma comment(lib, "wbemuuid.lib") int main(int argc, char **argv) { HRESULT hres; // Step 1: -------------------------------------------------- // Initialize COM. ------------------------------------------ hres = CoInitializeEx(0, COINIT_MULTITHREADED); if (FAILED(hres)) { cout << "Failed to initialize COM library. Error code = 0x" << hex << hres << endl; return 1; // Program has failed. } // Step 2: -------------------------------------------------- // Set general COM security levels -------------------------- hres = CoInitializeSecurity( NULL, -1, // COM authentication NULL, // Authentication services NULL, // Reserved RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation NULL, // Authentication info EOAC_NONE, // Additional capabilities NULL // Reserved ); if (FAILED(hres)) { cout << "Failed to initialize security. Error code = 0x" << hex << hres << endl; CoUninitialize(); return 1; // Program has failed. } // Step 3: --------------------------------------------------- // Obtain the initial locator to WMI ------------------------- IWbemLocator *pLoc = NULL; hres = CoCreateInstance( CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *)&pLoc); if (FAILED(hres)) { cout << "Failed to create IWbemLocator object." << " Err code = 0x" << hex << hres << endl; CoUninitialize(); return 1; // Program has failed. } // Step 4: ----------------------------------------------------- // Connect to WMI through the IWbemLocator::ConnectServer method IWbemServices *pSvc = NULL; // Connect to the root\cimv2 namespace with // the current user and obtain pointer pSvc // to make IWbemServices calls. hres = pLoc->ConnectServer( _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace NULL, // User name. NULL = current user NULL, // User password. NULL = current 0, // Locale. NULL indicates current NULL, // Security flags. 0, // Authority (for example, Kerberos) 0, // Context object &pSvc // pointer to IWbemServices proxy ); if (FAILED(hres)) { cout << "Could not connect. Error code = 0x" << hex << hres << endl; pLoc->Release(); CoUninitialize(); return 1; // Program has failed. } cout << "Connected to ROOT\\CIMV2 WMI namespace" << endl; // Step 5: -------------------------------------------------- // Set security levels on the proxy ------------------------- hres = CoSetProxyBlanket( pSvc, // Indicates the proxy to set RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx NULL, // Server principal name RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx NULL, // client identity EOAC_NONE // proxy capabilities ); if (FAILED(hres)) { cout << "Could not set proxy blanket. Error code = 0x" << hex << hres << endl; pSvc->Release(); pLoc->Release(); CoUninitialize(); return 1; // Program has failed. } // Step 6: -------------------------------------------------- // Use the IWbemServices pointer to make requests of WMI ---- // For example, get the name of the operating system IEnumWbemClassObject* pEnumerator = NULL; hres = pSvc->ExecQuery( bstr_t("WQL"), bstr_t(L"SELECT * FROM Win32_TemperatureProbe"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator); if (FAILED(hres)) { cout << "Query for operating system name failed." << " Error code = 0x" << hex << hres << endl; pSvc->Release(); pLoc->Release(); CoUninitialize(); return 1; // Program has failed. } // Step 7: ------------------------------------------------- // Get the data from the query in step 6 ------------------- IWbemClassObject *pclsObj = NULL; ULONG uReturn = 0; while (pEnumerator) { HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); if (0 == uReturn) { break; } VARIANT vtProp; // Get the value of the Name property hr = pclsObj->Get(L"SystemName", 0, &vtProp, 0, 0); wcout << " OS Name : " << vtProp.bstrVal << endl; VariantClear(&vtProp); VARIANT vtProp1; VariantInit(&vtProp1); pclsObj->Get(L"Caption", 0, &vtProp1, 0, 0); wcout << "Caption: " << vtProp1.bstrVal << endl; VariantClear(&vtProp1); pclsObj->Release(); } // Cleanup // ======== pSvc->Release(); pLoc->Release(); pEnumerator->Release(); CoUninitialize(); return 0; // Program successfully completed. } 

Vmware exit enter image description here

Conclusion on Real Cpu enter image description here

0
Oct 12 '16 at 9:18
source share



All Articles