سؤال

كنت بحاجة لاكتشاف ما إذا كان التطبيق الخاص بي يعمل داخل نظام التشغيل الظاهرية سبيل المثال أو لا.

لقد وجدت مقال مع بعض المعلومات المفيدة في هذا الموضوع.نفس المادة تظهر في أماكن متعددة ، أنا متأكد من المصدر الأصلي. VMware تنفذ معين صالح x86 تعليمات بالعودة المعلومات حول نفسها ، في حين VirtualPC يستخدم السحر رقم I/O ميناء في التعليمات.

هذا هو عملي ، ولكن يبدو أن تكون غير موثقة السلوك في كلتا الحالتين.أعتقد إصدار مستقبلي من VMWare أو VirtualPC قد تغيير آلية.هل هناك طريقة أفضل ؟ هل هناك دعم آلية المنتج ؟

وبالمثل, هل هناك طريقة للكشف عن كسين أو فيرتثلبوإكس?

أنا لا تشعر بالقلق إزاء الحالات التي يكون فيها منصة عمدا تحاول إخفاء نفسها.على سبيل المثال, مصائد مخترقي الشبكات عبر استخدام المحاكاة الافتراضية ولكن في بعض الأحيان تحجب آليات البرمجيات الخبيثة قد تستخدم للكشف عن ذلك.لا يهمني أن بلدي التطبيق سوف أعتقد أنه ليس من الظاهرية في هذه مصائد مخترقي الشبكات عبر, أنا أبحث عن "أفضل جهد" الحل.

التطبيق هو في الغالب جافا, على الرغم من أنني أتوقع أن استخدام التعليمات البرمجية الأصلية بالإضافة إلى JNI لهذا وظيفة معينة.ويندوز XP/Vista الدعم الأكثر أهمية ، على الرغم من الآليات المبينة في المادة المشار إليها عامة ملامح x86 و لا تعتمد على أي نظام تشغيل المرفق.

هل كانت مفيدة؟

المحلول

هل سمعت عن الحبة الزرقاء الحمراء حبوب منع الحمل ؟ .انها تقنية تستخدم لمعرفة ما إذا كنت تعمل داخل الجهاز الظاهري أو لا.أصل مصطلح ينبع من فيلم ماتريكس حيث الجدد وتقدم الأزرق أو الأحمر حبوب منع الحمل (البقاء داخل المصفوفة = أزرق ، أو لدخول العالم 'الحقيقية' = red).

وفيما يلي بعض التعليمات البرمجية التي سيتم الكشف عن هيتر كنت تعمل داخل 'ماتريكس' أو لا:
(رمز اقترضت من هذا الموقع الذي يحتوي أيضا على بعض المعلومات حول هذا الموضوع في متناول اليد):

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

وظيفة سيعود 1 عند تشغيل داخل virutal آلة, 0 خلاف ذلك.

نصائح أخرى

تحت لينكس اعتدت الأمر: dmidecode ( لدي سواء على CentOS و أوبونتو )

من الرجل:

dmidecode هو أداة الإغراق الكمبيوتر DMI (البعض يقول SMBIOS) الجدول محتويات في الإنسان-تنسيق قابل للقراءة.

لذا بحثت الإخراج وجدت على الأرجح 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

طريقة أخرى هي أن البحث الذي المصنعة عنوان MAC eth0 هو ذات الصلة إلى: http://www.coffer.com/mac_find/

إذا كان العائد مايكروسوفت ، وير & الخ..ثم ربما ملقم ظاهري.

وير له آليات لتحديد ما إذا كان البرنامج قيد التشغيل في برنامج VMware virtual machine مقالة "قاعدة المعارف" التي لديها بعض التعليمات البرمجية المصدر.

مايكروسوفت أيضا لديه صفحة على "تحديد ما إذا كان Hypervisor تثبيت".MS يحدد هذا الشرط الاساسي في IsVM اختبار" القسم الخاص بهم "التحقق من صحة الخادم الافتراضية اختبار" الوثيقة

وير و MS مستندات سواء ذكر باستخدام CPUID التعليمات للتحقق من hypervisor-الحاضر بت (bit 31 من تسجيل ECX)

RHEL bugtracker واحد على "أن مجموعة ISVM بت (ECX:31) عن CPUID ورقة 0x00000001" تعيين بت 31 من تسجيل ECX تحت كسين النواة.

حتى من دون الدخول في مورد تفاصيل يبدو مثل يمكنك استخدام CPUID تحقق لمعرفة إذا كنت تعمل فعليا أم لا.

