检测虚拟机环境的常见技术

下面列出检测 VMware 虚拟机的常见技术:

#include <iostream>
#include <windows.h>
#include <sysinfoapi.h>
#include <comdef.h>
#include <Wbemidl.h>
#include <ShlObj.h>
#include <LM.h>
#include <TlHelp32.h>
#include <string.h>
#include <string>
#include <atlbase.h>
#include <Iphlpapi.h>#include <Psapi.h>
#include <shlwapi.h>  //PathFileExists
#pragma comment(lib, "psapi.lib")
#pragma comment(lib, "shlwapi.lib")#pragma comment(lib, "wbemuuid.lib")
#pragma comment(lib, "netapi32.lib")
#pragma comment(lib,"Iphlpapi.lib") //GetAdaptersInfo需要添加Iphlpapi.lib库#define  ARRAY_SIZE 1024
using namespace std;// 检查管理员权限
BOOL isAdmin()
{BOOL bElevated = FALSE;HANDLE hToken = NULL;// Get current process tokenif (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))return FALSE;TOKEN_ELEVATION tokenEle;DWORD dwRetLen = 0;// Retrieve token elevation informationif (GetTokenInformation(hToken, TokenElevation, &tokenEle, sizeof(tokenEle), &dwRetLen)){if (dwRetLen == sizeof(tokenEle)){bElevated = tokenEle.TokenIsElevated;}}CloseHandle(hToken);return bElevated;
}// 检查CPU核心数
// SYSTEM_INFO.dwNumberOfProcessors
BOOL checkCPUCores(INT cores)
{INT i = 0;_asm { // x64编译模式下不支持__asm的汇编嵌入mov eax, dword ptr fs : [0x18] ; // TEBmov eax, dword ptr ds : [eax + 0x30] ; // PEBmov eax, dword ptr ds : [eax + 0x64] ;mov i, eax;}return i < cores;
}// 检查CPU温度(需要管理员权限)
// Get-WMIObject MSAcpi_ThermalZoneTemperature -Namespace "root/wmi"
// VM中无返回结果
// https://docs.microsoft.com/en-us/windows/win32/wmisdk/example--getting-wmi-data-from-the-local-computer
BOOL checkCPUTemperature()
{HRESULT hres;BOOL res = -1;do{// Step 1: --------------------------------------------------// Initialize COM. ------------------------------------------hres = CoInitializeEx(0, COINIT_MULTITHREADED);if (FAILED(hres)){// cout << "Failed to initialize COM library. Error code = 0x" << hex << hres << endl;break;                  // Program has failed.}// Step 2: --------------------------------------------------// Set general COM security levels --------------------------hres = CoInitializeSecurity(NULL,-1,                          // COM authenticationNULL,                        // Authentication servicesNULL,                        // ReservedRPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation  NULL,                        // Authentication infoEOAC_NONE,                   // Additional capabilities NULL                         // Reserved);if (FAILED(hres)){// cout << "Failed to initialize security. Error code = 0x" << hex << hres << endl;CoUninitialize();break;                    // Program has failed.}// Step 3: ---------------------------------------------------// Obtain the initial locator to WMI -------------------------IWbemLocator* pLoc = NULL;hres = CoCreateInstance(CLSID_WbemLocator,0,CLSCTX_INPROC_SERVER,IID_IWbemLocator, (LPVOID*)&pLoc);if (FAILED(hres)){// cout << "Failed to create IWbemLocator object." << " Err code = 0x" << hex << hres << endl;CoUninitialize();break;                 // Program has failed.}// Step 4: -----------------------------------------------------// Connect to WMI through the IWbemLocator::ConnectServer methodIWbemServices* pSvc = NULL;// Connect to the root\cimv2 namespace with// the current user and obtain pointer pSvc// to make IWbemServices calls.hres = pLoc->ConnectServer(// _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace_bstr_t(L"ROOT\\WMI"),NULL,                    // User name. NULL = current userNULL,                    // User password. NULL = current0,                       // Locale. NULL indicates currentNULL,                    // Security flags.0,                       // Authority (for example, Kerberos)0,                       // Context object &pSvc                    // pointer to IWbemServices proxy);if (FAILED(hres)){// cout << "Could not connect. Error code = 0x" << hex << hres << endl;pLoc->Release();CoUninitialize();break;                // Program has failed.}// cout << "Connected to ROOT\\WMI WMI namespace" << endl;// Step 5: --------------------------------------------------// Set security levels on the proxy -------------------------hres = CoSetProxyBlanket(pSvc,                        // Indicates the proxy to setRPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxxRPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxxNULL,                        // Server principal name RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxxNULL,                        // client identityEOAC_NONE                    // proxy capabilities );if (FAILED(hres)){// cout << "Could not set proxy blanket. Error code = 0x" << hex << hres << endl;pSvc->Release();pLoc->Release();CoUninitialize();break;               // Program has failed.}// Step 6: --------------------------------------------------// Use the IWbemServices pointer to make requests of WMI ----// For example, get the name of the operating systemIEnumWbemClassObject* pEnumerator = NULL;hres = pSvc->ExecQuery(bstr_t("WQL"),bstr_t("SELECT * FROM MSAcpi_ThermalZoneTemperature"),WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,NULL,&pEnumerator);if (FAILED(hres)){// cout << "Query for operating system name failed." << " Error code = 0x" << hex << hres << endl;pSvc->Release();pLoc->Release();CoUninitialize();break;               // Program has failed.}// Step 7: -------------------------------------------------// Get the data from the query in step 6 -------------------IWbemClassObject* pclsObj = NULL;ULONG uReturn = 0;while (pEnumerator){HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);if (0 == uReturn) // VM中结果为空{if (-1 == res){res = TRUE;}break;}VARIANT vtProp;// Get the value of the Name propertyhr = pclsObj->Get(L"CurrentTemperature", 0, &vtProp, 0, 0);// res = vtProp.ullVal / 10.0 - 273.15; // 开氏转摄氏res = FALSE;VariantClear(&vtProp);pclsObj->Release();}// Cleanup// ========pSvc->Release();pLoc->Release();pEnumerator->Release();CoUninitialize();} while (false);return res;
}// 检测MAC地址
// 00:05:69、00:0c:29、00:50:56开始的MAC地址与VMware相对应
// 00:03:ff开始的MAC地址与virtualpc对应
// 08:00:27开始的MAC地址与virtualbox对应
BOOL CheckMACEx()
{PIP_ADAPTER_INFO pIpAdapterInfo = new IP_ADAPTER_INFO();//PIP_ADAPTER_INFO结构体指针存储本机网卡信息unsigned long stSize = sizeof(IP_ADAPTER_INFO);         //得到结构体大小,用于GetAdaptersInfo参数int nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize);     //调用GetAdaptersInfo函数,填充pIpAdapterInfo指针变量;其中stSize参数既是一个输入量也是一个输出量wchar_t MAC[5][9] = { L"08-00-27", L"00-03-FF", L"00-0C-29" };//mac=="00-05-69", mac=="00-50-56"该方法不准确WCHAR buffer[20]{ 0 };//WCHAR* CurrentAPR;bool bRet = false;// 返回值if (ERROR_BUFFER_OVERFLOW == nRel){//如果函数返回的是ERROR_BUFFER_OVERFLOW//则说明GetAdaptersInfo参数传递的内存空间不够,同时其传出stSize,表示需要的空间大小//这也是说明为什么stSize既是一个输入量也是一个输出量               delete pIpAdapterInfo;//释放原来的内存空间     pIpAdapterInfo = (PIP_ADAPTER_INFO)new BYTE[stSize];//重新申请内存空间用来存储所有网卡信息        nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize);    //再次调用GetAdaptersInfo函数,填充pIpAdapterInfo指针变量}if (ERROR_SUCCESS == nRel){//可能有多网卡,因此通过循环去判断while (pIpAdapterInfo){wsprintf(buffer, L"%02X-%02X-%02X", pIpAdapterInfo->Address[0], pIpAdapterInfo->Address[1], pIpAdapterInfo->Address[2]);for (int i = 0; i < 3; ++i){// 检查MAC地址前3位是否在拼接好的内容中。if (wcsstr(buffer, MAC[i])){bRet = TRUE;break;}}pIpAdapterInfo = pIpAdapterInfo->Next;}}//释放内存空间if (pIpAdapterInfo){delete[]pIpAdapterInfo;}return bRet;
}// 检测内存大小
// SELECT * FROM Win32_ComputerSystem
// TotalPhysicalMemory
BOOL checkMemory(INT memory)
{_MEMORYSTATUSEX mst;mst.dwLength = sizeof(mst);GlobalMemoryStatusEx(&mst);if (mst.ullTotalPhys / (1024.0 * 1024 * 1024) < memory) // B{return TRUE;}else{return FALSE;}
}// 检测磁盘大小(需要管理员权限)
// SELECT * FROM Win32_LogicalDisk
// Size
BOOL checkPhyDisk(INT disk)
{HANDLE hDrive;GET_LENGTH_INFORMATION size;DWORD lpBytes;hDrive = CreateFileA("\\\\.\\PhysicalDrive0", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);if (hDrive == INVALID_HANDLE_VALUE){CloseHandle(hDrive);return FALSE;}bool result = DeviceIoControl(hDrive, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &size, sizeof(GET_LENGTH_INFORMATION), &lpBytes, NULL);CloseHandle(hDrive);if ((size.Length.QuadPart / 1073741824) < disk){return TRUE;}else{return FALSE;}
}// 检测进程
BOOL checkProcess()
{const char* list[5] = { "VBoxService.exe", "VBoxTray.exe", "VGAuthService.exe","vm3dservice.exe", "vmtoolsd.exe" };PROCESSENTRY32 pe32;pe32.dwSize = sizeof(pe32);HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);BOOL bResult = Process32First(hProcessSnap, &pe32);while (bResult){char sz_Name[MAX_PATH] = { 0 };WideCharToMultiByte(CP_ACP, 0, pe32.szExeFile, -1, sz_Name, sizeof(sz_Name), NULL, NULL);for (int i = 0; i < 4; ++i){if (strcmp(sz_Name, list[i]) == 0){return TRUE;}}bResult = Process32Next(hProcessSnap, &pe32);}return FALSE;
}// 检测注册表和文件路径(可能需要管理员权限)
BOOL checkPath()
{HKEY hkey;int CoeckStrictMode = 0;WIN32_FIND_DATA wfd1, wfd2;if (RegOpenKeyA(HKEY_CLASSES_ROOT, "\\Applications\\VMwareHostOpen.exe", &hkey) == ERROR_SUCCESS ||RegOpenKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Oracle\\VirtualBox Guest Additions", &hkey) == ERROR_SUCCESS){return TRUE;}// 文件夹路径//if (!PathIsDirectoryA("C:\\Program Files\\VMware\\VMware Tools\\") || //!PathIsDirectoryA("C:\\Program Files\\Oracle\\VirtualBox Guest Additions\\"))//{//printf("E2\n");//return TRUE;//}HANDLE hFind1 = FindFirstFileW(L"C:\\Program Files\\VMware\\VMware Tools\\", &wfd1);HANDLE hFind2 = FindFirstFileW(L"C:\\Program Files\\Oracle\\VirtualBox Guest Additions\\", &wfd2);if (INVALID_HANDLE_VALUE != hFind1 && (wfd1.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))CoeckStrictMode++;if (INVALID_HANDLE_VALUE != hFind2 && (wfd2.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))CoeckStrictMode++;CloseHandle(hFind1);CloseHandle(hFind2);if (PathFileExistsW(L"C:\\Program Files\\VMware\\VMware Tools\\") ||PathFileExistsW(L"C:\\Program Files\\Oracle\\VirtualBox Guest Additions\\"))CoeckStrictMode++;if (INVALID_FILE_ATTRIBUTES != GetFileAttributesW(L"C:\\Program Files\\VMware\\VMware Tools\\")||INVALID_FILE_ATTRIBUTES != GetFileAttributesW(L"C:\\Program Files\\Oracle\\VirtualBox Guest Additions\\"))CoeckStrictMode++;if (CoeckStrictMode > 1) return TRUE;return FALSE;
}int EnumDriverDevice() {DWORD cbNeeded = 0; // drivers[] 返回的字节数LPVOID drivers[ARRAY_SIZE] = { 0 }; // 驱动程序地址列表数组int cDrivers = 0;	// 驱动个数int CoeckStrictMode = 0;const wchar_t* wsDRVFile[8] = {L"vmmouse.sys",L"vmusbmouse.sys",L"vmrawdsk.sys",L"vmmemctl.sys",L"vm3dmp.sys",L"vm3dmp_loader.sys",L"vm3dmp-debug.sys",L"vm3dmp-stats.sys"};if (K32EnumDeviceDrivers(drivers, sizeof(drivers), &cbNeeded) && cbNeeded < sizeof(drivers)) // EnumDeviceDrivers 检索每个驱动文件的加载地址{wchar_t szDriver[ARRAY_SIZE] = { 0 };	// 驱动文件名wchar_t szPath[ARRAY_SIZE] = { 0 };	// 存放驱动文件全路径wchar_t szSystemPath[ARRAY_SIZE] = { 0 }; // 存放 system32 文件夹路径cDrivers = cbNeeded / sizeof(LPVOID);	// 驱动个数//得到C:\Windows\system32\dbghelp.dllGetSystemDirectoryW(szSystemPath, sizeof(szSystemPath));wcscat_s(szSystemPath, L"\\dbghelp.dll");for (int i = 0; i < cDrivers; i++){if (K32GetDeviceDriverBaseNameW(drivers[i], szDriver, sizeof(szDriver) / sizeof(LPVOID))){for (int i = 0; i < 8; i++)if (wcscmp(szDriver, wsDRVFile[i]) == 0)CoeckStrictMode++;// 打印驱动名//printf("【%d】:%ws\n", i + 1, szDriver);// 打印驱动文件路径//GetDeviceDriverFileName(drivers[i], szPath, sizeof(szPath));//printf("%s\n", szPath);}}}return CoeckStrictMode;
}BOOL checkVMDriversFile()
{if (EnumDriverDevice() >= 1) return TRUE;return FALSE;
}// 检测服务
BOOL checkSerivce()
{int menu = 0;// 打开系统服务控制器    SC_HANDLE SCMan = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);if (SCMan == NULL){return -1;}// 保存系统服务的结构  LPENUM_SERVICE_STATUSA service_status;DWORD cbBytesNeeded = NULL;DWORD ServicesReturned = NULL;DWORD ResumeHandle = NULL;service_status = (LPENUM_SERVICE_STATUSA)LocalAlloc(LPTR, 1024 * 64);// 获取系统服务的简单信息    bool ESS = EnumServicesStatusA(SCMan, //系统服务句柄    SERVICE_WIN32, //服务的类型    SERVICE_STATE_ALL,  //服务的状态    (LPENUM_SERVICE_STATUSA)service_status,  //输出参数,系统服务的结构    1024 * 64,  //结构的大小    &cbBytesNeeded, //输出参数,接收返回所需的服务    &ServicesReturned, //输出参数,接收返回服务的数量    &ResumeHandle //输入输出参数,第一次调用必须为0,返回为0代表成功);if (ESS == NULL){return -1;}for (DWORD i = 0; i < ServicesReturned; i++){if (strstr(service_status[i].lpDisplayName, "VMware Tools") != NULL ||strstr(service_status[i].lpDisplayName, "VMware 物理磁盘助手服务") != NULL || strstr(service_status[i].lpDisplayName, "Virtual Machine") != NULL ||strstr(service_status[i].lpDisplayName, "VirtualBox Guest") != NULL){return TRUE;}}//关闭服务管理器的句柄   CloseServiceHandle(SCMan);return FALSE;
}// 检测开机时间
BOOL checkUptime(DWORD msTime)
{DWORD UpTime = GetTickCount();if (UpTime < msTime){return TRUE;}else{return FALSE;}
}// 使用CPUID指令
// 当EAX=1时,CPUID的ECX中HYPERV_HYPERVISOR_PRESENT_BIT标识是否在虚拟环境中
BOOL checkCPUID()
{DWORD dw_ecx;bool bFlag = true;_asm {pushad; // 将32位通用寄存器压入堆栈pushfd; // 将32位标志寄存器EFLAGS压入堆栈mov eax, 1; // Processor Info and Feature Bitscpuid; // 根据传递给EAX寄存器的值,将对应的信息返回给EAX、EBX、ECX、EDXmov dw_ecx, ecx; // Feature Informationand ecx, 0x80000000; // Hypervisor present (always zero on physical CPUs) 即 HYPERV_HYPERVISOR_PRESENT_BITtest ecx, ecx; // AND为0的话ZF=1setz[bFlag]; // ZF为1的话bFlag=1popfd;popad;}if (bFlag) // 真实机器{return FALSE;}else{return TRUE;}
}// 检测TEMP目录下的文件数量
BOOL checkTempDir(INT aNum)
{int file_count = 0;DWORD dwRet;LPSTR pszOldVal;pszOldVal = (LPSTR)malloc(MAX_PATH * sizeof(char));dwRet = GetEnvironmentVariableA("TEMP", pszOldVal, MAX_PATH);std::string stdstr = pszOldVal;stdstr += "\\*";LPSTR s = const_cast<char*>(stdstr.c_str());WIN32_FIND_DATAA data;HANDLE hFind = FindFirstFileA(s, &data);if (hFind != INVALID_HANDLE_VALUE){do{file_count++;} while (FindNextFileA(hFind, &data));FindClose(hFind);}if (file_count < aNum){return TRUE;}else{return FALSE;}
}// 检测主板序列号、主机型号、系统盘所在磁盘名称等硬件信息
// WMI ROOT\\CIMV2
BOOL ManageWMIInfo(string& result, string table, wstring wcol)
{char bord[1024];HRESULT hres = CoInitialize(0);IWbemLocator* pLoc = NULL;hres = CoCreateInstance(CLSID_WbemLocator,0,CLSCTX_INPROC_SERVER,IID_IWbemLocator, (LPVOID*)&pLoc);if (FAILED(hres)){CoUninitialize();return FALSE;}IWbemServices* pSvc = NULL;hres = pLoc->ConnectServer(_bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace  NULL, // User name. NULL = current user  NULL, // User password. NULL = current  0, // Locale. NULL indicates current  NULL, // Security flags.  0, // Authority (e.g. Kerberos)  0, // Context object   &pSvc // pointer to IWbemServices proxy  );if (FAILED(hres)){pLoc->Release();CoUninitialize();return FALSE;}hres = CoSetProxyBlanket(pSvc, // Indicates the proxy to set  RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx  RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx  NULL, // Server principal name   RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx   RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx  NULL, // client identity  EOAC_NONE // proxy capabilities   );if (FAILED(hres)){pSvc->Release();pLoc->Release();CoUninitialize();return FALSE;}IEnumWbemClassObject* pEnumerator = NULL;string select = "SELECT * FROM " + table;hres = pSvc->ExecQuery(bstr_t("WQL"),bstr_t(select.c_str()),WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,NULL,&pEnumerator);if (FAILED(hres)){pSvc->Release();pLoc->Release();CoUninitialize();return FALSE;}ULONG uReturn = 0;IWbemClassObject* pclsObj;while (pEnumerator){HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);if (0 == uReturn){break;}VARIANT vtProp;VariantInit(&vtProp);hr = pclsObj->Get(wcol.c_str(), 0, &vtProp, 0, 0);if (!FAILED(hr)){CW2A tmpstr(vtProp.bstrVal);strcpy_s(bord, 200, tmpstr);result = bord;}VariantClear(&vtProp);pclsObj->Release();}pSvc->Release();pLoc->Release();pEnumerator->Release();CoUninitialize();return TRUE;
}// 检测磁盘驱动程序发布商名称
BOOL checkHardwareInfo()
{BOOL bRet = TRUE;do{string ret;ManageWMIInfo(ret, "Win32_BaseBoard", L"SerialNumber");if (ret == "None"){break;}ManageWMIInfo(ret, "Win32_DiskDrive", L"Caption");if (ret.find("VMware") != string::npos || ret.find("VBOX") != string::npos || ret.find("Virtual HD") != string::npos){break;}ManageWMIInfo(ret, "Win32_computersystem", L"Model");if (ret.find("VMware") != string::npos || ret.find("VirtualBox") != string::npos || ret.find("Virtual Machine") != string::npos){break;}bRet = FALSE;} while (FALSE);return bRet;
}// 使用sgdt和sldt指令探测VMware的技术通常被称为No Pill
// 通过禁用VMware加速可以防止No Pill技术的探测
BOOL checkNoPill()
{ULONG xdt = 0;ULONG InVM = 0;__asm{push edxsidt[esp - 2] // 将中断描述符表寄存器IDTR的内容存入指定地址单元pop edxnopmov xdt, edx}if (xdt > 0xd0000000){InVM = 1;}__asm{push edxsgdt[esp - 2] // 将全局描述符表格寄存器GDTR的内容存入指定地址单元pop edxnopmov xdt, edx}if (xdt > 0xd0000000){InVM += 1;}if (InVM == 0){return FALSE;}else{return TRUE;}
}// 检测IO端口
// VMware会监视in指令的执行,并捕获目的通信端口为0x5668(VX)的I/O
// VMware会检查第二个操作数是否是VX,在这种情况发生时
// EAX寄存器载入的值是0x564D5868(VMXh)
// ECX寄存器为在端口上执行相应操作的值
// 0xA:get VMware version type
// 0x14:get the memory size
// 则EBX为magic数VMXh,ECX为版本号
// 在真实机器上运行会触发EXCEPTION_EXECUTE_HANDLER异常
// https://www.aldeid.com/wiki/VMXh-Magic-Value
BOOL checkIOPort()
{bool rc = true;__try{__asm{push   edxpush   ecxpush   ebxmov    eax, 'VMXh'mov    ebx, 0mov    ecx, 10mov    edx, 'VX'in     eax, dx // 从一个源操作数指定的端口dx复制数据到目的操作数指定的内存地址cmp    ebx, 'VMXh'setz[rc]pop    ebxpop    ecxpop    edx}}__except (EXCEPTION_EXECUTE_HANDLER){rc = false;}return rc;
}// 检测无效指令
// VirtualPC使用一堆无效指令来允许虚拟机和VirtualPC之间连接,如果VirtualPC存在则不引起异常
DWORD IslnsideVPC_exceptionFilter(LPEXCEPTION_POINTERS ep)
{PCONTEXT ctx = ep->ContextRecord;ctx->Ebx = -1; // 未运行在VPC中  ctx->Eip += 4; // 跳过call VPC操作  return EXCEPTION_CONTINUE_EXECUTION;
}BOOL checkUnISA()
{bool rc = TRUE;__try{__asm{push ebxmov ebx, 0mov eax, 1__emit 0fh // 在当前位置直接插入数据__emit 3fh__emit 07h__emit 0bhtest ebx, ebxsetz[rc]pop ebx}}__except (IslnsideVPC_exceptionFilter(GetExceptionInformation())){rc = FALSE;}return rc;
}int DetectVisualMachine(int *s, int drd) {int* p = s;if (drd == 0 && checkCPUTemperature()) {s = new int;*s = *p;*p = (*s) + 1;DetectVisualMachine(p, ++drd);}else {s = new int;*s = *p;*p = (*s);DetectVisualMachine(p, ++drd);}if (*p == 1 && checkPhyDisk(250)) {s = new int;*s = *p;*p = (*s) + 1;DetectVisualMachine(p, ++drd);}else {s = new int;*s = *p;*p = (*s);DetectVisualMachine(p, ++drd);}if (*p == 2 && checkPath()) {s = new int;*s = *p;*p = (*s) + 1;DetectVisualMachine(p, ++drd);}else {s = new int;*s = *p;*p = (*s);DetectVisualMachine(p, ++drd);}if (*p == 3 && checkCPUCores(4)) {s = new int;*s = *p;*p = (*s) + 1;DetectVisualMachine(p, ++drd);}else {s = new int;*s = *p;*p = (*s);DetectVisualMachine(p, ++drd);}if (*p == 4 && CheckMACEx()) {s = new int;*s = *p;*p = (*s) + 1;DetectVisualMachine(p, ++drd);}else {s = new int;*s = *p;*p = (*s);DetectVisualMachine(p, ++drd);}if (*p == 5 && checkMemory(4)) {s = new int;*s = *p;*p = (*s) + 1;DetectVisualMachine(p, ++drd);}else {s = new int;*s = *p;*p = (*s);DetectVisualMachine(p, ++drd);}if (*p == 6 && checkProcess()) {s = new int;*s = *p;*p = (*s) + 1;DetectVisualMachine(p, ++drd);}else {s = new int;*s = *p;*p = (*s);DetectVisualMachine(p, ++drd);}if (*p == 7 && checkSerivce()) {s = new int;*s = *p;*p = (*s) + 1;DetectVisualMachine(p, ++drd);}else {s = new int;*s = *p;*p = (*s);DetectVisualMachine(p, ++drd);}if (*p == 8 && checkCPUID()) {s = new int;*s = *p;*p = (*s) + 1;DetectVisualMachine(p, ++drd);}else {s = new int;*s = *p;*p = (*s);DetectVisualMachine(p, ++drd);}if (*p == 9 && checkHardwareInfo()) {s = new int;*s = *p;*p = (*s) + 1;DetectVisualMachine(p, ++drd);}else {s = new int;*s = *p;*p = (*s);DetectVisualMachine(p, ++drd);}if (*p == 10 && checkIOPort()) {s = new int;*s = *p;*p = (*s) + 1;DetectVisualMachine(p, ++drd);}else {s = new int;*s = *p;*p = (*s);DetectVisualMachine(p, ++drd);}if (*p == 11 && checkVMDriversFile()) {s = new int;*s = *p;*p = (*s) + 1;DetectVisualMachine(p, ++drd);}else {s = new int;*s = *p;*p = (*s);DetectVisualMachine(p, ++drd);}if (*p == 12 && checkProcess()) {s = new int;*s = *p;*p = (*s) + 1;DetectVisualMachine(p, ++drd);}else {s = new int;*s = *p;*p = (*s);DetectVisualMachine(p, ++drd);}
}int main()
{// 需要管理员权限if (isAdmin() && IsUserAnAdmin()){printf("[+] Admin\n");if (checkCPUTemperature()){printf("[-] checkCPUTemperature - VM\n");}else{printf("[+] checkCPUTemperature - not VM\n");}if (checkPhyDisk(250)){printf("[-] checkPhyDisk - VM\n");}else{printf("[+] checkPhyDisk - not VM\n");}if (checkPath())//{printf("[-] checkPath - VM\n");}else{printf("[+] checkPath - not VM\n");}}//printf("[+] Not Admin\n");if (checkCPUCores(4)){printf("[-] checkCPUCores - VM\n");}else{printf("[+] checkCPUCores - not VM\n");}if (CheckMACEx()){printf("[-] checkMAC - VM\n");}else{printf("[+] checkMAC - not VM\n");}if (checkMemory(4)){printf("[-] checkMemory - VM\n");}else{printf("[+] checkMemory - not VM\n");}if (checkProcess()){printf("[-] checkProcess - VM\n");}else{printf("[+] checkProcess - not VM\n");}if (checkSerivce()){printf("[-] checkSerivce - VM\n");}else{printf("[+] checkSerivce - not VM\n");}if (checkCPUID()){printf("[-] checkCPUID - VM\n");}else{printf("[+] checkCPUID - not VM\n");}/**if (checkTempDir(30)){printf("[-] checkTempDir - VM\n");}else{printf("[+] checkTempDir - not VM\n");}*/if (checkHardwareInfo()){printf("[-] checkHardwareInfo - VM\n");}else{printf("[+] checkHardwareInfo - not VM\n");}if (checkIOPort()){printf("[-] checkIOPort - VM\n");}else{printf("[+] checkIOPort - not VM\n");}if (checkVMDriversFile()){printf("[-] checkDriversFile - VM\n");}else{printf("[+] checkDriversFile - not VM\n");}cin.get();return 0;
}

虚拟机实测:


发布于:2024.03.10.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/737040.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++】了解一下STL

个人主页 &#xff1a; zxctscl 如有转载请先通知 STL 1. 什么是STL2. STL的版本3. STL的六大组件4. STL的重要性5. 如何学习STL6. STL的缺陷 1. 什么是STL STL(standard template libaray-标准模板库)&#xff1a;是C标准库的重要组成部分&#xff0c;不仅是一个可复用的组件…

Php和h5等静态文件的服务容器化部署(下)

一、接着上文 上文介绍了php/h5程序的部署过程&#xff0c;最后是通过slb把不同的服务暴露给外部。 本文试着把外部的配置交待清楚&#xff0c;包括&#xff1a; kong配置ingress配置 部署逻辑图见下&#xff1a; 总结&#xff1a; 去掉slb&#xff0c;引入ingress组件。…

蓝桥杯真题讲解:接龙序列

蓝桥杯真题讲解&#xff1a;接龙序列 一、视频讲解二、暴力代码三、正解代码 一、视频讲解 蓝桥杯真题讲解&#xff1a;接龙序列 二、暴力代码 // 暴力代码&#xff1a;DFS&#xff08;2^n&#xff09; #include<bits/stdc.h> #define endl \n #define deb(x) cout &…

零基础自学C语言|自定义类型:结构体

✈结构体类型的声明 前面我们在学习操作符的时候&#xff0c;已经学习了结构体的知识&#xff0c;这里稍微复习一下。 &#x1f680;结构体回顾 结构是一些值的集合&#xff0c;这些值称为成员变量。结构的每个成员可以是不同类型的变量。 &#x1fa82;结构的声明 例如&a…

李彦宏:程序员职业将不复存在,会说话就能当程序员;ChatGPT 日耗电超 50 万度丨 RTE 开发者日报 Vol.161

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE &#xff08;Real Time Engagement&#xff09; 领域内「有话题的新闻」、「有态度的观点」、「有意思的数据」、「有思考的文章」、…

中国社会科学院与美国杜兰大学金融管理硕士——二月二,抬头皆是惊喜

在繁忙的都市生活中&#xff0c;每个人都在为自己的未来打拼&#xff0c;寻找着属于自己的那片天空。二月二&#xff0c;龙抬头&#xff0c;象征着春天的到来&#xff0c;万物复苏。在这个特殊的日子里&#xff0c;对于那些追求学术与职业双重成就的人来说&#xff0c;&#xf…

AIGC——DreamTuner通过单张图片生成与该图片主题风格一致的新图像

简介 DreamTuner的能力在于从单个图像生成主体驱动的新通用方法&#xff0c;这意味着用户只需提供一张图片&#xff0c;DreamTuner就能帮助他们生成与原始图片在主题和风格上一致的新图像。 算法重要之处在于其通用性和个性化定制的能力。无论是需要根据特定主题或条件创建个…

【深度学习笔记】优化算法——学习率调度器

学习率调度器 &#x1f3f7;sec_scheduler 到目前为止&#xff0c;我们主要关注如何更新权重向量的优化算法&#xff0c;而不是它们的更新速率。 然而&#xff0c;调整学习率通常与实际算法同样重要&#xff0c;有如下几方面需要考虑&#xff1a; 首先&#xff0c;学习率的大…

cefsharp(winForm)调用js脚本,js脚本调用c#方法

本博文针对js-csharp交互(相互调用的应用) (一)、js调用c#方法 1.1 类名称:cs_js_obj public class cs_js_obj{//注意,js调用C#,不一定在主线程上调用的,需要用SynchronizationContext来切换到主线程//private System.Threading.SynchronizationContext context;//…

Elasticsearch 分享

一、Elasticsearch 基础介绍 ElasticSearch 是分布式实时搜索、实时分析、实时存储引擎&#xff0c;简称&#xff08;ES)&#xff0c; 成立于2012年&#xff0c;是一家来自荷兰的、开源的大数据搜索、分析服务提供商&#xff0c;为企业提供实时搜索、数据分析服务&#xff0c;…

AHU 汇编 实验四

实验名称&#xff1a;实验四 两个数的相乘 实验内容&#xff1a; 用子程序形式编写&#xff1a; A*B&#xff1a;从键盘输入a和b&#xff0c;计算A*B&#xff0c;其中乘法采用移位和累加完成 实验过程&#xff1a; 源代码&#xff1a; data segmentmul1 db 16,?,16 dup(?…

树莓派安装Nginx服务搭建web网站结合内网穿透实现公网访问本地站点

文章目录 1. Nginx安装2. 安装cpolar3.配置域名访问Nginx4. 固定域名访问5. 配置静态站点 安装 Nginx&#xff08;发音为“engine-x”&#xff09;可以将您的树莓派变成一个强大的 Web 服务器&#xff0c;可以用于托管网站或 Web 应用程序。相比其他 Web 服务器&#xff0c;Ngi…

什么是高级编程语言?——跟老吕学Python编程

什么是高级编程语言&#xff1f;——跟老吕学Python编程 高级编程语言简介高级编程语言发展历程高级编程语言特点高级编程语言分类命令式语言函数式语言逻辑式语言面向对象语言 常见的高级编程语言及其特点和应用领域高级编程语言性能分析高级编程语言的工作方式 高级编程语言简…

GPT出现Too many requests in 1 hour. Try again later.

换节点 这个就不用多说了&#xff0c;你都可以上GPT帐号了&#xff0c;哈…… 清除cooki

平面纯弯梁单元Matlab有限元编程 |欧拉梁单元| 简支梁|悬臂梁|弯矩图 |变形图| Matlab源码 | 视频教程

专栏导读 作者简介&#xff1a;工学博士&#xff0c;高级工程师&#xff0c;专注于工业软件算法研究本文已收录于专栏&#xff1a;《有限元编程从入门到精通》本专栏旨在提供 1.以案例的形式讲解各类有限元问题的程序实现&#xff0c;并提供所有案例完整源码&#xff1b;2.单元…

容灾演练双月报|美创DRCC助力银行高效验证数据库高可用架构

了解更多灾备行业动态 守护数字化时代业务连续 目录 CONTENTS 01 灾备法规政策 02 热点安全事件 03 容灾演练典型案例 01 灾备法规政策 2月&#xff0c;工信部印发《工业领域数据安全能力提升实施方案&#xff08;2024—2026年&#xff09;》&#xff0c;要求到2026年…

专属你的时尚盛宴,尽在手机无人直播!

时尚&#xff0c;是一个永恒的话题。在这个充满活力的时代&#xff0c;时尚不仅仅是穿着打扮&#xff0c;更是一种生活态度&#xff0c;一种表达自我的方式。每个人都有自己独特的时尚理念&#xff0c;每个人都可以在时尚的世界里找到属于自己的一席之地。 手机无人直播&#…

鼠标在QTreeView、QTableView、QTableWidget项上移动,背景色改变

目录 1. 前言 2. 需求 3. 功能实现 3.1. 代码实现 3.2. 功能讲解 4. 附录 1. 前言 本博文用到了Qt的model/view framework框架,如果对Qt的“模型/视图/委托”框架不懂&#xff0c;本博文很难读懂。如果不懂这方面的知识&#xff0c;请在Qt Assistant 中输入Model/View…

力扣大厂热门面试算法题 15-17

15. 三数之和&#xff0c;16. 最接近的三数之和&#xff0c;17. 电话号码的字母组合&#xff0c;每题做详细思路梳理&#xff0c;配套Python&Java双语代码&#xff0c; 2024.03.11 可通过leetcode所有测试用例。 目录 15. 三数之和 解题思路 完整代码 Java Python ​…

Ubuntu 24.04 抢先体验换国内源 清华源 阿里源 中科大源 163源

Update 240307:Ubuntu 24.04 LTS 进入功能冻结期 预计4月25日正式发布。 Ubuntu22.04换源 Ubuntu 24.04重要升级daily版本下载换源步骤 (阿里源)清华源中科大源网易163源 Ubuntu 24.04 LTS&#xff0c;代号 「Noble Numbat」&#xff0c;即将与我们见面&#xff01; Canonica…