Jump to content

Detect running in Virtual Machine


Stilez
 Share

Recommended Posts

In case it's useful to anyone, this code works well for me and it's resilient against non-VM systems which have some virtual devices.

Unlike most code I've seen, it only reports a VM if it finds VM hardware in 2 or more different categories out of software (VM service processes), disk drives, BIOS ID and motherboard ID. So systems with virtual hard drive or an accidental match on some criterion are unlikely to trigger it by mistake.

Uses code by fennek (link)

At present it returns a string - empty "" if not a VM, or a description of its diagnostic reasoning if it decides we're in a VM. Easy to fix if you want classic 0 1 or @error returns.

$a = _CheckVM()

if $a = "" Then
    MsgBox(0, "I'm not in a VM", "Done!")
Else
    MsgBox(0, "I'm in a VM!", "My reason is" & @CRLF & @CRLF & $a)
EndIf



; Checks if we're in a VM. Returns "" if we aren't, or a string containing the diagnostic explanation if we are.

; Uses code by fennek, extra logic by Stilez
; www.secret-zone.net/showthread.php?3143-Detect-Vmware-VirtualBox-VirtualP-Autoit

; Method: Checks for VM services/processes, hard drives, bios ID and motherboard ID
; Reports a VM only if hardware in * 2 or more different categories * are found
; Note - reason is, non-VMs might use virtual hardware or have the word "virtual" in some description

Func _CheckVM()
   $strComputer = '.'
   $objWMIService = ObjGet('winmgmts:\\' & $strComputer & '\root\cimv2')
   $vmhit_count = 0
   $vmhit_details = ""

   ; Check for VM management processes
   If ProcessExists("VBoxService.exe") Or ProcessExists("VBoxTray.exe") Or ProcessExists("VMwareTray.exe") Or ProcessExists("VMwareUser.exe")  Then _AddVMHit($vmhit_count, $vmhit_details, "RUNNING SOFTWARE", "Found a Vbox or VMware guest OS service or tray process")
 
   ; Check for VM devices
   If Not IsObj($objWMIService) Then
      msgbox(0,"","? WTF?")
      return ""
   EndIf
   
   ; Check for VM hard disks
   $colItems = $objWMIService.ExecQuery('SELECT * FROM Win32_DiskDrive', 'WQL', 0x10 + 0x20)
   If IsObj($colItems) Then
      For $objItem In $colItems
         $vReturn = $objItem.Model
         Select
            Case StringInStr($vReturn,"VBOX HARDDISK") 
               _AddVMHit($vmhit_count, $vmhit_details, "DISKS", "Found device ""VBOX HARDDISK""")
            Case StringInStr($vReturn,"QEMU HARDDISK") 
               _AddVMHit($vmhit_count, $vmhit_details, "DISKS", "Found device ""QEMU HARDDISK""")
            Case StringInStr($vReturn,"VMWARE VIRTUAL IDE HARD DRIVE") 
               _AddVMHit($vmhit_count, $vmhit_details, "DISKS", "Found device ""VMWARE VIRTUAL IDE HARD DRIVE""")
            Case StringInStr($vReturn,"VMware Virtual S SCSI Disk Device") 
               _AddVMHit($vmhit_count, $vmhit_details, "DISKS", "Found device ""VMware Virtual S SCSI Disk Device""")
         EndSelect
      Next
   EndIf
 
   ; Check for VM BIOS
   $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_BIOS", "WQL", 0x10 + 0x20)
   If IsObj($colItems) Then
         For $objItem In $colItems
            Select
               Case StringInStr($objItem.BIOSVersion(0),"Vbox") 
                  _AddVMHit($vmhit_count, $vmhit_details, "BIOS", "Found Vbox BIOS version")
               Case StringInStr($objItem.SMBIOSBIOSVersion,"virt") 
                  _AddVMHit($vmhit_count, $vmhit_details, "BIOS", "Found Vbox BIOS version")
            EndSelect
         Next
   EndIf

   ; Check for VM Motherboard/chipset
    $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_Baseboard", "WQL", 0x10 + 0x20)
   If IsObj($colItems) Then
      For $objItem In $colItems
         Select
            Case StringInStr($objItem.Name,"Base Board") And StringInStr($objItem.Product, "440BX Desktop Reference Platform") 
               _AddVMHit($vmhit_count, $vmhit_details, "MOTHERBOARD", "Found VMware-style motherboard, ""440BX Desktop Reference Platform"" / Name=""Base Board""")
         EndSelect
      Next
   EndIf
 
   If $vmhit_count >= 2 Then
      Return $vmhit_details & @CRLF & @CRLF & "Hits in " & $vmhit_count & " of 4 hardware categories - probably a virtual machine."
   Else
      Return ""
   EndIf
   
