Frage

Ich muß erkennen, ob meine Anwendung in einer virtualisierten OS-Instanz ausgeführt wird oder nicht.

Ich habe festgestellt einen Artikel einige nützliche Informationen zum Thema. Der gleiche Artikel an mehreren Stellen angezeigt wird, ich bin nicht sicher, der ursprünglichen Quelle. VMware implementiert einen bestimmten ungültigen x86-Befehl Informationen über sich selbst zurück, während VirtualPC eine magische Zahl und I / O-Port mit einem IN-Befehl verwendet.

Dies ist bearbeitbar, scheint aber nicht dokumentiert Verhalten in beiden Fällen zu sein. Ich nehme an eine zukünftige Version von VMWare oder VirtualPC könnte den Mechanismus ändern. Gibt es einen besseren Weg? Gibt es einen unterstützten Mechanismus für die beiden Produkte?

In ähnlicher Weise ist es eine Möglichkeit, Xen oder VirtualBox ?

Ich bin nicht besorgt über Fälle, in denen die Plattform bewusst selbst zu verbergen versucht. Verwenden Sie zum Beispiel Honeypots Virtualisierung aber manchmal die Mechanismen verschleiern, die Malware verwenden würde es zu erkennen. Mir ist es egal, dass meine App denke, es wäre nicht in dieser Honeypots virtualisiert ist, ich bin nur für eine „best effort“ Lösung suchen.

Die Anwendung ist vor allem Java, obwohl ich nativen Code und JNI für diese Funktion zu nutzen bin zu erwarten. Windows XP / Vista-Unterstützung ist sehr wichtig, wenn die in dem genannten Artikel beschriebenen Mechanismen generische Funktionen von x86 und verlassen Sie sich nicht auf eine bestimmte OS-Anlage.

War es hilfreich?

Lösung

Haben Sie davon gehört? blaue Pille, rote Pille? . Es ist eine Technik verwendet, um zu sehen, wenn Sie in einer virtuellen Maschine oder nicht ausgeführt werden. Der Ursprung des Begriffs stammt von dem Matrix Film wo Neo einer blauen oder rote Pille angeboten (bleibt in der Matrix = blau, oder die ‚reale‘ Welt = rot eingeben).

Hier finden Sie einige Code, der erkennt wheter Sie in ‚die Matrix‘ ausgeführt werden oder nicht:
(Code entlehnt dieser Seite die enthält auch einige nette Informationen über das Thema bei der Hand):

 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;
 } 

Die Funktion gibt 1 zurück, wenn Sie innerhalb einer virutal Maschine ausgeführt werden, und 0 sonst.

Andere Tipps

Unter Linux verwendete ich den Befehl: dmidecode (ich habe es sowohl auf CentOS und Ubuntu)

von dem Mann:

  

dmidecode ist ein Werkzeug zum Dumping eines   Computer des DMI (manche sagen SMBIOS) Tabelle   Inhalt in einem für Menschen lesbares Format.

Also suchte ich die Ausgabe und fand heraus, seine wahrscheinlich 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

Eine andere Möglichkeit ist, an die Hersteller die MAC-Adresse von eth0 zu suchen ist verwandt mit: http://www.coffer.com/mac_find /

Wenn es zurückgeben Microsoft, vmware & etc .. dann ist es wahrscheinlich ein virtueller Server.

VMware hat einen Mechanismen zu bestimmen, ob Software in einer virtuellen VMware-Maschine Knowledge Base-Artikel läuft was einige Quellcode hat.

Microsoft hat auch eine Seite auf "Feststellen, ob Hypervisor ist installiert ". MS buchstabiert diese Anforderung von einem Hypervisor in dem Isvm TEST“Abschnitt ihres "Server Virtualization Validation Test" Dokument

Die VMware und MS-Dokumente sowohl erwähnt unter Verwendung des CPUID-Befehl den Hypervisor-Vorhanden-Bit (Bit 31 des Register ECX) zu überprüfen

Der RHEL Bugtracker hat man für "sollte Isvm Bit gesetzt (ECX: 31) für CPUID Blatt 0x00000001" Bit 31 des Registers ECX unter dem Xen-Kernel.

Also, ohne in Kreditoren Spezifika immer sieht es aus wie Sie die CPUID-Prüfung nutzen konnte wissen, ob Sie laufen praktisch oder nicht.

Nein. Dies ist unmöglich, mit absoluter Genauigkeit zu erfassen. Einige Virtualisierungssysteme wie QEMU , dass die gesamte Maschine bis zu den Hardware-Registern emulieren. Lassen Sie uns diese umdrehen: Was ist es Sie versuchen zu tun? Vielleicht können wir dabei helfen.

