deroko

VMware ring3 detection (RF handling)

Rating: 2 votes, 2.00 average.
Hello,

Here is one trick to detect vmware discovered by accidance

I was writing one unpacker, and for me RF was must have to make my unpacker simpler. Unpacker worked great on live system, and then I tried it in vmware, and I got many breaks at same part of the code which should be continued with RF.

RF from intel manual volume 3, chapter 18:

Code:
Because the debug exception for an instruction breakpoint is generated before the
instruction is executed, if the instruction breakpoint is not removed by the exception
handler; the processor will detect the instruction breakpoint again when the instruction
is restarted and generate another debug exception. To prevent looping on an
instruction breakpoint, the Intel 64 and IA-32 architectures provide the RF flag
(resume flag) in the EFLAGS register (see Section 2.3, “System Flags and Fields in
the EFLAGS Register,” in the Intel® 64 and IA-32 Architectures Software Developer’s
Manual, Volume 3A). When the RF flag is set, the processor ignores instruction
breakpoints.
Basically waht debugger would do with break point is:
- breakpoint reached -> clear breakpoint
- single step that instruction
- set breakpoint after singlestep
- continue execution
- too much not needed work...

For DebugRegister breaks on execution, you can simplfy this by setting RF in Eflags, and you don't have to remove your breakpoint on execution.

So here is how to detect VMWare presence using debug registers due to wrong RF handling:

Code allocates memory and stores there 0xC3, after that program generates exception to set debug registers. In exception handler code checks if exception occured 1st time (1st debug break) and sets RF (eg. continue execution), after that if exception occurs 2nd time, means that RF wasn't handled and that we have vmware (didn't try with other virtual machines).

main.c
Code:
#include        "defs.h"

PVOID   buffer;
DWORD   dwExceptionCount;

ULONG   filter(PEXCEPTION_INFO pei){
        PCONTEXT pctx;
        
        pctx = pei->pContext;
        if (dwExceptionCount == 0){
                dwExceptionCount++;
                pctx->Dr7 = BPM_LOCAL_EXACT | BPM0_LOCAL_ENABLED;
                pctx->Dr0 = (DWORD)buffer;
                pctx->Eip += 2;
                NtContinue(pctx, FALSE);
        }else if (dwExceptionCount == 1){
                dwExceptionCount++;
                pctx->EFlags |= 0x10000;
                NtContinue(pctx, FALSE);
        }else if (dwExceptionCount == 2){
                printf("[X] vmware detected\n");
                ExitProcess(0);
        }
        
        return EXCEPTION_EXECUTE_HANDLER;        
}

void __declspec(naked) hook_filter(void){
        __asm push      esp
        __asm call      filter
}

int __cdecl wmain(int argc, wchar_t **argv){
        VOID    (*func)();
        DWORD   dwOldProt;
        PUCHAR  kiuser;
        printf("[*] ring3 VMWARE detection - (c) 2009 deroko of ARTeam\n");
        kiuser = (PUCHAR)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "KiUserExceptionDispatcher");
        
        VirtualProtect(kiuser, 7, PAGE_EXECUTE_READWRITE, &dwOldProt);
        kiuser[0] = 0x68;
        *(DWORD *)&kiuser[1] = (DWORD)hook_filter;
        kiuser[5] = 0xc3;
                    
        buffer = func = VirtualAlloc(0, 0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
        *(DWORD *)func = 0xC3909090;
        
        __asm xor eax, eax
        __asm mov eax, [eax]
        func();
        
        printf("[*] vmware not detected\n");
        ExitProcess(0);
}

defs.h
Code:
 
#include        <windows.h>
#include        <stdio.h>

// Dr6
#define BPM0_DETECTED                    0x00000001
#define BPM1_DETECTED                    0x00000002
#define BPM2_DETECTED                    0x00000004
#define BPM3_DETECTED                    0x00000008

// Dr7
#define BPM0_LOCAL_ENABLED               0x00000001
#define BPM0_W                           0x00010000
#define BPM0_RW                          0x00030000

#define BPM1_LOCAL_ENABLED               0x00000004
#define BPM1_W                           0x00100000
#define BPM1_RW                          0x00300000

#define BPM2_LOCAL_ENABLED               0x00000010
#define BPM2_W                           0x01000000
#define BPM2_RW                          0x03000000

#define BPM3_LOCAL_ENABLED               0x00000040
#define BPM3_W                           0x10000000
#define BPM3_RW                          0x30000000

#define BPM_LOCAL_EXACT                  0x00000100

typedef LONG NTSTATUS;

NTSTATUS
NTAPI
NtContinue(__in PCONTEXT ctx, BOOL Alertalbe);

typedef struct{
	PULONG ExceptionCodeAddress;
	PCONTEXT   pContext;
	ULONG  ExceptionCode;
	ULONG  ExceptionFlags;
	PULONG ExceptionRecord;
	ULONG  ExceptionAddress;
	ULONG  NumberOfParameters;
	ULONG  ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
}EXCEPTION_INFO, *PEXCEPTION_INFO;

output of the program running in vmware:
Code:
[*] ring3 VMWARE detection - (c) 2009 deroko of ARTeam
[X] vmware detected
output of the program running on live system:

Code:
[*] ring3 VMWARE detection - (c) 2009 deroko of ARTeam
[*] vmware not detected

Hope you find it usefull

Submit "VMware ring3 detection (RF handling)" to Digg Submit "VMware ring3 detection (RF handling)" to del.icio.us Submit "VMware ring3 detection (RF handling)" to StumbleUpon Submit "VMware ring3 detection (RF handling)" to Google

Categories
Uncategorized

Comments