لا.هذا هو المستحيل للكشف بدقة كاملة.بعض الافتراضية ، كيمو, محاكاة جهاز بأكمله وصولا إلى سجلات الأجهزة.دعونا حول هذا:ما الذي تحاول فعله ؟ ربما نحن يمكن أن تساعد في ذلك.

أعتقد أن تسير إلى الأمام ، الاعتماد على الحيل مثل كسر SIDT الافتراضية هو حقا لن يساعد الأجهزة المقابس في جميع الثقوب التي الغريب و الفوضى المعمارية x86 قد تركت.أفضل أن اللوبي Vm مقدمي طريقة قياسية أن أقول أن كنت على VM-على الأقل من أجل القضية عندما قام المستخدم بشكل صريح يسمح بذلك.ولكن إذا افترضنا أننا صراحة السماح VM كشف يمكننا أيضا وضع علامات مرئية في هناك, صحيح ؟ أود أن أقترح فقط تحديث القرص الخاص بك VMs مع ملف أقول لك أن كنت على VM -- ملف نصي صغير في جذر نظام الملفات ، على سبيل المثال.أو تفقد ماك من ETH0 و مجموعة معينة معروفة السلسلة.

على فيرتثلبوإكس ، على افتراض لديك السيطرة على VM الضيف لديك dmidecode ، يمكنك استخدام هذا الأمر:

dmidecode -s bios-version

وأنه سيعود

VirtualBox

أود أن أوصي ورقة نشرت في اتحاد الحوسبة التقنية المتقدمة HotOS '07, Comptibility ليس الشفافية:VMM الكشف عن الأساطير والحقائق, التي خلصت إلى العديد من التقنيات معرفة ما إذا كان التطبيق قيد التشغيل في بيئة افتراضية.

على سبيل المثال ، استخدام sidt تعليمات redpill لا(ولكن هذه التعليمات يمكن أيضا أن تكون شفافة عن طريق الترجمة الدينامية) ، أو مقارنة من وقت cpuid ضد أخرى غير الافتراضية التعليمات.

في لينكس يمكنك تقرير /proc/cpuinfo.إذا كان في إم وير ، فإنه عادة ما يأتي المتابعة بشكل مختلف عما إذا كان على المعدن ، ولكن ليس دائما.Virtuozzo يظهر أن تمر من خلال الأجهزة الأساسية.

أثناء تثبيت الإنترنت أحد أوبونتو اكتشفت مجموعة تسمى imvirt.نلقي نظرة على ذلك في http://micky.ibh.net/~liske/imvirt.html

هذا ج وظيفة سيتم الكشف عن VM التشغيل الضيف:

(اختبار على ويندوز ، وقد تم تجميعها مع Visual Studio)

#include <intrin.h>

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

حاول من خلال قراءة SMBIOS الهياكل وخاصة البنيات مع BIOS المعلومات.

في لينكس يمكنك استخدام dmidecode أداة تصفح المعلومات.

التحقق من أداة virt-ما.ويستخدم ذكر سابقا dmidecode لتحديد ما إذا كنت على ظاهر المضيف نوع.

أنا استخدم هذا C# فئة للكشف إذا كان نظام التشغيل الضيف يعمل داخل بيئة افتراضية (ويندوز فقط):

سسنفو.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");
        }

على لينكس systemd يوفر قيادة للكشف عن إذا كان نظام تشغيل الجهاز الظاهري أو لا.

الأمر:
$ systemd-detect-virt

إذا كان النظام هو ظاهر في ذلك نواتج اسم virtuslization softwarwe/التكنولوجيا.إذا لم يكن ثم كان النواتج none

فعلى سبيل المثال إذا كان نظام تشغيل KVM ثم:

$ systemd-detect-virt
kvm

لا تحتاج إلى تشغيل سودو.

حاولت مقاربة مختلفة اقترح صديقي.الأجهزة الظاهرية تشغيل على برنامج VMWARE لا تملك درجة الحرارة وحدة المعالجة المركزية الملكية.أنا.أي أنهم لا تظهر درجة حرارة وحدة المعالجة المركزية.أنا باستخدام وحدة المعالجة المركزية الحرارة طلب التحقق من درجة الحرارة وحدة المعالجة المركزية.

(تشغيل ويندوز في إم وير) enter image description here

(تشغيل ويندوز على وحدة المعالجة المركزية) enter image description here

لذلك أنا رمز صغير ج برنامج للكشف عن درجة الحرارة Senser

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

}

الإخراج في إم وير الجهاز enter image description here

الإخراج في وحدة المعالجة المركزية enter image description here

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top