VMXh-Magic-Value

From aldeid
Jump to navigation Jump to search

VMXh Magic Value

  • If we are outside VMware, a privilege error occurs. If we're inside VMware, the magic value (VMXh) is moved to register EBX; otherwise, it is left at 0
  • Based on the version values returned by ECX, we can even determine the specific VMware product
Value of ECX VMware version
1 Express
2 ESX
3 GSX
4 Workstation
MOV   EAX,564D5868   ; 'VMXh'
MOV   EBX,0          ; Any value but not the MAGIC VALUE
MOV   ECX,0A         ; Get VMWare version
MOV   EDX,5658       ; 'VX' (port number)
IN    EAX,DX         ; Read port
CMP   EBX,564D5868   ; Is there a reply from VMWare?

The easiest way to overcome this technique is to NOP-out the in instruction or to patch the conditional jump that follows the test.

0x0A value

C source

void
test5 (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) {}
 
    #if DEBUG == 1
    printf ("\n [ a=%x ; b=%d ]\n\n", a, b);
    #endif
 
    printf ("\n[+] Test 5: VMware \"get version\" command\n");
 
    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  : Native OS\n\n");
}

Assembly

.text:00401290 VMXh_0xA_test   proc near
.text:00401290
.text:00401290 var_20          = dword ptr -20h
.text:00401290 var_1C          = dword ptr -1Ch
.text:00401290 ms_exc          = CPPEH_RECORD ptr -18h
.text:00401290
.text:00401290                 push    ebp
.text:00401291                 mov     ebp, esp
.text:00401293                 push    0FFFFFFFEh
.text:00401295                 push    offset stru_40B390
.text:0040129A                 push    offset __except_handler4
.text:0040129F                 mov     eax, large fs:0
.text:004012A5                 push    eax
.text:004012A6                 add     esp, 0FFFFFFF0h
.text:004012A9                 push    ebx
.text:004012AA                 push    esi
.text:004012AB                 push    edi
.text:004012AC                 mov     eax, ___security_cookie
.text:004012B1                 xor     [ebp+ms_exc.registration.ScopeTable], eax
.text:004012B4                 xor     eax, ebp
.text:004012B6                 push    eax
.text:004012B7                 lea     eax, [ebp+ms_exc.registration]
.text:004012BA                 mov     large fs:0, eax
.text:004012C0                 mov     [ebp+ms_exc.old_esp], esp
.text:004012C3                 mov     [ebp+ms_exc.registration.TryLevel], 0
.text:004012CA                 push    eax
.text:004012CB                 push    ebx
.text:004012CC                 push    ecx
.text:004012CD                 push    edx
.text:004012CE                 mov     eax, 564D5868h
.text:004012D3                 mov     ecx, 0Ah
.text:004012D8                 mov     dx, 5658h
.text:004012DC                 in      eax, dx
.text:004012DD                 mov     [ebp+var_1C], ebx
.text:004012E0                 mov     [ebp+var_20], ecx
.text:004012E3                 pop     edx
.text:004012E4                 pop     ecx
.text:004012E5                 pop     ebx
.text:004012E6                 pop     eax
.text:004012E7                 mov     [ebp+ms_exc.registration.TryLevel], 0FFFFFFFEh
.text:004012EE                 jmp     short loc_401300
.text:004012F0 ; ---------------------------------------------------------------------------
.text:004012F0
.text:004012F0 loc_4012F0:
.text:004012F0                 mov     eax, 1          ; Exception filter 0 for function 401290
.text:004012F5                 retn
.text:004012F6 ; ---------------------------------------------------------------------------
.text:004012F6
.text:004012F6 loc_4012F6:
.text:004012F6                 mov     esp, [ebp+ms_exc.old_esp] ; Exception handler 0 for function 401290
.text:004012F9                 mov     [ebp+ms_exc.registration.TryLevel], 0FFFFFFFEh
.text:00401300
.text:00401300 loc_401300:
.text:00401300                 push    offset aTest5VmwareGet ; "\n[+] Test 5: VMware \"get version\" co"...
.text:00401305                 call    _printf
.text:0040130A                 add     esp, 4
.text:0040130D                 cmp     [ebp+var_1C], 564D5868h
.text:00401314                 jnz     short loc_401386
.text:00401316                 push    offset aResultVmware_3 ; "Result  : VMware detected\nVersion : "
.text:0040131B                 call    _printf
.text:00401320                 add     esp, 4
.text:00401323                 cmp     [ebp+var_20], 1
.text:00401327                 jnz     short loc_401338
.text:00401329                 push    offset aExpress ; "Express\n\n"
.text:0040132E                 call    _printf
.text:00401333                 add     esp, 4
.text:00401336                 jmp     short loc_401384
.text:00401338 ; ---------------------------------------------------------------------------
.text:00401338
.text:00401338 loc_401338:
.text:00401338                 cmp     [ebp+var_20], 2
.text:0040133C                 jnz     short loc_40134D
.text:0040133E                 push    offset aEsx     ; "ESX\n\n"
.text:00401343                 call    _printf
.text:00401348                 add     esp, 4
.text:0040134B                 jmp     short loc_401384
.text:0040134D ; ---------------------------------------------------------------------------
.text:0040134D
.text:0040134D loc_40134D:
.text:0040134D                 cmp     [ebp+var_20], 3
.text:00401351                 jnz     short loc_401362
.text:00401353                 push    offset aGsx     ; "GSX\n\n"
.text:00401358                 call    _printf
.text:0040135D                 add     esp, 4
.text:00401360                 jmp     short loc_401384
.text:00401362 ; ---------------------------------------------------------------------------
.text:00401362
.text:00401362 loc_401362:
.text:00401362                 cmp     [ebp+var_20], 4
.text:00401366                 jnz     short loc_401377
.text:00401368                 push    offset aWorkstation ; "Workstation\n\n"
.text:0040136D                 call    _printf
.text:00401372                 add     esp, 4
.text:00401375                 jmp     short loc_401384
.text:00401377 ; ---------------------------------------------------------------------------
.text:00401377
.text:00401377 loc_401377:
.text:00401377                 push    offset aUnknownVersion ; "unknown version\n\n"
.text:0040137C                 call    _printf
.text:00401381                 add     esp, 4
.text:00401384
.text:00401384 loc_401384:
.text:00401384                 jmp     short loc_401393
.text:00401386 ; ---------------------------------------------------------------------------
.text:00401386
.text:00401386 loc_401386:
.text:00401386                 push    offset aResultNative_3 ; "Result  : Native OS\n\n"
.text:0040138B                 call    _printf
.text:00401390                 add     esp, 4
.text:00401393
.text:00401393 loc_401393:
.text:00401393                 mov     ecx, [ebp+ms_exc.registration.Next]
.text:00401396                 mov     large fs:0, ecx
.text:0040139D                 pop     ecx
.text:0040139E                 pop     edi
.text:0040139F                 pop     esi
.text:004013A0                 pop     ebx
.text:004013A1                 mov     esp, ebp
.text:004013A3                 pop     ebp
.text:004013A4                 retn
.text:004013A4 VMXh_0xA_test   endp

