deroko
August 9th, 2009, 11:17
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:
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
defs.h
output of the program running in vmware:
output of the program running on live system:
Hope you find it usefull
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
