use*_*612 6 c++ focus virtual-machine detect
我有 2 个应用程序,每个应用程序都在各自独立的 MS Windows 7 虚拟机 (VM) 上运行。我无法为主机编写软件作为解决方案的一部分。我正在使用 Qt 使用 C++ 进行编码。
这可能不可能,但我希望能够检测虚拟机窗口何时具有焦点(不是应用程序窗口,而是虚拟机)。这两个应用程序都是全屏应用程序(至少在虚拟机内全屏),始终具有应用程序窗口焦点,但我希望能够在用户的键盘输入敲击键盘之前检测到他们将进入哪个虚拟机。钥匙。
有任何想法吗?
小智 7
没有 100% 的方法来识别 VM 与否。但有一些“指标”:
\n所有这些方法都不可靠,但被广泛使用。
\nVMware 提供了官方记录的虚拟机检测方法(带有代码片段)。\n有一种方法基于使用虚拟机管理程序端口 0x5658(“VX”)和虚拟机管理程序魔术 DWORD 0x564D5868(代表“VMXh”)
\nbool IsVMWare()\n{\n bool res = true;\n\n __try\n {\n __asm\n {\n push edx\n push ecx\n push ebx\n\n mov eax, \'VMXh\'\n mov ebx, 0 \n mov ecx, 10 // get VMWare version\n mov edx, \'VX\' // port number\n\n in eax, dx // read port\n // on return EAX returns the VERSION\n \n cmp ebx, \'VMXh\' // compare with target\n setz [res] // set return value\n\n pop ebx\n pop ecx\n pop edx\n }\n }\n __except(EXCEPTION_EXECUTE_HANDLER)\n {\n res = false;\n }\n\n return res;\n}\nRun Code Online (Sandbox Code Playgroud)\n另一种方法是测试 CPUID 管理程序 (HV) 存在位和 HV 供应商的名称:
\nbool IsVM()\n{\n int cpuInfo[4] = {};\n\n //\n // Upon execution, code should check bit 31 of register ECX\n // (the \xe2\x80\x9chypervisor present bit\xe2\x80\x9d). If this bit is set, a hypervisor is present.\n // In a non-virtualized environment, the bit will be clear.\n //\n __cpuid(cpuInfo, 1);\n \n\n if (!(cpuInfo[2] & (1 << 31)))\n return false;\n \n //\n // A hypervisor is running on the machine. Query the vendor id.\n //\n const auto queryVendorIdMagic = 0x40000000;\n __cpuid(cpuInfo, queryVendorIdMagic);\n\n const int vendorIdLength = 13;\n using VendorIdStr = char[vendorIdLength];\n\n VendorIdStr hyperVendorId = {};\n \n memcpy(hyperVendorId + 0, &cpuInfo[1], 4);\n memcpy(hyperVendorId + 4, &cpuInfo[2], 4);\n memcpy(hyperVendorId + 8, &cpuInfo[3], 4);\n hyperVendorId[12] = \'\\0\';\n\n static const VendorIdStr vendors[]{\n "KVMKVMKVM\\0\\0\\0", // KVM \n "Microsoft Hv", // Microsoft Hyper-V or Windows Virtual PC */\n "VMwareVMware", // VMware \n "XenVMMXenVMM", // Xen \n "prl hyperv ", // Parallels\n "VBoxVBoxVBox" // VirtualBox \n };\n\n for (const auto& vendor : vendors)\n {\n if (!memcmp(vendor, hyperVendorId, vendorIdLength))\n return true;\n }\n\n return false;\n}\nRun Code Online (Sandbox Code Playgroud)\n一些硬件检测方法的实现依赖于VM如何模拟CPU行为。例如,使用缓存指令,如wbinvd和invd,但它们是特权的。
\n一些阅读更多内容的链接:
\n有一篇关于虚拟机和沙箱检测的有趣文章有趣文章以及一些代码示例。
\n我找到了一个存储库,其中包含一些用 C 实现的方法。其中一些只能在 Windows 上使用,但也有一些跨平台的方法
\n那段代码应该可以完成工作
BOOL IsVMRunning()
{
#if _WIN64
UINT64 time1 = __rdtsc();
UINT64 time2 = __rdtsc();
return ((time2 - time1) > 500);
#else
unsigned int time1 = 0;
unsigned int time2 = 0;
__asm
{
RDTSC
MOV time1, EAX
RDTSC
MOV time2, EAX
}
return ((time2 - time1) > 500);
#endif
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8352 次 |
| 最近记录: |