Parsi Coders
Virtual Machine Detection - نسخه قابل چاپ

+- Parsi Coders (http://parsicoders.com)
+-- انجمن: Cracking / Anti Crack (http://parsicoders.com/forumdisplay.php?fid=75)
+--- انجمن: Anti Debug (http://parsicoders.com/forumdisplay.php?fid=76)
+--- موضوع: Virtual Machine Detection (/showthread.php?tid=1059)



Virtual Machine Detection - Amin_Mansouri - 10-16-2011

با سورس زیر میتونید تشخیص بدید برنامه تو vm اجرا شده یا نه ...
کد:
/*
Virtual Machine Detection
   Coded by stoopid

Credits to Cobein
*/

#include <stdio.h>
#include <windows.h>

char* sProduct[] = { "*VMWARE*", "*VBOX*", "*VIRTUAL*" };    

bool DetectVM()
{
    HKEY hKey;
    char szBuffer[64];  
    unsigned long hSize = sizeof(szBuffer) - 1;
    
    if (RegOpenKeyEx( HKEY_LOCAL_MACHINE, "SYSTEM\\ControlSet001\\Services\\Disk\\Enum", 0, KEY_READ, &hKey ) == ERROR_SUCCESS )
    {
        if( RegQueryValueEx( hKey, "0", NULL, NULL, (unsigned char *)szBuffer, &hSize ) == ERROR_SUCCESS)
        {
            for( int i = 0; i < ( sizeof( sProduct ) / sizeof( char* ) ); i++ )
            {
                if( strstr( szBuffer, sProduct[ i ] ) )
                {
                    RegCloseKey( hKey );
                    return true;
                }
            }
        }
        RegCloseKey( hKey );
    }
    return false;
}

int main()
{    
    if ( DetectVM() ) {
        printf ( "VM detected\n" );
    }
    else {
        printf ( "No VM detected\n" );
    }
    return 0;
}



RE: Virtual Machine Detection - Amin_Mansouri - 10-16-2011

Check if windows host is a VM.
Cross-compiled with mingw 4.2.1 and 4.4.5, tested under XP 32 bits and '7' 64 bits VBox VMs only
کد:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <windows.h>
#include <tlhelp32.h>

/* maximun length of registry subkeys.
* MAX_CHAR/5 is set as the maximun length of processes names. */
#define MAX_CHAR 100

typedef char * string;


/*    removes the first character of given string.
*    example: Str="blah"; _StrLower(Str); <- Str is now "lah".
*/
void _substr(string Str){
    size_t i;
    for(i=0; Str[i]; i++)
        Str[i] = Str[i+1];
    Str[i] = '\0';
}


/*    converts the string to lower case.
*    example: Str="bLAH"; _StrLower(Str); <- Str is now "blah".
*/
void _StrLower(string Str){

    size_t i;
    for (i = 0; (Str[i] = (char)tolower(Str[i])) != '\0'; i++)
        ;
}


/*    checks if the given process is running.
*    case of 'proc' doesn't matter
*    example: chk_process("ExPLoReR.eXE") returns TRUE if explorer.exe is running.
*    taken from:
*    http://stackoverflow.com/questions/8...-its-name-in-c
*/
bool chk_process(string proc){

    PROCESSENTRY32 entry;
    entry.dwFlags = sizeof(PROCESSENTRY32);
    unsigned short len = strlen(proc);
    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
    char exe_name[MAX_CHAR] = "";
    _StrLower(proc);

    if(Process32First(snapshot, &entry))
        while(Process32Next(snapshot, &entry)){
            strcpy(exe_name, entry.szExeFile);
            exe_name[MAX_CHAR-1] = '\0';
            _StrLower(exe_name);
            if(!strncmp(proc, exe_name, len))
                return TRUE;
        }

    CloseHandle(snapshot);

    return FALSE;
}


/*    check if the given subkey exists.
*        key = name of subkey in HKEY_LOCAL_MACHINE in which to find subkeys
*        vals = array of strings with which to compare the subkeys
*        size = number of strings in 'vals'
*    example: query_subkey("HARDWARE\\ACPI\\DSDT", { "VBOX__" }, 1) returns true if there exist the
*        subkey "VBOX__" under "HKEY_LOCAL_MACHINE\HARDWARE\ACPI\DSDT"
*    case for strings in 'vals' matter, other don't.
*/
bool query_subkey(string key, char vals[][MAX_CHAR], unsigned short size){

    char subkey_name[256];
    unsigned long subkey_name_len, retcode, i, j;
    HKEY hkey;

    if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, key, NULL, KEY_ENUMERATE_SUB_KEYS, &hkey) == ERROR_SUCCESS)

        for(i = 0; 1; i++){

            subkey_name_len = 255;
            retcode = RegEnumKeyExA(hkey, i, subkey_name, &subkey_name_len, NULL, NULL, NULL, NULL);
            subkey_name[255] = '\0';

            if(retcode == ERROR_SUCCESS)

                for(j = 0; j < size; j++){

                    if(vals[j] && !strcmp(vals[j], subkey_name)){

                        RegCloseKey(hkey);
                        return TRUE;
                    }
                }

            else if(retcode == ERROR_NO_MORE_ITEMS){

                RegCloseKey(hkey);
                return FALSE;
            }
        }

    RegCloseKey(hkey);

    return FALSE;
}


/*    check if a string 'Str' is contained in registry value 'val', under the subkey 'key' in HKEY_LOCAL_MACHINE
*        key = represents the subkey in HKEY_LOCAL_MACHINE
*        val = name of the value in the subkey. if it doesn't exists, return FALSE
*        Str = string with which to compare the data in the value val
*    only for REG_SZ value types.
*    example:
*    query_val_data("HARDWARE\\DESCRIPTION\\System", "Identifier", "VBOX") will return TRUE if "vbox" is contained
*        contained in the registry value "Identifier" under "HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System".
*    case of registry value 'val' matter, other don't.
*/
bool query_val_data(string key, string val, string Str){

    HKEY hkey;
    DWORD size = 500, keytype = REG_SZ, i=0;
    unsigned char data_name[size];
    char data[size];

    if(RegOpenKeyExA(HKEY_LOCAL_MACHINE, TEXT(key), 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS){

        LONG retcode = RegQueryValueExA(hkey, TEXT(val), 0, &keytype, (unsigned char*)data_name, &size);

        if(retcode == ERROR_SUCCESS){

            RegCloseKey(hkey);

            strcpy(data, (char *)data_name);
            _StrLower(Str);    _StrLower(data);

            size = strlen(Str);
            i = strlen(data);

            while(i >= size){

                if(!strncmp(Str, data, size))
                    return TRUE;
                else{
                    _substr(data);
                    i--;
                }
            }
        }
        if(retcode == ERROR_FILE_NOT_FOUND)
            return FALSE;
    }
    return FALSE;
}


/*    This functions are "translation" of the script "checkvm.rb" ( scripts/meterpreter/checkvm.rb )
*    from metasploit.
*    https://www.metasploit.com/redmine/p...ter/checkvm.rb
*    I just copied the registry keys, values and data, and the process names for checking VM.
*    You can add your own VM programs to the list (QEMU, Parallels, Bochs, ...).
*/

/* check if host is a Hyper-V VM*/
bool hypervchk(void){
    
    unsigned short i;
    char key[][MAX_CHAR] = {
        "SOFTWARE\\Microsoft",
        "SYSTEM\\ControlSet001\\Services"
    };
    char vals[][4][MAX_CHAR] = {
        { "Hyper-V", "VirtualMachine" , "", "" },
        { "vmicheartbeat", "vmicvss", "vmicshutdown", "vmicexchange" }
    };

    for(i=0; i < 2; i++)
        if(query_subkey(key[i], vals[i], 4))
            return TRUE;

    return FALSE;
}


/* check if host is a VMWare VM*/
bool vmwarechk(void){

    char vmwareprocs[][MAX_CHAR/5] = { "vmwareuser.exe", "vmwaretray.exe" };
    unsigned short i;

    for(i=0; i<2; i++)
        if(chk_process(vmwareprocs[i]))
            return TRUE;

    char key[][MAX_CHAR] = {
        "SYSTEM\\ControlSet001\\Services",
        "HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0"
    };

    char vals[][MAX_CHAR] = { "vmdebug", "vmmouse", "VMTools", "VMMEMCTL" };

    if(query_subkey(key[0], vals, 4))
        return TRUE;

    char str[] = "vmware", val[] = "Identifier";
    if(query_val_data(key[1], val, str))
        return TRUE;

    return FALSE;
}


/* check if host is a Virtual PC VM*/
bool checkvrtlpc(void){

    char vpcprocs[][MAX_CHAR/5] = { "vmusrvc.exe", "vmsrvc.exe" };
    unsigned short i;

    for(i=0; i<2; i++)
        if(chk_process(vpcprocs[i]))
            return TRUE;

    char key[] = "SYSTEM\\ControlSet001\\Services";
    char vals[][MAX_CHAR] = { "vpcbus", "vpc-s3", "vpcuhub", "msvmmouf" };
    if(query_subkey(key, vals, 4))
        return TRUE;

    return FALSE;
}


/* check if host is a VirtualBox VM*/
bool vboxchk(void){

    char vboxprocs[][MAX_CHAR/5] = { "vboxservice.exe", "vboxtray.exe" };
    unsigned short i, j;

    char key[][MAX_CHAR] = {
        "HARDWARE\\ACPI\\DSDT",
        "HARDWARE\\ACPI\\FADT",
        "HARDWARE\\ACPI\\RSDT",
        "SYSTEM\\ControlSet001\\Services",
        "HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0",
        "HARDWARE\\DESCRIPTION\\System"
    };

    char vals[][4][MAX_CHAR] = {
        { "VBOX__" , "", "", "" },
        { "VBoxMouse", "VBoxGuest", "VBoxService", "VBoxSF" }
    };

    char val[][MAX_CHAR] = {
        "Identifier",
        "SystemBiosVersion"
    };

    char str[] = "VBOX";

    for(i=0; i < 3; i++){
    if(query_subkey(key[i], vals[0], 4))
        return TRUE;
    }

    if(query_subkey(key[i++], vals[1], 4))
        return TRUE;

    for(j=0; j < 2; j++)
        if(query_val_data(key[i+j], val[j], str))
            return TRUE;

    for(i=0; i<2; i++)
        if(chk_process(vboxprocs[i]))
            return TRUE;

    return FALSE;
}


/* check if host is a Xen VM*/
bool xenchk(void){

    unsigned short i;
    char xenprocs[] = "xenservice.exe";

    if(chk_process(xenprocs))
        return TRUE;

    char key[][MAX_CHAR] = {
        "HARDWARE\\ACPI\\DSDT",
        "HARDWARE\\ACPI\\FADT",
        "HARDWARE\\ACPI\\RSDT",
        "SYSTEM\\ControlSet001\\Services"
    };
    char vals[][5][MAX_CHAR] = {
        { "Xen" , "", "", "", "" },
        { "xenevtchn", "xennet", "xennet6", "xensvc", "xenvdb" }
    };

    for(i=0; i< 3; i++)
        if(query_subkey(key[i], vals[0], 4))
            return TRUE;

    if(query_subkey(key[3], vals[1], 4))
        return TRUE;

    return FALSE;
}

/*    main program, for testing purposes */
int main(void){
    
    if(hypervchk() || xenchk() || checkvrtlpc() || vmwarechk() || vboxchk())
        MessageBoxA(NULL, "Virtual Machine", "Title", MB_OK);
    else    MessageBoxA(NULL, "No Virtual Machine", "Title", MB_OK);
    return 0;


کد:
#include < windows.h >
#include < tlhelp32.h >

typedef int (__cdecl *pPrintf)( const char *, ... );
pPrintf _printf;

char *servicelist[] =
{
    // hyperv
    "vmicheartbeat",
    "vmicvss",
    "vmicshutdown",
    "vmicexchange",
    // vmware
    "vmdebug",
    "vmmouse",
    "VMTools",
    "VMMEMCTL",
    // virtual pc
    "vpcbus",
    "vpc-s3",
    "vpcuhub",
    "msvmmouf",
    // virtualbox
    "VBoxMouse",
    "VBoxGuest",
    "VBoxService",
    "VBoxSF",
    // xen vm
    "xenevtchn",
    "xennet",
    "xennet6",
    "xensvc",
    "xenvdb",
    NULL
};

// msdn code is best code
#define MAX_KEY_LENGTH 255
BOOL KnownServiceExists( void )
{
    HKEY hKey;
    TCHAR achKey[MAX_KEY_LENGTH];
    DWORD i, retCode, cbName, cSubKeys = 0;
    FILETIME ftLastWriteTime;
    int n;

    if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\ControlSet001\\Services", 0, KEY_READ, &hKey) == ERROR_SUCCESS )
    {
        retCode = RegQueryInfoKey( hKey, 0, 0, 0, &cSubKeys, 0, 0, 0, 0, 0, 0, &ftLastWriteTime );

        if ( cSubKeys )
        {
//            _printf( "\n[*] number of services: %d\n", cSubKeys );

            for ( i = 0; i < cSubKeys; i++ )
            {
                cbName = MAX_KEY_LENGTH;
                
                retCode = RegEnumKeyEx(hKey, i, achKey, &cbName, 0, 0, 0, &ftLastWriteTime );

                if ( retCode == ERROR_SUCCESS )
                {
//                    _printf( "(%d) %s\n", i + 1, achKey );
                    for ( n = 0; servicelist[n]; n++ )
                    {
                        if ( !lstrcmpi(servicelist[n], achKey) )
                        {
                            RegCloseKey( hKey );
                            return 1;
                        }
                    }
                }
            }
        }
    }

    RegCloseKey( hKey );
    return 0;
}

// doesn't work on vista 64bit if compiled as 32bit (even running as admin with SE_DEBUG...)
// works on win7x64 though
BOOL KnownProcRunning( void )
{
    PROCESSENTRY32 entry;
    HANDLE snapshot;
    
    entry.dwFlags = sizeof( PROCESSENTRY32 );
    snapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );

    if ( Process32First(snapshot, &entry) )
    {
        while ( Process32Next(snapshot, &entry) )
        {
            _printf( "[*] (pid:%d) %s\n", entry.th32ProcessID, entry.szExeFile );
            // oh well
        }
    }

    CloseHandle( snapshot );
    return 0;
}

int mainCRTStartup( void )
{
    HMODULE msvcrt;

    msvcrt = LoadLibrary( "msvcrt.dll" );
    _printf = (pPrintf)GetProcAddress( msvcrt, "printf" );
    
    if ( !_printf ) ExitProcess( 1 );

    if ( KnownServiceExists() == 1 )
        _printf( "[!] virtual machine detected...\n" );
    else    
        _printf( "[?] no virtual machine detected...\n" );

//    KnownProcRunning();
    ExitProcess( 0 );
}



RE: Virtual Machine Detection - x.kazemi@gmail.com - 06-19-2014

به نامش
سلام دوستان من یکسری اطلاعات در رابطه با انواع روش های شناسایی ماشین مجازی می خوام یعنی کلا یکسری اطلاعات از ابتدا تا جاهای نسبتا مهمی در رابطه با Anti VM ها اگه کسی اطلاعاتی تئوری، عملی و یا هر چیزی داره لطفا به اشتراک بذاره، در ضمن این کد هایی که برای تشخیص اجرا شدن برنامه در ماشین های مجازی مختلف نوشته شده است هم خوبه اما اگه تحلیلی از اینها ارائه بشه خیلی بهتر بدرد میخوره .
ممنون.


RE: Virtual Machine Detection - Amin_Mansouri - 06-20-2014

درود
انواع مدها رو میتونید در بخش زیر ببنیید :
http://parsicoders.com/forumdisplay.php?fid=76