Announcement

Collapse

Forum Guidelines

This forum is for finished source code that is working properly. If you have questions about this or any other source code, please post it in one of the Discussion Forums, not here.
See more
See less

Detect if running under VMWare

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Detect if running under VMWare

    vmware is an excellent program that allows you to run multiple operating systems on the same computer concurrently. sometimes it's useful to know if you're running under a real os or in this 'emulated' operating system state, and there is a test you can use to determine this. however, if the test fails (if vmware isn't there), the test will crash your program, but that little problem is easily overcome with a structured exception handler, and i've used a modified version of florent heyworth's excellent <a href="http://"http://g]http://www.powerbasic.com/support/forums/smile.gif[/img]

    Code:
    #compile exe
    #register none
    #include "win32api.inc"
     
    type seh
         dwprevlink as dword
         dwcurrenthandler as dword
         dwsafeoffset as dword
         dwprevesp as dword
         dwprevebp as dword
    end type
     
    function seh_handler cdecl( ptexcept as exception_record ptr, ptframe as seh ptr, ptcontext as context ptr, byval pdwdispatch as dword) as long
       @ptcontext.regeip = @ptcontext.regeip + 13  '// set eip to a known safe offset
    end function
     
    function vmwaredetect() as long
       #register none
       function = 0
       local lebp as long, lesp as long, tseh as seh
       '// setup the seh.
       ! push dword fs:[0]
       tseh.dwcurrenthandler = codeptr(seh_handler)
       tseh.dwsafeoffset = codeptr(except)
       ! lea esi, tseh
       ! mov fs:[0], esi
       ! mov lesp, esp
       ! mov lebp, ebp
       tseh.dwprevesp = lesp
       tseh.dwprevebp = lebp
       '// call the vmware backdoor to see if its there.
       '// if its not there, our seh will save us from crashing.
       ! mov ecx, &h0a
       ! mov      eax, "vmxh"
       ! mov      dx,  "vx"
       ! in       eax, dx
       ! cmp      ebx, "vmxh"
       ! je       vmwarefound
       ! jmp      except
    vmwarefound:
      function = 1
    except:
    ! pop dword fs:[0]
    end function
     
    function pbmain() as long
    if vmwaredetect = 1 then
       '// vmware detected
    else
       '// not detected
    end if
    end function

    ------------------
    the powerbasic crypto archives - my email - protection scheme testing - what's mine is yours...

    [this message has been edited by wayne diamond (edited september 05, 2003).]
    -

  • #2
    Here's a link with more info on what kind of info can be retrieved:
    http://chitchat.at.infoseek.co.jp/vmware/

    ------------------
    Balt
    bi at inside dot net
    "It's not the end, not even the beginning of the end, but, it might be the end of the beginning!"

    Comment


    • #3
      Here is a more generic method that uses the RDTSC counter instruction.

      It's not quite as reliable as the VM-specific methods like the one I posted above as it essentially counts the time taken to execute two instructions, but has the advantage of being able to generically detect if it's running inside any VM, so it can detect VMWare, Virtual PC, and others.

      Code:
      #COMPILE EXE
       
      FUNCTION InsideVM() AS LONG '// Returns 1 if running inside a VM
       try_again:
          ! db &h0F,&h31    ; rdtsc
          ! mov ebx, eax
          ! db &h0F,&h31    ; rdtsc
          ! sub eax, ebx
          ! push eax
          ! cmp eax, 1
          ! jz try_again
          ! pop eax
          ! cmp eax, &h0200
          ! jb no_vm
          ! mov eax, 1
          ! jmp finish
       no_vm:
          ! mov eax, 0
       finish:
      ! mov FUNCTION, eax
      END FUNCTION
       
      FUNCTION PBMAIN() AS LONG
       MSGBOX "InsideVM = " & STR$(InsideVM)
      END FUNCTION
      -

      Comment


      • #4
        great code and info there wayne thanks! i use a similar method with inline ASM in VB with the ThunderVB add-in i tryed to port it to powerbasic but it doesnt support SIDT... ill post the VB code anyway..

        Code:
        Function IsVMware() As Long
        '#asm' LOCAL opIDT:FWORD
        '#asm'             pushad
        '#asm' lea eax, opIDT
        '#asm' SIDT FWORD ptr [eax]
        '#asm' Add eax, 2
        '#asm' .if dword ptr [eax] <= 0F0000000h
        '#asm'     .if dword ptr [eax] >= 0D0000000h
        '#asm'         popad
        '#asm'         mov eax, -2
        '#asm'         ret
        '#asm'     .endif
        '#asm' .elseif dword ptr [eax] > 0FF000000h
        '#asm'     popad
        '#asm'     mov eax, -1
        '#asm'     ret
        '#asm' .endif
        '#asm' popad
        '#asm' xor eax, eax
        '#asm' ret
        End Function

        Comment


        • #5
          I've used this code quite successfully for a long time now, see sample code below, to provide a way of determining if a server is virtual or not.

          However on a VMware Windows Server 2008 R2 Standard server it comes back as not virtual.

          Its a Intel Xeon CPU 2.66GHz with the 64bit OS.

          There may need to be a small adjustment made to the ASM to cater for 64bit systems , anyone come across this before?

          Code:
          #COMPILE EXE
          #DIM ALL
          
          FUNCTION PBMAIN () AS LONG
          
            STDOUT STR$(funIsVirtual)
            WAITKEY$
          
          END FUNCTION
          
          FUNCTION funIsVirtual() AS LONG
          ' Function to return whether or not the server is virtual
          '
          try_again:
              ! db &h0F,&h31    ; rdtsc
              ! mov ebx, eax
              ! db &h0F,&h31    ; rdtsc
              ! SUB eax, ebx
              ! push eax
              ! cmp eax, 1
              ! jz try_again
              ! pop eax
              ! cmp eax, &h0200
              ! jb no_vm
              ! mov eax, 1
              ! jmp finish
          no_vm:
              ! mov eax, 0
          finish:
              ! mov FUNCTION, eax
          END FUNCTION

          Comment

          Working...
          X