2009-01-31 35 views
31

Làm cách nào để phát hiện (.NET hoặc Win32) nếu ứng dụng của tôi đang chạy trên máy ảo?Làm cách nào để phát hiện xem ứng dụng của tôi có đang chạy trên máy ảo không?

+0

Tôi đã chạy một ứng dụng vào một ngày khác và nó sẽ không chạy trong Máy ảo ... nó nói nó không thể. Tôi đã tự hỏi làm thế nào nó biết. – Jason

+5

Có một số thứ không hoạt động trong máy ảo: một số phần của MS SQL Server, C# cho trình mô phỏng thiết bị và * gasp * Virtual PC/Server. Có thể lập kế hoạch cho điều đó trong các chương trình và kịch bản là có giá trị. –

+1

... vì vậy nếu bạn có sự phụ thuộc vào thứ gì đó không hoạt động trong một số môi trường (ví dụ: máy ảo), thì bạn nên truy vấn phụ thuộc đó để xem liệu nó có hoạt động trong môi trường hiện tại hay không. Hoặc có lẽ tôi đã bỏ lỡ quan điểm của bạn? – reuben

Trả lời

17

Theo Virtual PC Guy 's blog post 'Detecting Microsoft virtual machines', bạn có thể sử dụng WMI để kiểm tra với nhà sản xuất bo mạch chủ. Trong PowerShell:

(gwmi Win32_BaseBoard).Manufacturer -eq "Microsoft Corporation" 
+15

Er, còn máy ảo không phải MS thì sao? –

+4

Ngoài ra, như đã đề cập bởi commenter @ErikFunkenbusch về câu trả lời của tôi cho câu hỏi này, kiểm tra này sẽ không chính xác xác định MS Surface Pro như một máy ảo. – RobSiklos

+0

Để công bằng, đối với MS Virtual Machines, nhiều sản phẩm Surface đã được phát hành _after_ câu trả lời này đã được đăng. –

12

Dưới đây là ví dụ về một cách để thực hiện. Nó chỉ làm việc với Virtual PC của Microsoft và VMWare, nhưng đó là một sự khởi đầu: http://www.codeproject.com/KB/system/VmDetect.aspx

+0

Điều đó rất thú vị ... xem cách các máy phản ứng với việc sử dụng các lệnh lắp ráp không hợp lệ. Tuyệt vời! – Jason

+1

Tôi đã tìm kiếm "phát hiện nếu chạy trong máy ảo" (không có dấu ngoặc kép) trong Google và đó là kết quả đầu tiên. –

+1

Thực ra cách tốt nhất là "lấy dấu phần cứng": http://blogs.msdn.com/virtual_pc_guy/archive/2005/10/27/484479.aspx –

0

Cách đơn giản nhất tôi tìm thấy để tìm hiểu xem ứng dụng # C của tôi đang chạy trên một máy ảo vmware hoặc không phải là để kiểm tra địa chỉ MAC của card NIC (s). Nếu đó là một máy ảo VMware nó sẽ luôn luôn là: 00: 50: 56: XX: YY: ZZ

Bạn có thể liệt kê thông qua NIC as resolved here.

+4

-1: tất nhiên VMware được tự do thay đổi định dạng địa chỉ MAC của họ bất cứ khi nào họ muốn, mà không nói trước cho bạn –

+1

Theo http://standards.ieee.org VMWare sử dụng: 00:05:69, 00: 0C: 29 , 00: 1C: 14 cũng như 00:50:56 cho phần Tổ chức của Địa chỉ MAC. Và như @John_Saunders cho biết, họ có thể thêm một số mới vào danh sách bất cứ khi nào họ muốn. –

3

Jay Abuzi cho thấy dung dịch trong PowerShell. Dưới đây là giống như aC# Chức năng:

