Windows 10任务管理器如何检测虚拟机?

gol*_*lum 7 windows virtualization reverse-engineering virtual-machine windows-10

Windows 10任务管理器(taskmgr.exe)知道它是在物理机还是虚拟机上运行.

如果查看" 性能"选项卡,您会注意到处理器标签的数量是读取逻辑处理器:虚拟处理器:.

此外,如果在虚拟机内运行,还有标签虚拟机:是.

请参阅以下两个屏幕截图:

taskmgr本地处理器

taskmgr虚拟处理器

我的问题是,如果有一个记录的API调用taskmgr用于进行这种检测吗?

我非常简短地看一下反汇编,似乎检测代码与GetLogicalProcessorInformationEx和/或IsProcessorFeaturePresent和/或NtQuerySystemInformation有某种关系.

但是,我没有看到(至少没有花费更多时间来分析汇编代码).

并且:这个问题是IMO与其他现有问题无关,如何检测我的程序是否在虚拟机内运行?因为我没有看到任何代码试图将smbios表字符串或cpu供应商字符串与管理程序典型的现有已知字符串("qemu","virtualbox","vmware")进行比较.我不排除较低级别的API实现可以做到这一点,但我没有在taskmgr.exe中看到这种代码.

更新:我还可以排除taskmgr.exe正在使用CPUID指令(EAX = 1并检查ECX中的管理程序位31)来检测矩阵.

更新:仔细看看反汇编表明确实检查了第31位,显然没有那么做.

我将在下面自己回答这个问题.

gol*_*lum 10

我已经从Windows 10 1803(OS Build 17134.165)中分析了x64 taskmgr.exe,方法是回写写入到设置虚拟机:是标签的位置的内存位置.

负责该变量的值是函数的返回码 WdcMemoryMonitor::CheckVirtualStatus

以下是cpuid此函数中第一次使用该指令的反汇编:

lea     eax, [rdi+1]                 // results in eax set to 1
cpuid
mov     dword ptr [rbp+var_2C], ebx  // save CPUID feature bits for later use
test    ecx, ecx
jns     short loc_7FF61E3892DA       // negative value check equals check for bit 31
...
return 1
loc_7FF61E3892DA:
// different feature detection code if hypervisor bit is not set
Run Code Online (Sandbox Code Playgroud)

因此taskmgr不使用任何硬件字符串,mac地址或一些其他复杂技术,而只是检查是否设置了管理程序位(CPUID叶0x01 ECX位31)).

结果当然是假的,因为例如添加-hypervisor到qemu的cpu参数会禁用管理程序cpuid标志,导致任务管理器不显示虚拟机:是的.

最后是一些示例代码(在Windows和Linux上测试)完全模仿Windows任务管理器的测试:

#include <stdio.h>

#ifdef _WIN32
#include <intrin.h>
#else
#include <cpuid.h>
#endif

int isHypervisor(void)
{
#ifdef _WIN32
    int cpuinfo[4];
    __cpuid(cpuinfo, 1);
    if (cpuinfo[2] >> 31 & 1)
        return 1;
#else
    unsigned int eax, ebx, ecx, edx;
    __get_cpuid (1, &eax, &ebx, &ecx, &edx);
    if (ecx >> 31 & 1)
        return 1;
#endif
    return 0;
}

int main(int argc, char **argv)
{
    if (isHypervisor())
        printf("Virtual machine: yes\n");
    else
        printf("Virtual machine: no\n"); /* actually "maybe */

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • 感谢发布调查结果 (2认同)
  • 完善!这是来自VMWare的文档,描述了叶子0x01 ECX位31:https://kb.vmware.com/s/article/1009458 - 确切地说你已经找到了. (2认同)