vmware - किसी एप्लिकेशन से वर्चुअलाइज्ड ओएस का पता लगाएं?




virtualbox virtual-pc (10)

मुझे यह पता लगाने की ज़रूरत है कि मेरा एप्लिकेशन वर्चुअलाइज्ड ओएस इंस्टेंस के भीतर चल रहा है या नहीं।

मुझे इस विषय पर कुछ उपयोगी जानकारी के साथ एक लेख मिला है। एक ही लेख कई स्थानों पर दिखाई देता है, मैं मूल स्रोत से अनिश्चित हूं। VMware अपने बारे में जानकारी लौटने के लिए एक विशेष अमान्य x86 निर्देश लागू करता है, जबकि VirtualPC एक निर्देश संख्या के साथ एक जादू संख्या और I / O बंदरगाह का उपयोग करता है।

यह काम करने योग्य है, लेकिन दोनों मामलों में अनियंत्रित व्यवहार प्रतीत होता है। मुझे लगता है कि वीएमवेयर या वर्चुअल पीसी की भावी रिलीज तंत्र को बदल सकती है। क्या कोई बेहतर तरीका है? क्या उत्पाद के लिए कोई समर्थित तंत्र है?

इसी प्रकार, Xen या VirtualBox का पता लगाने का कोई तरीका है?

मैं उन मामलों के बारे में चिंतित नहीं हूं जहां मंच जानबूझकर खुद को छिपाने की कोशिश कर रहा है। उदाहरण के लिए, हनीपॉट वर्चुअलाइजेशन का उपयोग करते हैं लेकिन कभी-कभी उन तंत्रों को अस्पष्ट करते हैं जो मैलवेयर इसका पता लगाने के लिए उपयोग करेंगे। मुझे परवाह नहीं है कि मेरा ऐप सोचता है कि यह इन हनीपॉट्स में वर्चुअलाइज्ड नहीं है, मैं बस एक "सर्वश्रेष्ठ प्रयास" समाधान की तलाश में हूं।

एप्लिकेशन ज्यादातर जावा है, हालांकि मैं इस विशेष समारोह के लिए मूल कोड प्लस जेएनआई का उपयोग करने की उम्मीद कर रहा हूं। विंडोज एक्सपी / विस्टा समर्थन सबसे महत्वपूर्ण है, हालांकि संदर्भित आलेख में वर्णित तंत्र x86 की सामान्य विशेषताएं हैं और किसी भी विशेष ओएस सुविधा पर भरोसा नहीं करते हैं।


उपकरण virt-what । यह निर्धारित करने के लिए कि क्या आप वर्चुअलाइज्ड होस्ट और प्रकार पर हैं, यह पहले उल्लिखित dmidecode का उपयोग करता है।


क्या आपने नीली गोली, लाल गोली के बारे में सुना है ? । यह एक तकनीक है जो यह देखने के लिए प्रयोग की जाती है कि आप वर्चुअल मशीन के अंदर चल रहे हैं या नहीं। शब्द की उत्पत्ति मैट्रिक्स फिल्म से उत्पन्न होती है जहां नियो को नीली या लाल गोली दी जाती है (मैट्रिक्स = नीले रंग के अंदर रहने के लिए, या 'असली' दुनिया = लाल दर्ज करने के लिए)।

निम्नलिखित कुछ कोड है जो 'मैट्रिक्स' के अंदर चल रहे मक्खन का पता लगाएंगे या नहीं:
(कोड इस साइट से उधार लिया गया है जिसमें विषय के बारे में कुछ अच्छी जानकारी भी शामिल है):

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

जब आप एक वायरल मशीन के अंदर चल रहे हों, और 0 अन्यथा फ़ंक्शन 1 लौटाएगा।


नहीं। पूर्ण सटीकता के साथ पता लगाना असंभव है। QEMU जैसे कुछ वर्चुअलाइजेशन सिस्टम, हार्डवेयर रजिस्टरों को एक पूरी मशीन का अनुकरण करते हैं। आइए इसे चारों ओर घुमाएं: आप क्या करने की कोशिश कर रहे हैं? शायद हम इसके साथ मदद कर सकते हैं।


