Wykrywanie VMware w C#

Jak wykryć VMware

VMware jest często wykorzystywane w celu uruchamiania złamanego oprogramowania lub aby ominąć zabezpieczenia autora oprogramowania.

Często to wygląda tak, że kupujący po zakupie oprogramowania otrzymuje licencję zablokowaną na sprzętowy identyfikator jednego komputera, który okazuje się być obrazem VMware i tak później oprogramowanie jest dystrybuowane (czytaj sprzedawane) dalej.

Wersji natywnych, wykorzystujących systemowe różnice w działaniu na wykrywanie VMware są dziesiątki, chciałem przedstawić krótki snippet w C# do wykrywania może nie samego VMware, ale narzędzi VMware Tools, które instaluje się na wirtualnej maszynie, aby zapewnić komfortową pracę między wirtualną maszyną, a maszyną użytkownika (np. zapewnić funkcje drag&drop plików etc.), jest to zwykle jedna z pierwszych czynności jakie robi się po zainstalowaniu systemu na wirtualnej maszynie.

using System;
using System.Runtime.InteropServices;

// potrzebne importy
[DllImport("KERNEL32.dll", SetLastError=true)]
static extern IntPtr OpenEvent(uint dwDesiredAccess, bool bInheritHandle, string lpName);

[DllImport("KERNEL32.dll", SetLastError=true)]
static extern IntPtr CreateMutex(IntPtr lpMutexAttributes, bool bInitialOwner, string lpName);

[DllImport("KERNEL32.dll")]
private extern static Boolean CloseHandle(IntPtr handle);

public const int ERROR_ALREADY_EXISTS = 183;

/// 
/// wykrywanie obecności VMWare po zainstalowanych narzędziach VMWare Tools
/// na wirtualnej maszynie
/// 
/// true jeśli wykryto zainstalowane narzędzia VMWare Tools
public static bool IsVMWare()
{
    // otwórz obiekt "VMwareDnDManagerEvent"
    IntPtr eventHandle = OpenEvent(0x001F0003, false, "VMwareDnDManagerEvent");

    // jeśli udało się otworzyć event, to znaczy, że obecne są narzędzia VMWare Tools
    if (eventHandle != IntPtr.Zero)
    {
        CloseHandle(eventHandle);
        return true;
    }

    // utwórz mutex o nazwie wykorzystywanej przez VMWare Tools
    IntPtr mutexHandle = CreateMutex(IntPtr.Zero, false, "VMwareGuestDnDDataMutex");

    // zamknij uchwyt mutexa
    if (mutexHandle != IntPtr.Zero)
    {
        CloseHandle(mutexHandle);
    }

    // jeśli mutex o tej nazwie istnieje, to znaczy, że są obecne narzędzia VMware Tools
    if (Marshal.GetLastWin32Error() == ERROR_ALREADY_EXISTS)
    {
        return true;
    }

    return false;
}

Wykrywanie dotyczy VMware w wersji 7, w wersji 8 należy już zastosować inne nazwy obiektów ze względu na zaktualizowane VMware Tools, jeśli ktoś jest zainteresowany wykrywaniem VMware w najnowszych wersjach (i nie tylko tego środowiska, np. VirtualBox etc.), proszę o kontakt.