基於軟體特徵檢測虛擬機
在調試時,有可能會放在虛擬機里調試,所以反調試就需要檢測是否在VM中,這裡提供的方法有以下三種:
方式1:搜索服務 – 包含WMware Tools / WMware 物理磁碟助手服務
方式2:找文件路徑 – C:\Program Files\VMware\VMware Tools
方式3:尋找進程 – vmtoolsd.exe
程式碼:
#include <stdio.h> #include <Windows.h> #include <process.h> #include <TlHelp32.h> #include "Psapi.h" #include <Shlwapi.h> #pragma comment(lib,"Shlwapi.lib") /**********************************************************************************/ // 通過VMware Tools路徑檢測虛擬機 BOOL CheckVmByPath() { // PathIsDirectory需要包含Shlwapi的頭文件和庫 if (PathIsDirectory("C:\\Program Files\\VMware\\VMware Tools") == 0 ) { return FALSE; } else { return TRUE; } } DWORD WINAPI ThreadFuncCallBack(LPVOID lp) { while (true) { if (CheckVmByPath()) { MessageBox(0, "VM存在", "提示",MB_OK); break; } } return 0; } /**********************************************************************************/ // 搜索服務 -- 包含WMware Tools / WMware 物理磁碟助手服務 BOOL CheckVmByServe() { SC_HANDLE SCMan = OpenSCManager(NULL,NULL, SC_MANAGER_CONNECT| SC_MANAGER_ENUMERATE_SERVICE); // 打開本地的服務控制管理器資料庫,得到句柄 if (SCMan == NULL) { return FALSE; } else { LPENUM_SERVICE_STATUSA service_status; DWORD dwByteNeed = NULL; // 需要的服務 DWORD dwServiceReturned = NULL; // 返回服務的數量 DWORD dwResumeHandle = NULL; service_status = (LPENUM_SERVICE_STATUSA)LocalAlloc(LPTR, 1024*64); bool bEss = EnumServicesStatusA(SCMan, SERVICE_WIN32, SERVICE_STATE_ALL, service_status, 1024 * 64, &dwByteNeed,&dwServiceReturned,&dwResumeHandle); if (bEss == NULL) { DWORD Error = GetLastError(); printf("%d", Error); return FALSE; } for (size_t i = 0; i < dwServiceReturned; i++) { if (strstr(service_status[i].lpDisplayName, "VMware Tools") != NULL || strstr(service_status[i].lpDisplayName, "WMware 物理磁碟助手服務") != NULL) { return TRUE; } } CloseServiceHandle(SCMan); return FALSE; } } /**********************************************************************************/ BOOL FindProcess(TCHAR *pName) { HANDLE SnapshotHandle; //定義一個快照 PROCESSENTRY32 ProcessEntry32; //照片結構體 SnapshotHandle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); //照第一張相 if (SnapshotHandle != INVALID_HANDLE_VALUE) { ProcessEntry32.dwSize = sizeof(PROCESSENTRY32); if (Process32First(SnapshotHandle, &ProcessEntry32)) //照的第一張放到ProcessEntry32裡面 { do { if (!strcmp(ProcessEntry32.szExeFile, pName)) { return TRUE; } } while (Process32Next(SnapshotHandle, &ProcessEntry32)); return FALSE; } } } // 尋找調試器進程 DWORD WINAPI ThreadFuncCallBack2(LPVOID lp) { while (TRUE) { CHAR NeedFindPName[20] = "vmtoolsd.exe"; if (FindProcess(NeedFindPName)) { MessageBox(0, "存在VM","提示", MB_OK); break; } } return 0; } int main() { // 方式1:搜索服務 -- 包含WMware Tools / WMware 物理磁碟助手服務 // CreateThread(NULL, NULL, ThreadFuncCallBack, NULL, NULL, NULL); // 方式2:找文件路徑 -- C:\Program Files\VMware\VMware Tools /* if (CheckVmByServe()) { MessageBox(0, "VM存在", "提示", MB_OK); return 0; } */ // 方式3:尋找進程 -- vmtoolsd.exe CreateThread(NULL, NULL, ThreadFuncCallBack2, NULL, NULL, NULL); while (true) { printf("RUN\n"); } system("pause"); return 0; }
在虛擬機中運行exe文件: