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

Windows 10任务管理器如何检测虚拟机?,windows,windows-10,virtual-machine,reverse-engineering,virtualization,Windows,Windows 10,Virtual Machine,Reverse Engineering,Virtualization,Windows 10任务管理器(taskmgr.exe)知道它是在物理机还是虚拟机上运行 如果查看“性能”选项卡,您会注意到“处理器数量”标签的内容为逻辑处理器:或虚拟处理器: 此外,如果在虚拟机内运行,则还有标签virtual machine:Yes 请参见以下两个屏幕截图: 我的问题是,taskmgr是否使用有文档记录的API调用进行此类检测 我对反汇编做了一个简短的观察,似乎检测代码与and/or和/或有某种关联 但是,我不知道该怎么做(至少在不花更多时间分析汇编代码的情况下是这样)

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

如果查看“性能”选项卡,您会注意到“处理器数量”标签的内容为逻辑处理器:或虚拟处理器:

此外,如果在虚拟机内运行,则还有标签virtual machine:Yes

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

我的问题是,taskmgr是否使用有文档记录的API调用进行此类检测

我对反汇编做了一个简短的观察,似乎检测代码与and/or和/或有某种关联

但是,我不知道该怎么做(至少在不花更多时间分析汇编代码的情况下是这样)

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

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

更新:仔细查看反汇编显示确实有一个位31的检查,只是显然没有这样做


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

我已经分析了Windows 10 1803(OS Build 17134.165)中的x64 taskmgr.exe,方法是追溯到在设置虚拟机:Yes标签时参考的内存位置的写操作

负责该变量值的是函数的返回代码
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
因此,taskmgr没有使用任何硬件字符串、mac地址或其他复杂技术,只是检查是否设置了虚拟机监控程序位(叶0x01 ECX位31))

结果当然是假的,因为例如,将
-hypervisor
添加到qemu的cpu参数中会禁用hypervisor cpuid标志,从而导致task manager不再显示Virtual machine:yes

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

#包括
#ifdef_WIN32
#包括
#否则
#包括
#恩迪夫
int isHypervisor(无效)
{
#ifdef_WIN32
int-cpuinfo[4];
__cpuid(cpuinfo,1);
如果(cpuinfo[2]>>31和1)
返回1;
#否则
无符号整数eax、ebx、ecx、edx;
__获取cpuid(1,&eax,&ebx,&ecx,&edx);
如果(ecx>>31&1)
返回1;
#恩迪夫
返回0;
}
int main(int argc,字符**argv)
{
if(isHypervisor())
printf(“虚拟机:是\n”);
其他的
printf(“虚拟机:否”;/*实际上“可能”*/
返回0;
}

@CodeCaster我不这么认为。至少我在代码中没有看到任何提示,表明它试图将smbios表数据或供应商字符串与已知虚拟化字符串(qemu、vmware等)相匹配。Taskmgr在函数u int64 WdcMemoryMonitor::CheckVirtualStatus()中使用CPUID来检查状态。@magicandre1981是和否。
CheckVirtualStatus()
将CPUID用于多项检测任务(例如签名、制造商ID字符串)但只有一次EAX=1,在这种情况下,只分析ECX的第5位以检查VMX扩展。缺少的VMX标志不是虚拟机的合适指示器。好的,我只与IDA进行了简短的查看,没有检查EAX值means@magicandre1981尽管如此,你是对的。我错过了它,因为我关心它对eax位移位进行了测试,但没有注意到在该函数中首次使用CPUID之后出现了测试ecx的jns,ecx与测试位31相同;)完美!以下是VMWare的文档,描述了叶0x01 ecx位31:-您是如何发现的。