思路:扫描启动项下的启动exe。然后将其替换 bool IsInsideVMWare() { bool rc = true; __try { __asm { push edx push ecx push ebx mov eax, ‘VMXh‘ mov ebx, 0 // any value but not the MAGIC VALUE mov ecx, 10 // get VMWare version mov edx, ‘VX‘ // port number in eax, dx // read port // on return EAX returns the VERSION cmp ebx, ‘VMXh‘ // is it a reply from VMWare? setz [rc] // set return value pop ebx pop ecx pop edx } } __except(EXCEPTION_EXECUTE_HANDLER) { rc = false; } return rc; } DWORD __forceinline IsInsideVPC_exceptionFilter(LPEXCEPTION_POINTERS ep) { PCONTEXT ctx = ep->ContextRecord; ctx->Ebx = -1; // Not running VPC ctx->Eip += 4; // skip past the "call VPC" opcodes return EXCEPTION_CONTINUE_EXECUTION; // we can safely resume execution since we skipped faulty instruction } // High level language friendly version of IsInsideVPC() bool IsInsideVPC() { bool rc = false; __try { _asm push ebx _asm mov ebx, 0 // It will stay ZERO if VPC is running _asm mov eax, 1 // VPC function number // call VPC _asm __emit 0Fh _asm __emit 3Fh _asm __emit 07h _asm __emit 0Bh _asm test ebx, ebx _asm setz [rc] _asm pop ebx } // The except block shouldn‘t get triggered if VPC is running!! __except(IsInsideVPC_exceptionFilter(GetExceptionInformation())) { } return rc; } BOOL CheckVMWare() { unsigned char mem[4] = {0}; __asm str mem; if ((mem[0] == 0x00) && (mem[1] == 0x40)) { return TRUE; } else { return FALSE; } } DWORD IslnsideVPC_exceptionFilter(LPEXCEPTION_POINTERS ep) { PCONTEXT ctx=ep->ContextRecord; ctx->Ebx = -1; //未运行在VPC中 ctx->Eip += 4; //跳过”call VPC”操作 return EXCEPTION_CONTINUE_EXECUTION; } BOOL CheckVirtualPC() { bool rc = TRUE; __try { __asm { push ebx mov ebx, 0 mov eax, 1 __emit 0fh __emit 3fh __emit 07h __emit 0bh test ebx, ebx setz[rc] pop ebx } } __except(IslnsideVPC_exceptionFilter(GetExceptionInformation())) { rc = FALSE; } return rc; } BOOL CheckVMWare() { bool rc = true; __try { __asm { push edx push ecx push ebx mov eax, ‘VMXh‘ mov ebx, 0 mov ecx, 10 mov edx, ‘VX‘ in eax, dx cmp ebx, ‘VMXh‘ setz [rc] pop ebx pop ecx pop edx } } __except(EXCEPTION_EXECUTE_HANDLER) { rc = false; } return rc; } BOOL CheckVMWare() { ULONG xdt = 0 ; ULONG InVM = 0; __asm { push edx sidt [esp-2] pop edx nop mov xdt , edx } if (xdt > 0xd0000000) { InVM = 1; } else { InVM = 0; } __asm { push edx sgdt [esp-2] pop edx nop mov xdt , edx } if (xdt > 0xd0000000) { InVM += 1; } if (InVM == 0) { return FALSE; } else { return TRUE; } } BOOL CheckVMWare() { int menu = 0; //打开系统服务控制器 SC_HANDLE SCMan = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE); if(SCMan == NULL) { cout << GetLastError() << endl; printf("OpenSCManager Eorror/n"); 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) { printf("EnumServicesStatus Eorror/n"); return -1; } for(int i = 0; i < ServicesReturned; i++) { if (strstr(service_status[i].lpDisplayName, "VMware Tools")!=NULL || strstr(service_status[i].lpDisplayName, "VMware 物理磁盘助手服务")!=NULL) { return TRUE; } } //关闭服务管理器的句柄 CloseServiceHandle(SCMan); return FALSE; } BOOL CheckVirtualPC() { int menu = 0; //打开系统服务控制器 SC_HANDLE SCMan = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE); if(SCMan == NULL) { cout << GetLastError() << endl; printf("OpenSCManager Eorror/n"); 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) { printf("EnumServicesStatus Eorror/n"); return -1; } for(int i = 0; i < ServicesReturned; i++) { if (strstr(service_status[i].lpDisplayName, "Virtual Machine")!=NULL) { return TRUE; } } //关闭服务管理器的句柄 CloseServiceHandle(SCMan); return FALSE; } BOOL CheckVirtualBox() { int menu = 0; //打开系统服务控制器 SC_HANDLE SCMan = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE); if(SCMan == NULL) { cout << GetLastError() << endl; printf("OpenSCManager Eorror/n"); 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) { printf("EnumServicesStatus Eorror/n"); return -1; } for(int i = 0; i < ServicesReturned; i++) { if (strstr(service_status[i].lpDisplayName, "VirtualBox Guest")!=NULL) { return TRUE; } } //关闭服务管理器的句柄 CloseServiceHandle(SCMan); return FALSE; } BOOL CheckVMWare() { __asm { rdtsc xchg ebx,eax rdtsc sub eax,ebx cmp eax,0xFF jg detected } return FALSE; detected: return TRUE; } BOOL CheckVirtualPC() { __asm { rdtsc xchg ebx,eax rdtsc sub eax,ebx cmp eax,0xFF jg detected } return FALSE; detected: return TRUE; } BOOL CheckVirtualBox() { __asm { rdtsc xchg ebx,eax rdtsc sub eax,ebx cmp eax,0xFF jg detected } return FALSE; detected: return TRUE; } BOOL CheckVMWare() { HKEY hkey; if (RegOpenKey(HKEY_CLASSES_ROOT, "\\Applications\\VMwareHostOpen.exe", &hkey) == ERROR_SUCCESS) { return TRUE; } else { return FALSE; } } BOOL CheckVirtualBox() { HKEY hkey; if (RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Oracle\\VirtualBox Guest Additions", &hkey) == ERROR_SUCCESS) { return TRUE; } else { return FALSE; } } BOOL CheckVMware() { if (PathIsDirectory("C:\\Program Files\\VMware\\VMware Tools\\") == 0) { return FALSE; } else { return TRUE; } } BOOL CheckVirtualBox() { if (PathIsDirectory("C:\\Program Files\\Oracle\\VirtualBox Guest Additions\\") == 0) { return FALSE; } else { return TRUE; } } BOOL CheckVMWare() { DWORD ret = 0; PROCESSENTRY32 pe32; pe32.dwSize = sizeof(pe32); HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if(hProcessSnap == INVALID_HANDLE_VALUE) { return FALSE; } BOOL bMore = Process32First(hProcessSnap, &pe32); while(bMore) { if (strcmp(pe32.szExeFile, "vmware.exe")==0) { return TRUE; } bMore = Process32Next(hProcessSnap, &pe32); } CloseHandle(hProcessSnap); return FALSE; } BOOL CheckVirtualBox() { DWORD ret = 0; PROCESSENTRY32 pe32; pe32.dwSize = sizeof(pe32); HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if(hProcessSnap == INVALID_HANDLE_VALUE) { return FALSE; } BOOL bMore = Process32First(hProcessSnap, &pe32); while(bMore) { if (strcmp(pe32.szExeFile, "VBoxService.exe")==0) { return TRUE; } bMore = Process32Next(hProcessSnap, &pe32); } CloseHandle(hProcessSnap); return FALSE; } BOOL CheckVMWare() { string mac; get_3part_mac(mac); if (mac=="00-05-69" || mac=="00-0c-29" || mac=="00-50-56") { return TRUE; } else { return FALSE; } } 2 3 4 5 6 7 8 9 10 11 12 13 BOOL CheckVirtualPC() { string mac; get_3part_mac(mac); if (mac=="00-03-ff") { return TRUE; } else { return FALSE; } } BOOL CheckVirtualBox() { string mac; get_3part_mac(mac); if (mac=="08-00-27") { return TRUE; } else { return FALSE; } } typedef struct _ASTAT_ { ADAPTER_STATUS adapt; NAME_BUFFER NameBuff[30]; } ASTAT, *PASTAT; void get_3part_mac(string &mac) { NCB Ncb; ASTAT Adapter; UCHAR uRetCode; LANA_ENUM lenum; memset(&Ncb, 0, sizeof(Ncb)); Ncb.ncb_command = NCBENUM; Ncb.ncb_buffer = (UCHAR *)&lenum; Ncb.ncb_length = sizeof(lenum); uRetCode = Netbios(&Ncb); for (int i = 0; i < lenum.length; i++) { memset(&Ncb, 0, sizeof(Ncb)); Ncb.ncb_command = NCBRESET; Ncb.ncb_lana_num = lenum.lana[i]; uRetCode = Netbios(&Ncb); memset(&Ncb, 0, sizeof(Ncb)); Ncb.ncb_command = NCBASTAT; Ncb.ncb_lana_num = lenum.lana[i]; strcpy((char *)Ncb.ncb_callname, "*"); Ncb.ncb_buffer = (unsigned char *)&Adapter; Ncb.ncb_length = sizeof(Adapter); uRetCode = Netbios(&Ncb); if (uRetCode == 0) { char tmp[128]; sprintf(tmp, "%02x-%02x-%02x", Adapter.adapt.adapter_address[0], Adapter.adapt.adapter_address[1], Adapter.adapt.adapter_address[2] ); mac = tmp; } } } BOOL ManageWMIInfo(string &result, string table, wstring wcol) { HRESULT hres; char bord[1024]; //初始化COM hres = CoInitialize(0); //获得WMI连接COM接口 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(); return false; } //通过连接接口连接WMI的内核对象名ROOT//CIMV2 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)) { cout << "Could not connect. Error code = 0x" << hex << hres << endl; 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)) { cout << "Could not set proxy blanket. Error code = 0x" << hex << hres << endl; pSvc->Release(); pLoc->Release(); CoUninitialize(); return false; } //通过请求代理来向WMI发送请求 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)) { cout << "Query for Network Adapter Configuration failed." << " Error code = 0x”" << hex << hres << endl; 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 tmpstr1(vtProp.bstrVal); strcpy_s(bord,200,tmpstr1); result = bord; } VariantClear(&vtProp); } //释放资源 pSvc->Release(); pLoc->Release(); pEnumerator->Release(); pclsObj->Release(); CoUninitialize(); return true; } BOOL CheckVMWare() { string table = "Win32_BaseBoard"; wstring wcol = L"SerialNumber"; string ret; ManageWMIInfo(ret, table, wcol); if (ret == "None") { return TRUE; } else { return FALSE; } } BOOL CheckVMWare() { string table = "Win32_DiskDrive"; wstring wcol = L"Caption"; string ret; ManageWMIInfo(ret, table, wcol); if (ret.find("VMware") != string::npos) { return TRUE; } else { return FALSE; } } BOOL CheckVMWare() { string table = "Win32_computersystem"; wstring wcol = L"Model"; string ret; ManageWMIInfo(ret, table, wcol); if (ret.find("VMware") != string::npos) { return TRUE; } else { return FALSE; } } BOOL CheckVirtualBox() { string table = "Win32_computersystem"; wstring wcol = L"Model"; string ret; ManageWMIInfo(ret, table, wcol); if (ret.find("VirtualBox") != string::npos) { return TRUE; } else { return FALSE; } } BOOL CheckVirtualBox() { string table = "Win32_DiskDrive"; wstring wcol = L"Caption"; string ret; ManageWMIInfo(ret, table, wcol); if (ret.find("VBOX") != string::npos) { return TRUE; } else { return FALSE; } } BOOL CheckVirtualPC() { string table = "Win32_DiskDrive"; wstring wcol = L"Caption"; string ret; ManageWMIInfo(ret, table, wcol); if (ret.find("Virtual HD") != string::npos) { return TRUE; } else { return FALSE; } } BOOL CheckVirtualPC() { string table = "Win32_computersystem"; wstring wcol = L"Model"; string ret; ManageWMIInfo(ret, table, wcol); if (ret.find("Virtual Machine") != string::npos) { return TRUE; } else { return FALSE; } }