检测程序是否在虚拟机运行的两种方法


      最近在项目中遇到一个虚拟机检测的问题,需要检测当前程序是否在虚拟机中运行

     刚遇到这个问题时感觉就是一头雾水,一脸懵逼的有没有?咱又不是开发虚拟机的不是,怎么知道要怎么检测是不是虚拟机呢?何况现在主流的虚拟机有好几个,有没有通用的方法呢?相信很多朋友也会有同样的问题。但可以肯定的是,既然是虚拟机,肯定有和物理机不一样的东西,只要找到这些不一样的固有属性,用程序加以判断,肯定有可以检测出来。那么具体有些什么区别?又该如何检测呢?充分利用互联网的优势,先百度谷歌再说。

      不查不知道,一查吓一跳,看来遇到这个问题的人还是挺多的。发现比较好的博文都是在CSND上有木有?这里要好好感谢一下CSDN,不但有各种高水平技术贴,据说还可以用来做SEO的有木有啊?不过现在CSDN可不允许你随便做SEO了,人家要审核你的文章了,这也真是烦人,好不容易晚上有时间来发个文章,写完以后要等到第二天人工审核才能过,你说这心都凉了半截有木有?。

        言规正这里经过本人的一一查看和总结,发现比较可行的方法就是某位大牛总结的几种方法。这里就不多解释了,直接上链接,感兴趣的同学可以自己去了解一下:http://blog.csdn.net/whatday/article/details/10393325,这里介绍了7种方法,都有代码,同时还有反检测。我没有一一测试,需要的同学可在实践测试一下,我直接采用了第一种方法,并且找到了第一种方法的完整原码。只需要调用IsVirtualMachine即可判断是否是虚拟机中,是不是很方便呢有木有?  原码的下载地址:https://www.codeproject.com/Articles/9823/Detect-if-your-program-is-running-inside-a-Virtual

    上面的方法可以检测出 Vmware 和 virtualPC,但是没有告诉我们怎么检测XGenServer 虚拟机。如果要检测XGenServer呢要怎么办?

继续百度谷歌,结果关于这个虚拟机检测的方法,反正我是没有在网上找了半天没有发现,心凉了半截有木有?好吧,没有就自己想办法了,这里我想到的办法是获取硬件信息了,虚拟机的硬件都是虚拟出来的,比如网卡,磁盘啊。首先验证一下这个方法有没有效啊。查硬件信息用设备管理器。如下图所示:

果然有亮点。再来一个:msinfo32看看:


   海阔天空啊,就你了。经验证VMWARE 上也一样有亮点哦, 这里不贴图了。大家自己去看下就知道了,都是VMware开头的。接下来就是获取这些信息了,这个用WMI就可以获取到这里贴上获取信息的源码供大家使用:

扫描二维码关注公众号,回复: 3792924 查看本文章


TClient.h

#pragma once
#include<atlbase.h>
#include<objbase.h>
#include<WbemIdl.h>
#include<WbemCli.h>
#include<comdef.h>

#pragma comment(lib,"wbemuuid.lib")
#pragma comment(lib,"ole32.lib")

#define DEF_MAX_WBEMOBJ 20
#define DEF_MAX_PATH    260

class TClientDMI
{
public:
	TClientDMI();
	~TClientDMI();
public:
	CString  getDMIInformation(TCHAR *pWin32_ClassName, TCHAR *pUniqueCaption,TCHAR *pUniqueValue, TCHAR *pTargetCaption);

private:
	HRESULT  _initDMI();
private:
	BSTR     m_strNameSpace;
	BOOL     m_blDMIInit;           //DMI init flag
private:
	IWbemLocator*           m_pIWbemLocator;
	IWbemServices*          m_pIWbemServices;
	IEnumWbemClassObject*   m_pIEnumWbem;
	IWbemClassObject*       m_szIWbemObject[DEF_MAX_WBEMOBJ];
	BSTR                    m_strClassName;

};