मुझे लगता है कि आगे बढ़ना, टूटी हुई एसआईडीटी वर्चुअलाइजेशन जैसी चालों पर भरोसा करना वास्तव में मदद नहीं करेगा क्योंकि हार्डवेयर सभी छेदों को प्लग करता है जो अजीब और गन्दा x86 आर्किटेक्चर छोड़ चुके हैं। सबसे अच्छा यह होगा कि वीएम प्रदाताओं को एक मानक तरीका के लिए लॉबी करना होगा ताकि आप यह कह सकें कि आप वीएम पर हैं - कम से कम उस मामले के लिए जब उपयोगकर्ता ने स्पष्ट रूप से अनुमति दी है। लेकिन अगर हम मानते हैं कि हम स्पष्ट रूप से वीएम को पहचानने की इजाजत दे रहे हैं, तो हम वहां पर दृश्यमान मार्कर भी रख सकते हैं, है ना? मैं आपको अपने वीएम पर डिस्क को बस एक फ़ाइल के साथ अद्यतन करने का सुझाव दूंगा जो आपको बता रहा है कि आप एक वीएम पर हैं - फाइल सिस्टम की जड़ में एक छोटी पाठ फ़ाइल, उदाहरण के लिए। या ETH0 के मैक का निरीक्षण करें, और इसे किसी ज्ञात स्ट्रिंग पर सेट करें।


मैं यह C# कक्षा का पता लगाने के लिए उपयोग करता हूं कि अतिथि ओएस वर्चुअल वातावरण ( केवल विंडोज़ ) के अंदर चल रहा है या नहीं:

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

}

उपयोग:

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

मैंने अपने दोस्त द्वारा सुझाए गए एक अलग दृष्टिकोण की कोशिश की। VMWARE पर चलने वाली वर्चुअल मशीनों में CPU TEMPERATURE संपत्ति नहीं है। यानी वे सीपीयू का तापमान नहीं दिखाते हैं। मैं सीपीयू तापमान की जांच के लिए सीपीयू थर्मामीटर आवेदन का उपयोग कर रहा हूँ।

(विंडोज़ वीएमवेयर में चल रहा है)

(विंडोज़ एक असली सीपीयू पर चल रहा है)

तो मैं तापमान सेंसर का पता लगाने के लिए एक छोटा सी कार्यक्रम कोड

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

}

एक वीएमवेयर मशीन पर आउटपुट

एक वास्तविक सीपीयू पर आउटपुट


लिनक्स के तहत मैंने कमांड का इस्तेमाल किया: dmidecode (मेरे पास सेंटोस और उबंटू दोनों हैं)

आदमी से:

dmidecode एक मानव-पठनीय प्रारूप में कंप्यूटर की डीएमआई (कुछ SMBIOS) टेबल सामग्री को डंप करने के लिए एक उपकरण है।

तो मैंने आउटपुट की खोज की और शायद इसकी माइक्रोसॉफ्ट हाइपर-वी पाया

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

एक अन्य तरीका यह है कि किस निर्माता को eth0 का मैक पता से संबंधित है: http://www.coffer.com/mac_find/

यदि यह माइक्रोसॉफ्ट, वीएमवेयर और आदि लौटाता है तो यह शायद एक आभासी सर्वर है।


लिनक्स के तहत, आप / proc / cpuinfo पर रिपोर्ट कर सकते हैं। यदि यह वीएमवेयर में है, तो आमतौर पर यह नंगे धातु पर होता है, लेकिन हमेशा नहीं होता है। Virtuozzo अंतर्निहित हार्डवेयर के लिए एक पास-थ्रू दिखाता है।


वीएमवेयर में यह निर्धारित करने के लिए एक तंत्र है कि क्या एक वीएमवेयर वर्चुअल मशीन नॉलेज बेस आलेख में सॉफ़्टवेयर चल रहा है जिसमें कुछ स्रोत कोड हैं।

माइक्रोसॉफ्ट के पास "हाइपरविजर स्थापित किया गया है " पर एक पृष्ठ भी है। एमएस अपने "सर्वर वर्चुअलाइजेशन सत्यापन परीक्षण" दस्तावेज़ के आईएसवीएम टेस्ट "खंड में एक हाइपरवाइजर की इस आवश्यकता को बताता है

वीएमवेयर और एमएस दस्तावेज़ दोनों हाइपरवाइजर-वर्तमान बिट (रजिस्टर ईसीएक्स के बिट 31) की जांच के लिए सीपीयूआईडी निर्देश का उपयोग करते हुए उल्लेख करते हैं।

आरएचईएल बगट्रैकर के पास ज़ेन कर्नेल के तहत रजिस्टर ईसीएक्स के बिट 31 सेट करने के लिए "सीएसआईआईडी पत्ता 0x00000001" के लिए आईएसवीएम बिट (ईसीएक्स: 31) सेट करना चाहिए "

तो विक्रेता विनिर्देशों में शामिल किए बिना ऐसा लगता है कि आप CPUID जांच का उपयोग यह जान सकते हैं कि आप वर्चुअल रूप से चल रहे हैं या नहीं।


SMBIOS संरचनाओं को पढ़कर देखें, विशेष रूप से BIOS जानकारी वाले structs।

लिनक्स में आप जानकारी ब्राउज़ करने के लिए dmidecode उपयोगिता का उपयोग कर सकते हैं।