/// <summary> 
    /// Detect if this OS runs in a virtual machine 
    /// 
    /// http://blogs.msdn.com/b/virtual_pc_guy/archive/2005/10/27/484479.aspx 
    /// 
    /// Microsoft themselves say you can see that by looking at the motherboard via wmi 
    /// </summary> 
    /// <returns>false</returns> if it runs on a fysical machine 
    public bool DetectVirtualMachine() 
    { 
     bool result = false; 
     const string MICROSOFTCORPORATION ="microsoft corporation"; 
     try 
     { 
      ManagementObjectSearcher searcher = 
       new ManagementObjectSearcher("root\\CIMV2","SELECT * FROM Win32_BaseBoard"); 

      foreach (ManagementObject queryObj in searcher.Get()) 
      { 
       result = queryObj["Manufacturer"].ToString().ToLower() == MICROSOFTCORPORATION.ToLower(); 
      } 
      return result; 
     } 
     catch (ManagementException ex) 
     { 
      return result; 
     } 
    } 
+0

Đáng buồn thay, kỹ thuật này và tương tự không hoạt động trong hệ thống W7 của tôi đang chạy VMWare ThinApp để kiểm tra. ** queryObj.Properties ** giống hệt nhau trong cả hai môi trường. –

+1

@ JesseChisholm - không chỉ vậy, nhưng điều này sẽ báo cáo sai rằng phần cứng không phải của Microsoft là một máy ảo, chẳng hạn như Surface Pro. Tôi muốn đề nghị rằng bạn đã có một thiết lập sai nếu ThinApp của bạn ảo hóa dữ liệu WMI. –

+0

@ErikFunkenbusch - Toàn bộ điểm ** ảo hóa là vì vậy mã không cần phải biết hoặc quan tâm cho dù đó là trực tiếp hay ảo. Vì vậy, mỗi nhà sản xuất VM làm việc rất chăm chỉ để làm cho nó không thể biết. Cho đến nay, cách duy nhất tôi đã tìm thấy cho _my_ ứng dụng để biết, là có thực thi VM vượt qua trong một tham số dòng lệnh cho tôi biết tôi đang chạy ảo. Thở dài. –

36

Đây là những gì tôi sử dụng:

using (var searcher = new System.Management.ManagementObjectSearcher("Select * from Win32_ComputerSystem")) 
{ 
    using (var items = searcher.Get()) 
    { 
    foreach (var item in items) 
    { 
     string manufacturer = item["Manufacturer"].ToString().ToLower(); 
     if ((manufacturer == "microsoft corporation" && item["Model"].ToString().ToUpperInvariant().Contains("VIRTUAL")) 
      || manufacturer.Contains("vmware") 
      || item["Model"].ToString() == "VirtualBox") 
     { 
     return true; 
     } 
    } 
    } 
} 
return false; 

Sửa 2014/12/02: Mã Cập nhật để nó không còn phát hiện một Microsoft Surface Pro như một máy ảo. Cảm ơn Erik Funkenbusch đã chỉ ra điều này.

Chỉnh sửa 2017-06-29: Mã được cập nhật để mã cũng kiểm tra giá trị của thuộc tính HypervisorPresent.

Chỉnh sửa 2018-02-05: xóa séc đối với thuộc tính HypervisorPresent vì nó không chính xác. Thuộc tính này có thể trả về true nếu chạy trên máy chủ O/S trên máy chủ hyper-V.

+2

Một số kiểm tra nhanh có vẻ như biểu thức kiểm tra có thể được đơn giản hóa (đối với một số định nghĩa 'đơn giản hóa') thành 'item [" Model "]. ToString(). ToLower(). Chứa (" virtual ")'. –

+0

Bạn có thể truyền "các mục" thành '' IEnumerable '' như sau: 'var managementItems = items.OfType ();' để sử dụng với các phương thức mở rộng 'IEnumerable'. –

+2

Tôi nghĩ mã này sẽ phát hiện phần cứng máy tính của Microsoft như phần cứng của máy ảo, chẳng hạn như Surface Pro. –