TClient.cpp

#include "stdafx.h"
#include "TClientDMI.h"

TClientDMI::TClientDMI()
{  
	m_blDMIInit = FALSE;
	m_strNameSpace  = NULL;
	m_pIWbemLocator = NULL;
	m_pIWbemServices= NULL;
	m_pIEnumWbem    = NULL;
	m_strClassName  = NULL;

	for (int i=0;i<DEF_MAX_WBEMOBJ;i++)
	{
		m_szIWbemObject[i] = NULL;  
	}

}  
TClientDMI::~TClientDMI()
{
	if (m_pIEnumWbem != NULL)
	{ 
		m_pIEnumWbem->Release();
		m_pIEnumWbem = NULL;
	}

	if (m_strClassName != NULL)
	{
		SysFreeString(m_strClassName);
		m_strClassName = NULL;
	}

	if (m_strNameSpace != NULL)
	{
		SysFreeString(m_strNameSpace);
		m_strNameSpace = NULL;
	}

	if (m_pIWbemServices != NULL)
	{
		m_pIWbemServices->Release();
		m_pIWbemServices = NULL;
	}

	if (m_pIWbemLocator != NULL)
	{
		m_pIWbemLocator->Release();
		m_pIWbemLocator = NULL;
	}
	CoUninitialize();

}  
//////////////////////////////////////////////////////////////////////////  
//    
//          init DMI interface  
//  
//////////////////////////////////////////////////////////////////////////  


HRESULT TClientDMI::_initDMI()
{  
	HRESULT hr = CoInitializeEx(0, COINIT_MULTITHREADED);
	if (FAILED(hr))
	{
		return hr;
	}
	hr = CoInitializeSecurity(NULL, -1, NULL, NULL,
		RPC_C_AUTHN_LEVEL_DEFAULT,
		RPC_C_IMP_LEVEL_IMPERSONATE,
		NULL, EOAC_SECURE_REFS, NULL); 
	if (FAILED(hr))
	{
		return hr;
	}
	hr = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER,
		IID_IWbemLocator, (LPVOID*)&m_pIWbemLocator);
	if (FAILED(hr))
	{
		return hr;
	}
	m_strNameSpace = SysAllocString(_T("\\\\.\\root\\cimv2"));
	hr = m_pIWbemLocator->ConnectServer(m_strNameSpace, NULL, NULL, 0L, 0L, NULL, NULL, &m_pIWbemServices);
	if (FAILED(hr))
	{
		return hr;
	}
	m_blDMIInit = TRUE;
	return hr;
}

//////////////////////////////////////////////////////////////////////////  
//              common query process  
//step1. Init DMI interface  
//step2. Get ClassInformation  
//step3. Get Instance  
//step4. Get the property of Instance  
//////////////////////////////////////////////////////////////////////////  

