Hello,

A long time ago I made some deeper analysis at Gynvael's Microsoft VirtualPC 2004 (build 528) Detection, and I found another way of finding out whether the code is running on some VM or not.

The method is based mostly on the previous one, however I was said it's also able to detect Bochs (haven't confirmed it).
It takes advantage of the fact that the real Intel CPU generates two different exceptions during the execution of 16 (EXCEPTION_ACCESS_VIOLATION) and 20 (EXCEPTION_ILLEGAL_INSTRUCTION) byte-long instructions, while VirtualPC and other VM's don't generate any or there is no difference beetwen how virtual machines react on these 2 looong prefixes+opcodes.

I've only tested it on the Microsoft VirtualPC 2007 now, but it worked on almost every VM, at the time of the research itself.
I haven't found this method described anywhere yet, but let me know, if You've seen it before.

PurplePill (some temp name, huh) binary download: http://j00ru.vexillium.org/PurplePill.exe

And here is the Proof of Concept code (masm32 style):


Code:
; Universal (?) Virtual Machine detector =^^=
; masm32 
; research & code by j00ru//vx
; 

.486
.model flat, stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib


.data
  ExpTitle  db 'VM PurplePill - (by j00ru//vx)',0
  ExpON     db 'Virtual Machine detected!',0
  ExpOFF    db 'Virtual Machine NOT detected!',0
  buf       dd 0DEADC0D3h

.code
start:

  ; SEH
  xor eax, eax
  push offset AccViolationSEH
  db 064h ; FS
  push dword ptr [eax]
  db 064h ; FS
  mov dword ptr [eax], esp

  ; 11 * Segment prefix DS: - on real CPU this code causes
  ; Access Violation #GP(0) exception
  db 3eh, 3eh, 3eh, 3eh, 3eh, 3eh, 3eh, 3eh, 3eh, 3eh, 3eh
  mov eax, dword ptr [buf]
  
  ; no exception - detected!
  jmp detected

AccViolationSEH:
  ; real CPU generates Access Violation exception 
  ; other exception - vm detected!
  mov eax, [esp+4]
  cmp dword ptr [eax], EXCEPTION_ACCESS_VIOLATION
  jnz detected

  ; SEH
  xor eax, eax
  push offset IllInstructionSEH
  db 064h ; FS
  push dword ptr [eax]
  db 064h ; FS
  mov dword ptr [eax], esp

  ; 15 * Segment prefix DS: on real CPU this code causes
  ; Illegal Instruction #UD exception
  db 3eh, 3eh, 3eh, 3eh, 3eh, 3eh, 3eh, 3eh, 3eh, 3eh, 3eh, 3eh, 3eh, 3eh, 3eh
  mov eax, dword ptr [buf]

  ; no exception - vm detected!
  jmp detected

IllInstructionSEH:
  ; real CPU generates Illegal Instruction exception
  ; other exception - vm detected!
  mov eax, [esp+4]
  cmp dword ptr [eax], EXCEPTION_ILLEGAL_INSTRUCTION
  jnz detected
  
  ; no virtual machine detected
  invoke MessageBoxA, 0, offset ExpOFF, offset ExpTitle, MB_ICONINFORMATION
  jmp exit 

detected:
  invoke MessageBoxA, 0, offset ExpON, offset ExpTitle, MB_ICONERROR
  jmp exit

exit:
  invoke ExitProcess, 0
    
end start

https://www.openrce.org/blog/view/1025/Old_new_Virtual_Machine_detection_method.