EndFunc   ;==>_CheckVM


Func _AddVMHit(ByRef $vmhit_count, ByRef $vmhit_details, $this_hit_category, $this_hit_text)
   If StringInStr($vmhit_details, "In CATEGORY:" & $this_hit_category & ":") Then
      ; Already logged a hit in this category, just note the extra hit
      $vmhit_details &= " and " & $this_hit_text
   Else
      ; Category not logged yet - add it and the hit
      if $vmhit_details > "" Then $vmhit_details &= @CRLF
      $vmhit_details &= "In CATEGORY:" & $this_hit_category & ": " & $this_hit_text
      $vmhit_count += 1
   EndIf
EndFunc   ;==>_AddVMHit

If anyone knows what to do when ObjGet('winmgmts:\\.\root\cimv2') isn't an object, please say!

Also any other VM hardware identifiers - please add them to this thread :mellow:

Edited by Stilez
Link to comment
Share on other sites

You could use some more error checking; e.g. Win2k crashes with

C:\Documents and Settings\Administrator\Desktop\Detect running in Virtual Machine.au3 (58) : ==> The requested action with this object has failed.:
Case StringInStr($objItem.BIOSVersion(0),"Vbox")
Case StringInStr($objItem.BIOSVersion(0)^ ERROR

VMware Workstation 7.1.2/AutoIt 3.3.0.0 (I know it's old but should not matter here I think)

Edited by AdmiralAlkex
Link to comment
Share on other sites

You could use some more error checking; e.g. Win2k crashes with

C:\Documents and Settings\Administrator\Desktop\Detect running in Virtual Machine.au3 (58) : ==> The requested action with this object has failed.:
Case StringInStr($objItem.BIOSVersion(0),"Vbox")
Case StringInStr($objItem.BIOSVersion(0)^ ERROR
VMware Workstation 7.1.2/AutoIt 3.3.0.0 (I know it's old but should not matter here I think)

Thanks! I agree, I haven't checked the code on old or unusual platforms, or even other platforms that are current. I'm not sure what is best practice here, if I were expected to check code against other platforms (which I don't own copies of) I'd never get round to releasing code publicly, as I mainly write it for my own use. I don't have win2k so I'm glad you spotted it. Presumably some versions don't include the property BIOSVersion(0)? If you can suggest amended code below, that would be great, and if there's a better way to present code when it's useful but not tested on many platforms, let me know :mellow:

(In this case the only reason this code exists is, I want my win7 install to automatically switch to the highest valid resolution post-install. That depends whether it's in a VM or not, which means reliably detecting VM running. I wasn't happy that existing VM detection code would do this reliably for my future Win7 installs, for example if the user has a VHD some code assumes the system is on a VM. So this code got written to detect better. It's probably useful for others, and helpful to people who are "in my shoes", but I'm sure it can be refined. Best practice? Dunno :) )

Edited by Stilez
Link to comment
Share on other sites

  • 4 weeks later...

That script you have there is a slightly modified version of the original script posted at fenneks forum, somebody just sort of added a nifty reporting function.

I had replied to him with the functions that check for bios from a udf around here, he had made the VM part, that was back when I thought checking it that way was special, then I noticed its better to just do this.

If _IsInVBox() Then _
MsgBox(64,"","I'm in a VBox")

Func _IsInVBox()
If StringInStr(RegRead("HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System","SystemBiosVersion"),"VBOX")Then _
Return True
Return False
EndFunc

and avoid any errors.

Link to comment
Share on other sites

I'm running Microsoft Virtual PC and my SystemBiosVersion is :

A M I - 2000622

BIOS Date: 02/22/06 20:54:49 Ver: 08.00.02

BIOS Date: 02/22/06 20:54:49 Ver: 08.00.02

I have to thank you man, you don't know how long I've been trying to get the information you posted, I asked at fenneks forum but its just so damn slow, thanks to your post I've been able to make this after a google search.

Opt("MustDeclareVars", 1)
;Converted from VBS script found @ below address...
;http://blogs.technet.com/b/tonyso/archive/2010/05/13/how-to-tell-if-you-are-in-a-vm-using-script.aspx
;THAT1ANONYMOUSEDUDE Marlboroloco@gmail.com
 
If _VCheck() Then
MsgBox(0, "", "True")
Else
MsgBox(0, "", "False")
EndIf
 
Func _VCheck()
Local $strComputer = ".", $sMake, $sModel, $sBIOSVersion, $bIsVM, $sVMPlatform
Local $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
Local $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_ComputerSystem")
If IsObj($colItems) Then
For $objItem In $colItems
;MsgBox(0,"","Name: " & $objItem.Name)
$sMake = $objItem.Manufacturer
$sModel = $objItem.Model
Next
EndIf
 
$colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_BIOS", "WQL", 0x10 + 0x20)
If IsObj($colItems) Then
For $objItem In $colItems
;MsgBox(0,"",$objItem.BIOSVersion(0))
$sBIOSVersion = $objItem.SMBIOSBIOSVersion
Next
EndIf
 
$bIsVM = False
$sVMPlatform = ""
 
MsgBox(0, "", "Manufacturer=" & $sMake)
MsgBox(0, "", "Model=" & $sModel)
MsgBox(0, "", "BIOSVersion=" & $sBIOSVersion)
If $sModel = "Virtual Machine" Then
; Microsoft virtualization technology detected, assign defaults
$sVMPlatform = "Hyper-V"
$bIsVM = True
; Try to determine more specific values
Switch $sBIOSVersion
Case "VRTUAL - 1000831"
$bIsVM = True
$sVMPlatform = "Hyper-V 2008 Beta or RC0"
Case "VRTUAL - 5000805", "BIOS Date: 05/05/08 20:35:56  Ver: 08.00.02"
$bIsVM = True
$sVMPlatform = "Hyper-V 2008 RTM"
Case "VRTUAL - 3000919"
$bIsVM = True
$sVMPlatform = "Hyper-V 2008 R2"
Case "A M I  - 2000622"
$bIsVM = True
$sVMPlatform = "VS2005R2SP1 or VPC2007"
Case "A M I  - 9000520"
$bIsVM = True
$sVMPlatform = "VS2005R2"
Case "A M I  - 9000816", "A M I  - 6000901"
$bIsVM = True
$sVMPlatform = "Windows Virtual PC"
Case "A M I  - 8000314"
$bIsVM = True
$sVMPlatform = "VS2005 or VPC2004"
EndSwitch
ElseIf $sModel = "VMware Virtual Platform" Then
; VMware detected
$sVMPlatform = "VMware"
$bIsVM = True
ElseIf $sModel = "VirtualBox" Then
; VirtualBox detected
$bIsVM = True
$sVMPlatform = "VirtualBox"
Else
; This computer does not appear to be a virtual machine.
EndIf
; Set the return value
If $bIsVM Then
MsgBox(0, "", "IsVirtualMachine=True")
MsgBox(0, "", "VirtualMachinePlatform=" & $sVMPlatform)
Else
MsgBox(0, "", "IsVirtualMachine=False")
EndIf
Return $bIsVM
EndFunc   ;==>_VCheck

Now all you have to do is mold it to your needs.

Edited by THAT1ANONYMOUSEDUDE
Link to comment
Share on other sites

This is how I did it >> idea was from UEZ!

UDF List:

 
_AdapterConnections() • _AlwaysRun() • _AppMon() • _AppMonEx() • _ArrayFilter/_ArrayReduce • _BinaryBin() • _CheckMsgBox() • _CmdLineRaw() • _ContextMenu() • _ConvertLHWebColor()/_ConvertSHWebColor() • _DesktopDimensions() • _DisplayPassword() • _DotNet_Load()/_DotNet_Unload() • _Fibonacci() • _FileCompare() • _FileCompareContents() • _FileNameByHandle() • _FilePrefix/SRE() • _FindInFile() • _GetBackgroundColor()/_SetBackgroundColor() • _GetConrolID() • _GetCtrlClass() • _GetDirectoryFormat() • _GetDriveMediaType() • _GetFilename()/_GetFilenameExt() • _GetHardwareID() • _GetIP() • _GetIP_Country() • _GetOSLanguage() • _GetSavedSource() • _GetStringSize() • _GetSystemPaths() • _GetURLImage() • _GIFImage() • _GoogleWeather() • _GUICtrlCreateGroup() • _GUICtrlListBox_CreateArray() • _GUICtrlListView_CreateArray() • _GUICtrlListView_SaveCSV() • _GUICtrlListView_SaveHTML() • _GUICtrlListView_SaveTxt() • _GUICtrlListView_SaveXML() • _GUICtrlMenu_Recent() • _GUICtrlMenu_SetItemImage() • _GUICtrlTreeView_CreateArray() • _GUIDisable() • _GUIImageList_SetIconFromHandle() • _GUIRegisterMsg() • _GUISetIcon() • _Icon_Clear()/_Icon_Set() • _IdleTime() • _InetGet() • _InetGetGUI() • _InetGetProgress() • _IPDetails() • _IsFileOlder() • _IsGUID() • _IsHex() • _IsPalindrome() • _IsRegKey() • _IsStringRegExp() • _IsSystemDrive() • _IsUPX() • _IsValidType() • _IsWebColor() • _Language() • _Log() • _MicrosoftInternetConnectivity() • _MSDNDataType() • _PathFull/GetRelative/Split() • _PathSplitEx() • _PrintFromArray() • _ProgressSetMarquee() • _ReDim() • _RockPaperScissors()/_RockPaperScissorsLizardSpock() • _ScrollingCredits • _SelfDelete() • _SelfRename() • _SelfUpdate() • _SendTo() • _ShellAll() • _ShellFile() • _ShellFolder() • _SingletonHWID() • _SingletonPID() • _Startup() • _StringCompact() • _StringIsValid() • _StringRegExpMetaCharacters() • _StringReplaceWholeWord() • _StringStripChars() • _Temperature() • _TrialPeriod() • _UKToUSDate()/_USToUKDate() • _WinAPI_Create_CTL_CODE() • _WinAPI_CreateGUID() • _WMIDateStringToDate()/_DateToWMIDateString() • Au3 script parsing • AutoIt Search • AutoIt3 Portable • AutoIt3WrapperToPragma • AutoItWinGetTitle()/AutoItWinSetTitle() • Coding • DirToHTML5 • FileInstallr • FileReadLastChars() • GeoIP database • GUI - Only Close Button • GUI Examples • GUICtrlDeleteImage() • GUICtrlGetBkColor() • GUICtrlGetStyle() • GUIEvents • GUIGetBkColor() • Int_Parse() & Int_TryParse() • IsISBN() • LockFile() • Mapping CtrlIDs • OOP in AutoIt • ParseHeadersToSciTE() • PasswordValid • PasteBin • Posts Per Day • PreExpand • Protect Globals • Queue() • Resource Update • ResourcesEx • SciTE Jump • Settings INI • SHELLHOOK • Shunting-Yard • Signature Creator • Stack() • Stopwatch() • StringAddLF()/StringStripLF() • StringEOLToCRLF() • VSCROLL • WM_COPYDATA • More Examples...

Updated: 22/04/2018

Link to comment
Share on other sites

  • 2 weeks later...
  • 10 months later...

i just use the motherboard valu in BIOS to find out if machine is virtuall all my virtual machines report "440BX Desktop Reference Platform".

I notice by accident. :)

Edited by lgvlgv
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...