CString TClientDMI::getDMIInformation(TCHAR *pWin32_ClassName, TCHAR *pUniqueCaption, TCHAR *pUniqueValue, TCHAR *pTargetCaption)
{
	CString strRet = _T("");
	//  TCHAR szTarget[MAX_PATH] = { 0 };
	HRESULT hr = S_OK;
	if (!m_blDMIInit)
	{
		hr= _initDMI();
	}
	if (SUCCEEDED(hr))
	{  
		VARIANT var;
		ULONG uReturned;
		HRESULT hr;
		VariantInit(&var);

		m_pIEnumWbem = NULL;
		m_strClassName = NULL;
		m_strClassName = SysAllocString(pWin32_ClassName);

		if (!m_strClassName)
		{
			return strRet;
		}
		hr = m_pIWbemServices->CreateInstanceEnum(m_strClassName, 0, NULL, &m_pIEnumWbem);  

		if (FAILED(hr))
		{
			return strRet;
		}
		
		uReturned = 1;
		hr = m_pIEnumWbem->Next(2000 * DEF_MAX_WBEMOBJ, DEF_MAX_WBEMOBJ, m_szIWbemObject, &uReturned);

		if (FAILED(hr))
		{  
			return strRet;
		}  
		VariantClear(&var);

		UINT i = 0;
		for (i = 0; i < uReturned; i++)
		{
			if (m_szIWbemObject[i] != NULL) 
			{
				VariantClear(&var);
				var.bstrVal = NULL;

				if (pUniqueCaption != NULL)
				{
					hr = m_szIWbemObject[i]->Get(pUniqueCaption, 0, &var, NULL, NULL);
					if (hr != WBEM_S_NO_ERROR)
					{
						return strRet;
					}
				}

				if (pUniqueCaption == NULL || var.bstrVal!=NULL && 
					_tcsncmp((V_BSTR(&var)),pUniqueValue, _tcslen(pUniqueValue)) == 0)
				{
					VariantClear(&var);
					var.bstrVal = NULL;
					hr = m_szIWbemObject[i]->Get(pTargetCaption, 0, &var, NULL, NULL);
					if (var.vt != VT_NULL)
					{
						SAFEARRAY *pArr = nullptr;
						BSTR vbStr = nullptr;
						pArr = V_ARRAY(&var);
						if (SafeArrayGetDim(pArr)!=1)
						{
							strRet = var.bstrVal;
						}
						else
						{
							LONG lLeft = 0;
							LONG lRight = 0;
							SafeArrayGetLBound(pArr, 1, &lLeft);
							SafeArrayGetUBound(pArr, 1, &lRight);

							LONG arrayCount = lLeft;
							while (arrayCount<=lRight)
							{
								if (SafeArrayGetElement(pArr,&arrayCount,&vbStr) == S_OK)
								{  
									strRet += vbStr;
									strRet += _T(" ");
								}
								arrayCount++;
							}

						}
						if (vbStr!=nullptr)
						{  
							SysFreeString(vbStr); 
							vbStr = nullptr;
						}
						break;
					}
				}
			}
		}
		VariantClear(&var);
	}  

	return strRet;  
}  

DetectVM.cpp

#include "stdafx.h"
#include "DetectVM.h"
#include <windows.h>
#include "TClientDMI.h"

static CString strManufacturer;
static CString strModel;
static CString strDiskDrive;
static bool bInit = false;

void init()
{
	if(!bInit)
	{
		TClientDMI DMI = TClientDMI();
		strManufacturer = DMI.getDMIInformation(_T("Win32_ComputerSystem"), NULL, NULL, _T("Manufacturer"));
		strManufacturer.MakeLower();

		strModel = DMI.getDMIInformation(_T("Win32_ComputerSystem"), NULL, NULL, _T("Model"));
		strModel.MakeLower();

		strDiskDrive = DMI.getDMIInformation(_T("Win32_DiskDrive"), NULL, NULL, _T("Model"));
		strDiskDrive.MakeLower();
		bInit = true;
	}
/*	MessageBox(NULL, strManufacturer,strManufacturer,MB_OK);
	MessageBox(NULL, strModel,strModel,MB_OK);
	MessageBox(NULL, strDiskDrive,strDiskDrive,MB_OK);*/
}

bool IsInsideVirtualMachine()
{
	return IsInsideVMWare() || IsInsideXenServer();
}

bool IsInsideVMWare()
{
	if(!bInit)
		init();
	if(strManufacturer.Find(_T("vmware")) >= 0)
		return true;
	if(strModel.Find(_T("vmware")) >= 0)
		return true;
	return false;
}

bool IsInsideXenServer()
{
	if(!bInit)
		init();
	// 检测系统制造商为XGen 系统模式为 HVM domU
	if(strDiskDrive.Find(_T("qemu harddisk")) == 0)
		return true;
	if(strManufacturer == _T("xen"))
		return true;
	if(strModel.Find(_T("hvm domu")) == 0)
		return true;
	return false;
}


猜你喜欢

转载自blog.csdn.net/hnlwt/article/details/69224851