0
public static bool isVirtualMachine() 
{ 
    const string MICROSOFTCORPORATION = "microsoft corporation"; 
    const string VMWARE = "vmware"; 

    foreach (var item in new ManagementObjectSearcher("Select * from Win32_ComputerSystem").Get()) 
    { 
     string manufacturer = item["Manufacturer"].ToString().ToLower(); 
     // Check the Manufacturer (eg: vmware, inc) 
     if (manufacturer.Contains(MICROSOFTCORPORATION) || manufacturer.Contains(VMWARE)) 
     { 
      return true; 
     } 

     // Also, check the model (eg: VMware Virtual Platform) 
     if (item["Model"] != null) 
     { 
      string model = item["Model"].ToString().ToLower(); 
      if (model.Contains(MICROSOFTCORPORATION) || model.Contains(VMWARE)) 
      { 
       return true; 
      } 
     } 
    } 
    return false; 
} 
+0

Đáng buồn thay, kỹ thuật này và tương tự không hoạt động trong hệ thống W7 của tôi đang chạy VMWare ThinApp để kiểm tra. * queryObj.Properties ** giống hệt nhau trong cả hai môi trường –

1

Để kiểm tra mức độ thấp hơn Tôi khuyên bạn nên xem ScoopyNG [1]. Nó là một tập hợp các phương thức phát hiện vm ở mức độ thấp, hoạt động tốt, mặc dù có một chút ngày.

Nếu bạn thực sự muốn dựa vào những thứ khác, như công cụ đã cài đặt (VM * Additions), chúng dễ dàng hơn nhiều để "giả".

Bài đăng trên blog này cũng có một cái nhìn tổng quan khá đẹp, từ các công cụ cấp thấp, kiểm tra các tệp DLL, filepath và khóa registry cụ thể để kiểm tra.

[1] http://trapkit.de/research/vmm/scoopyng/index.html

[2] http://securitykitten.github.io/vm-checking-and-detecting/

2

chức năng C này sẽ phát hiện VM Khách OS: (Tested trên Windows, biên soạn với Visual Studio)

#include <intrin.h> 

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

Để làm rõ, đoạn mã này sử dụng lệnh 'cpuid' để phát hiện xem bit feature có được thiết lập cho biết mã đang chạy trên hypervisor hay không. không có yêu cầu rằng một hypervisor thực tế luôn đặt bit này, đặc biệt là cho các hypervisor phần mềm. –

0

C++ đang sẽ phát hiện các Sản phẩm Vmware như express, esx, fusion hoặc workstation

// VMWareDetector.cpp : Defines the entry point for the console application. 
// 

#include "stdafx.h" 
#include "windows.h" 
#include <conio.h> 
void CheckVM(void); 
int main() 
{ 
    CheckVM(); 
    _getch(); 
    return 0; 
} 

void CheckVM(void) 
{ 
    unsigned int a, b; 

    __try { 
     __asm { 

      // save register values on the stack 
      push eax 
      push ebx 
      push ecx 
      push edx 

      // perform fingerprint 
      mov eax, 'VMXh' // VMware magic value (0x564D5868) 
      mov ecx, 0Ah // special version cmd (0x0a) 
      mov dx, 'VX' // special VMware I/O port (0x5658) 

      in eax, dx // special I/O cmd 

      mov a, ebx // data 
      mov b, ecx // data (eax gets also modified 
         // but will not be evaluated) 

         // restore register values from the stack 
         pop edx 
         pop ecx 
         pop ebx 
         pop eax 
     } 
    } 
    __except (EXCEPTION_EXECUTE_HANDLER) {} 
    printf("\n[+] Debug : [ a=%x ; b=%d ]\n\n", a, b); 
    if (a == 'VMXh') { // is the value equal to the VMware magic value? 
     printf("Result : VMware detected\nVersion : "); 
     if (b == 1) 
      printf("Express\n\n"); 
     else if (b == 2) 
      printf("ESX\n\n"); 
     else if (b == 3) 
      printf("GSX\n\n"); 
     else if (b == 4) 
      printf("Workstation\n\n"); 
     else 
      printf("unknown version\n\n"); 
    } 
    else 
     printf("Result : Not Detected\n\n"); 
} 
Các vấn đề liên quan