0x14 value

C source

void
test6 (void)
{
    unsigned int    a    = 0;
 
    __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, 14h // get memory size command (0x14)
            mov dx, 'VX' // special VMware I/O port (0x5658)
 
            in eax, dx // special I/O cmd
 
            mov a, eax // data 
 
            // restore register values from the stack
            pop edx
            pop ecx
            pop ebx
            pop eax
        }
    } __except (EXCEPTION_EXECUTE_HANDLER) {}
 
    printf ("\n[+] Test 6: VMware \"get memory size\" command\n");
 
    if (a > 0)
        printf ("Result  : VMware detected\n\n");
    else 
        printf ("Result  : Native OS\n\n");
}

Assembly

.text:004013B0 VMXh_0x14_test  proc near
.text:004013B0
.text:004013B0 var_1C          = dword ptr -1Ch
.text:004013B0 ms_exc          = CPPEH_RECORD ptr -18h
.text:004013B0
.text:004013B0                 push    ebp
.text:004013B1                 mov     ebp, esp
.text:004013B3                 push    0FFFFFFFEh
.text:004013B5                 push    offset stru_40B3B0
.text:004013BA                 push    offset __except_handler4
.text:004013BF                 mov     eax, large fs:0
.text:004013C5                 push    eax
.text:004013C6                 add     esp, 0FFFFFFF4h
.text:004013C9                 push    ebx
.text:004013CA                 push    esi
.text:004013CB                 push    edi
.text:004013CC                 mov     eax, ___security_cookie
.text:004013D1                 xor     [ebp+ms_exc.registration.ScopeTable], eax
.text:004013D4                 xor     eax, ebp
.text:004013D6                 push    eax
.text:004013D7                 lea     eax, [ebp+ms_exc.registration]
.text:004013DA                 mov     large fs:0, eax
.text:004013E0                 mov     [ebp+ms_exc.old_esp], esp
.text:004013E3                 mov     [ebp+var_1C], 0
.text:004013EA                 mov     [ebp+ms_exc.registration.TryLevel], 0
.text:004013F1                 push    eax
.text:004013F2                 push    ebx
.text:004013F3                 push    ecx
.text:004013F4                 push    edx
.text:004013F5                 mov     eax, 564D5868h
.text:004013FA                 mov     ecx, 14h
.text:004013FF                 mov     dx, 5658h
.text:00401403                 in      eax, dx
.text:00401404                 mov     [ebp+var_1C], eax
.text:00401407                 pop     edx
.text:00401408                 pop     ecx
.text:00401409                 pop     ebx
.text:0040140A                 pop     eax
.text:0040140B                 mov     [ebp+ms_exc.registration.TryLevel], 0FFFFFFFEh
.text:00401412                 jmp     short loc_401424
.text:00401414 ; ---------------------------------------------------------------------------
.text:00401414
.text:00401414 loc_401414:
.text:00401414                 mov     eax, 1          ; Exception filter 0 for function 4013B0
.text:00401419                 retn
.text:0040141A ; ---------------------------------------------------------------------------
.text:0040141A
.text:0040141A loc_40141A:
.text:0040141A                 mov     esp, [ebp+ms_exc.old_esp] ; Exception handler 0 for function 4013B0
.text:0040141D                 mov     [ebp+ms_exc.registration.TryLevel], 0FFFFFFFEh
.text:00401424
.text:00401424 loc_401424:
.text:00401424                 push    offset aTest6VmwareGet ; "\n[+] Test 6: VMware \"get memory size\"...
.text:00401429                 call    _printf
.text:0040142E                 add     esp, 4
.text:00401431                 cmp     [ebp+var_1C], 0
.text:00401435                 jbe     short loc_401446
.text:00401437                 push    offset aResultVmware_4 ; "Result  : VMware detected\n\n"
.text:0040143C                 call    _printf
.text:00401441                 add     esp, 4
.text:00401444                 jmp     short loc_401453
.text:00401446 ; ---------------------------------------------------------------------------
.text:00401446
.text:00401446 loc_401446:
.text:00401446                 push    offset aResultNative_4 ; "Result  : Native OS\n\n"
.text:0040144B                 call    _printf
.text:00401450                 add     esp, 4
.text:00401453
.text:00401453 loc_401453:
.text:00401453                 mov     ecx, [ebp+ms_exc.registration.Next]
.text:00401456                 mov     large fs:0, ecx
.text:0040145D                 pop     ecx
.text:0040145E                 pop     edi
.text:0040145F                 pop     esi
.text:00401460                 pop     ebx
.text:00401461                 mov     esp, ebp
.text:00401463                 pop     ebp
.text:00401464                 retn
.text:00401464 VMXh_0x14_test  endp