bool CheckVMware1() { __asm { rdtsc xchg ebx, eax rdtsc sub eax, ebx cmp eax, 0xFF jg detected } return FALSE; detected: return TRUE; }
HKEY_CLASSES_ROOT\\Applications\\VMwareHostOpen.exe
。bool CheckVMware2() { HKEY hkey; if (RegOpenKey(HKEY_CLASSES_ROOT, "\\Applications\\VMwareHostOpen.exe", &hkey) == ERROR_SUCCESS) { return TRUE; } else { return FALSE; } }
vmtoolsd.exe
。bbool CheckVMware3() { 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((const char *)pe32.szExeFile, "vmtoolsd.exe") == 0) { return TRUE; } bMore = Process32Next(hProcessSnap, &pe32); } CloseHandle(hProcessSnap); return FALSE; }
C:\Program Files\VMware\VMware Tools\
。bool CheckVMware4() { if (PathIsDirectory("C:\\Program Files\\VMware\\VMware Tools\\") == 0) { return FALSE; } else { return TRUE; } }
bool CheckVMware5() { //打開系統服務控制器 SC_HANDLE SCMan = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE); if (SCMan == NULL) { printf("%ld", GetLastError()); 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; }
int main() { int n; bool result; while (1) { printf("虛擬機檢測技術:\n"); printf("1. 基於CPU運算時間的檢測\n"); printf("2. 基於註冊表的檢測\n"); printf("3. 基於當前進程信息的檢測\n"); printf("4. 基於特定文件的檢測\n"); printf("5. 基於註冊服務的檢測\n"); printf("0. 退出\n"); printf("請選擇:"); scanf("%d", &n); flushall(); printf("檢測結果:"); switch (n) { case 0: return 0; case 1: result = CheckVMware1(); break; case 2: result = CheckVMware2(); break; case 3: result = CheckVMware3(); break; case 4: result = CheckVMware4(); break; case 5: result = CheckVMware5(); break; default:printf("輸入錯誤,請從新輸入!\n"); Sleep(2000); system("cls"); continue; } if (result) printf("yes!\n"); else printf("no!\n"); printf("按任意鍵返回主菜單\n"); getch(); flushall(); system("cls"); } return 0; }
主要編寫2個文件:checkvm.dll
與testvm.exe
,下面分2部分詳細介紹。安全
checkvm.h
、checkvm.cpp
、dllmain.cpp
、Source.def
bool chekvm();
bool checkvm() { int num = 0; if (CheckVMware1()) num++; if (CheckVMware2()) num++; if (CheckVMware3()) num++; if (CheckVMware4()) num++; if (CheckVMware5()) num++; if (num >= 4) { printf("This is a virtual machine!\n"); return FALSE; } else { printf("This is not a virtual machine!\n"); return TRUE; } }
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; }
LIBRARY "checkvm" EXPORTS checkvm @1
checkvm.dll
所編寫,調用checkvm.dll
中的checkvm()
函數便可,詳細代碼以下:int main() { HMODULE hmod = LoadLibrary("checkvm.dll"); //用於加載dll typedef int(*LoadProc)(); LoadProc Load_proc = (LoadProc)GetProcAddress(hmod, "checkvm"); //GetProcAddress()用於得到函數地址 int iRet = Load_proc(); getchar(); return 0; }
checkvm.dll
便可。