Ich denke, dass nach vorn gehen, auf Tricks angewiesen wie die gebrochene SIDT Virtualisierung nicht wirklich wird helfen, da die Hardware alle Löcher verstopft, dass die seltsame und unordentlich x86-Architektur verlassen haben. Am besten wäre es, den Vm-Anbieter für einen Standard-Weg zur Lobby zu sagen, dass Sie auf einer VM sind - zumindest für den Fall, wenn der Benutzer der ausdrücklich erlaubt hat. Aber wenn wir davon ausgehen, dass wir ausdrücklich die VM erlauben erkannt werden, können wir genauso gut platzieren sichtbare Markierungen in es, nicht wahr? Ich würde vorschlagen, nur die Festplatte auf Ihrer VMs mit einer Datei aktualisieren Sie sagen, dass Sie auf einer VM sind - eine kleine Textdatei, in der Wurzel des Dateisystems, zum Beispiel. Oder überprüfen Sie die MAC von ETH0 und festgelegt, dass zu einem bestimmten bekannten String.

Auf VirtualBox, vorausgesetzt, Sie Kontrolle über den VM-Gast haben, und Sie haben dmidecode, können Sie diesen Befehl verwenden:

dmidecode -s bios-version

und es wird wieder

VirtualBox

Ich mag ein Papier geschrieben auf Usenix otos empfehlen '07, Comptibility ist nicht Transparenz: VMM-Erkennung Mythen und Wirklichkeiten , die mehrere Techniken kommen zu dem Schluss zu sagen, ob die Anwendung in einer virtualisierten läuft Umgebung.

Verwenden Sie zum Beispiel sidt Anweisung als Redpill tut (aber dieser Befehl kann auch transparent durch dynamische Übersetzung gemacht werden) oder die Laufzeit von cpuid gegen andere nicht-virtualisierten Anweisungen vergleichen.

Unter Linux können Sie auf / proc / cpuinfo melden. Wenn es in VMware ist, kommt es-up in der Regel anders, als wenn sie auf blankes Metall ist, aber nicht immer. Virtuozzo zeigt einen Pass-Through auf die zugrunde liegende Hardware.

Während die newes Ubuntu Installation entdeckte ich das Paket namens imvirt. Werfen Sie einen Blick auf sie unter http://micky.ibh.net/~liske/imvirt.html

Diese C-Funktion erkennt VM-Gastbetriebssystem:

(Getestet unter Windows kompiliert mit Visual Studio)

#include <intrin.h>

    bool isGuestOSVM()
    {
        unsigned int cpuInfo[4];
        __cpuid((int*)cpuInfo,1);
        return ((cpuInfo[2] >> 31) & 1) == 1;
    }

Versuchen Sie durch das Lesen der SMBIOS Strukturen, vor allem die Strukturen mit der BIOS Informationen.

Unter Linux können Sie verwenden, um den dmidecode Dienstprogramm, um die Informationen zu suchen.

Überprüfen Sie das Werkzeug virt-was . Es verwendet die zuvor dmidecode erwähnt, um zu bestimmen, ob Sie auf einer virtualisierten Host und den Typ sind.

Ich benutze diese C# Klasse zu erkennen, ob das Gastbetriebssystem innerhalb einer virtuellen Umgebung ( Fenster nur ) ausgeführt wird:

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|A M I|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;
            }
        }

}

Verwendung:

        if (sysInfo.isVM()) { 
            Console.WriteLine("VM FOUND");
        }

Unter Linux systemd liefert einen Befehl zum Erkennen, ob das System als virtuelle Maschine ausgeführt wird oder nicht.

Befehl:
$ systemd-detect-virt

Wenn das System den es gibt Namen des virtuslization softwarwe / Technologie virtualisiert wird. Wenn nicht, dann gibt er none

Zum Beispiel, wenn das System läuft KVM dann:

$ systemd-detect-virt
kvm

Sie müssen nicht als sudo ausgeführt werden.

habe ich versucht, ein anderer Ansatz von meiner friend.Virtual Maschine vorgeschlagen auf VMWARE laufen müssen nicht CPU-Temperatur-Eigenschaft. das heißt sie nicht die Temperatur der CPU anzeigen. Ich bin mit CPU Thermometer Anwendung für die CPU-Temperatur prüfen.

(Windows Laufen in VMWARE) eingeben Bild Beschreibung hier

(Windows auf einer realen CPU ausgeführt wird) eingeben Bild Beschreibung hier

So I-Code ein kleiner C-Programm die Temperatur Senser

erkennen
#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.

}

Ausgabe auf einer VMware-Maschine eingeben Bild Beschreibung hier

Ausgabe auf einem echten Cpu eingeben Bild Beschreibung hier

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top