百科问答小站 logo
百科问答小站 font logo



操作系统能否知道自己处于虚拟机中? 第1页

  

user avatar   qlf2012 网友的相关建议: 
      

目前虚拟机环境检测有两个“金标准”,分别是Al-khaserPafish。这两个开源项目几乎一网打尽了所有公开常见的VM检测技术。下面简要分析一下它们的技术原理。

一、硬件信息检测

首先大概说说操作系统是怎么知道这台计算机安了哪些设备的。计算机启动的时候,主板固件会给OS传两个信息表,分别是ACPI和SMBIOS。ACPI表有很多部分,其中硬件信息主要集中在DSDT和SSDT这两部分。

ACPI表的每个部分开头都有一个OEM ID和OEM Table ID,这是第一个容易露馅的地方,例如QEMU默认将OEM ID写为BOCHS,将OEM Table ID写为BXPC + 部分名称,如DSDT部分就写成“BXPCDSDT”。

虚拟机的ACPI表中往往会存在一些现实中不存在的硬件,用于主客机间通讯,这是第二个容易露馅的地方,例如QEMU的DSDT表中会有DBUG和FWCF这两个硬件。

计算机中大部分设备的信息并不写在ACPI和SMBIOS表中。像显卡、声卡、网卡、USB这些都属于PCI设备,与PCI控制器相连。PCI控制器本身提供一个接口,可以列出所有检测到的PCI设备。每个PCI设备有四个用来亮明身份的代号,分别是Vendor ID, Device ID, Subsystem ID, Class ID。一般来说,OS检测到PCI设备时,会首先根据Vendor ID和Device ID搜索驱动;如果搜不到驱动,则会根据Class ID查找是否有这一类设备的通用驱动。

虚拟机模拟出的PCI设备,其身份代号往往采用特定数字,这是第三个容易露馅的地方,例如QEMU模拟出的VirtIO设备,其Vendor ID多为0x1AF4。

相比于ACPI,SMBIOS对系统的正常运行没有那么重要。但是Windows的“系统信息”工具显示的内容,多半都来自SMBIOS表,这是第四个容易露馅的地方,例如目前主流的虚拟机固件是OVMF,那么虚拟机里面“系统信息”就会显示出OVMF的信息。

有些恶意软件会通过检测系统是否有风扇和热区域(Thermal Zone)来判断是否处于虚拟环境。目前所有版本的Windows,都是从SMBIOS表中读取风扇信息,从ACPI表中读取Thermal Zone信息。但是正常的商业软件一般不使用此方法判定,因为很多正常的笔记本电脑也没有在SMBIOS表中写入风扇信息。

此外还有硬盘产品名、序列号、声卡ID、网卡MAC地址等容易带有虚拟机特征的地方。

二、CPU信息检测

x86 CPU本身有一条指令叫CPUID,用于探测该CPU所支持的功能,例如是否支持SSE指令集等。有些功能虚拟机无法模拟,就会屏蔽掉相关功能的信息,这是第五个容易露馅的地方

早期虚拟化技术不完善的时候,虚拟机软件需要挪动一些重要数据结构的位置,例如中断表(IDT)等。著名的Red Pill程序就是靠读取这些结构的地址来判定虚拟环境。但是后来有了Intel VT-x等硬件虚拟化技术,以及KVM以后,这些检测方法就基本被淘汰了。

基于KVM的客机,如果将EAX寄存器置为0x40000000,并执行CPUID指令,会在EBX、ECX、EDX寄存器中读取到字符串“KVMKVMKVM”,这是第六个容易露馅的地方

三、驱动信息检测

在有Linux KVM之前,各虚拟机软件用的几乎都是半虚拟化(Paravirtualization),也就是必须对客机软件做一定修改才能在虚拟机中正常运行。例如VMWare虚拟机需要在客机中安装一些驱动程序,这些驱动的信息中都带有VMWare标识,这是第七个容易露馅的地方

KVM实现的是全虚拟化,不需要对客机做任何修改,所以不必担心这些问题。但是,按默认配置的QEMU虚拟机会带有很多VirtIO接口的设备,这些设备的驱动也会留下虚拟机的痕迹,需要当心。

四、计时检测

x86 CPU中有一个精度极高的计时器,称为TSC计时器,可以精确到CPU时钟周期数。那么可以执行一段CPU指令,并将消耗的时间与正常CPU上消耗的时间进行对比,如果明显高于正常值,就可判定处于虚拟机环境。

目前最常用的方法是,在两次读取TSC计时器之间,执行一次CPUID指令。前文说到,虚拟机软件一般会特殊处理CPUID指令,屏蔽掉一些无法模拟的功能的信息,执行这些操作所需的时间远多于正常CPU上执行一次CPUID所需的时间,这是第八个容易露馅的地方

目前没有简单的办法可以骗过计时检测,所有已知方案都需要用特制的Linux内核和特制的QEMU软件配合。


但是近几年来,虚拟机环境检测已经没那么重要了。这是因为微软在Windows 10上大力推广Hyper-V技术,有相当数量的用户自己都不知道自己处于虚拟机环境。例如,只要在Windows 10 Home的Windows Defender中开启Memory Integrity或Core Isolation功能,就等同于开启Hyper-V,并让Windows运行在虚拟机环境下。

于是有很多网游反作弊系统,只要检测到开启了Hyper-V,就放弃检测虚拟机环境。于是在Linux界就有了一种神奇的操作,先用KVM开Windows虚拟机,然后在Windows中开启Hyper-V,这样就能愉快地玩各种3A巨作了。

当然这种操作需要CPU和Hypervisor支持Nested Virtualization,然而Windows的Hyper-V长期以来不支持AMD的Nesting,会在启动时卡死。直到2020年6月,微软才宣布Windows 10 Insider的Hyper-V开始支持嵌套虚拟化。最近国外Reddit上有人报告使用5.11.6版本的Linux内核(无需打补丁),配合4.2版本的QEMU,可以在AMD系统上正常启动Windows 10 20H2并开启Hyper-V,可能是Linux KVM那边做了改进。


既然这么多人看我就再写一写怎么绕开这些虚拟机检测方法。我日常电脑装的是Linux,平时用Linux KVM + QEMU方案跑Windows虚拟机。QEMU是开源的虚拟机Hypervisor,命令行参数非常灵活,有另一个开源项目libvirt专门帮助配置QEMU的参数。下面的内容都是基于KVM + QEMU + libvirt。我从简单的操作写起,比较难隐藏的东西放到后面。

1)CPU信息:打开libvirt的XML配置,找到<cpu>段落,将mode设为host-passthrough,然后段落里面添加一行

       <feature policy="disable" name="hypervisor"/>     

找到<os>段落,里面添加一行

       <smbios mode="host"/>     

2)KVM Hypervisor信息:XML配置中找到<features>段落,里面添加几行

       <hyperv>   <vendor_id state="on" value="random"/> </hyperv> <kvm>   <hidden state="on"/> </kvm>     

3)硬盘产品名、序列号:将Disk bus设为SCSI,Serial随便填写,添加一个SCSI Controller,Model填为saslsi1068,然后在XML配置中找到<disk>段落,在里面添加几行

       <vendor>Samsung</vendor> <product>20GB Harddisk</product>     

此处Vendor和Product可随便填写

4)网卡:NIC Device Model选rtl8139,然后用这个网站随机生成一个MAC地址填进去。

5)QEMU硬编码的ID信息:修改这些ID有两种方法,一种是下载QEMU源代码,修改硬编码ID后重新编译;另一种是直接用radare2等二进制修改工具,在QEMU可执行文件上打补丁。下面列出应当隐藏的硬编码ID对应的代码位置。(QEMU源代码见github

ACPI OEM ID:见hw/acpi/aml-build.c中的build_header函数

ACPI DSDT中的FWCF设备:见hw/i386/acpi-build.c中的build_dsdt函数

ACPI DSDT中的DBUG设备:见hw/i386/acpi-build.c中的build_dbg_aml函数

常规PCI设备ID:见hw/pci/pci.c中的pci_set_default_subsystem_id函数

VGA设备ID:见hw/display/vga-pci.c中的vga_pci_class_init函数

声卡ID:见hw/audio/hda-codec-common.h中所有含有QEMU_HDA_ID_*宏的数据结构

VirtIO Serial设备ID:见hw/virtio/virtio-serial-pci.c中的virtio_serial_pci_class_init函数

6)风扇和热区域:利用QEMU的-acpitable参数,伪造一个ACPI SSDT表,里面填入一个Thermal Zone的信息;再利用QEMU的-smbios参数,伪造一个SMBIOS Entry Type 27,里面填入一个风扇的信息。

ACPI标准第11.7节提供了ACPI Thermal Zone的例子

SMBIOS标准第7.28节提供了SMBIOS Entry Type 27的格式说明

7)计时检测:这个绕过很麻烦,需要重新编译Linux内核,主要原理是每当遇到CPUID这种需要Hypervisor专门处理的指令时,都把TSC计时器的当前值减掉一定量,这样就抵消掉处理这些指令花掉的时间。

详见Reddit上相关讨论:
reddit.com/r/VFIO/comme
reddit.com/r/VFIO/comme
reddit.com/r/VFIO/comme


user avatar   liu-yimo-49 网友的相关建议: 
      

我从网络安全的角度作答。

“如何防止操作系统或软件知道自己处于虚拟机中?”

答案很简单:不使用虚拟机!

想象这样一种情境:我想从网上下载某个免费软件,但我被杀毒软件警告,该免费软件包含病毒。由于我非常需要这个免费软件,遂决定冒险一试。为防止病毒对主机造成伤害,我利用 Oracle VM 创建了一个虚拟机,希望在虚拟机中测试这个免费软件。

请注意:在虚拟机中测试软件无法100%保证主机安全

原因是有些恶意软件具备从虚拟机中逃逸的能力,即“反虚拟机技术(anti-virtual machine techniques)”。

唯一安全的办法是使用另一台物理隔离的计算机进行测试。该计算机不联网,不保存任何个人信息或重要文件,不做任何其他用途,只用于测试。

另外,不要依赖系统还原,那样做依然存在感染风险。


user avatar   haozhi-yang-41 网友的相关建议: 
      

根据软硬等价原理,如果虚拟机刻意这么做,一定可以骗过os。

但似乎没有虚拟机去费这劲做这些无聊的事情。


user avatar   x-secure 网友的相关建议: 
      

一大早起来真是笑死我了。

由于老头环空前的热潮,以及B站特有的UP主靠制作视频吸引流量转直播的模式,导致很多有人气但完全没有魂系列经验的主播在播这款游戏。比如某幻、瓶子。

(就是一开始制作视频是主业,直播是兼职,甚至是乐趣兴趣,到直播为主,制作视频反倒成了兼职。这种现象在游戏区特别明显。)

这就很有节目效果了,我看几个有名气的主播,都是重复被虐,平均活不过5分钟。真正是在哪里跌倒就从哪里跌倒。

很多在我们这些老玩家看来常识性的东西,对于他们来说完全不存在的。

盾反这种就不提了(其实我也不会),连二人转、回合制、推图都不懂。在大型地牢里不想打小怪,一个劲往前跑,结果变成开火车;当着怪物的面喝药=白喝;开宝箱被怪物背刺;以为学了法术就是法爷了,结果被几只鸟打得抱头鼠窜。

然后另一边,那些原本有魂系列经验的主播,就吃了刻板印象的亏。觉得自己有技术有实力,也不练级就顺着主线硬钢。就比如一上来的野外精英太阳骑士,要么你死要么我亡,绕路是不可能绕路的。

太阳骑士都还好,毕竟王老菊都能杀。

但没有等级,没有血量,没有伤害,硬钢噩兆。

真当噩兆快慢刀是假的,自己打几次就能盾反了?而且老头环这次砍了盾反在BOSS战中的作用,要反三次(二次)才能触发处决。

结果被虐3000遍,又不好意思去练级,尬在那了。

老头环是不是玩家的盛宴我还不知道(买了游戏,昨天也预下载了,结果今天起来发现那个盘满了……正在重新下载,下载完了又发现,我的电脑只有8G内存……),但肯定是不少主播的灾难、观众的盛宴。

当然,我也知道有些主播直播受罪是搞节目效果,但我也是真看到有主播被气到下播了。

另外一点,老头环这次其实是以探索为主要玩法。

B站UP主老戴今天专门做了一期视频讲解,想要玩好、玩轻松,就是尽可能的探索地图,拿物品、刷等级。而不是走到哪杀到哪,打不过硬去打。

就比如第一个剧情BOSS前,大地图上有的是小型地牢,野外精英,要把图清完了再去打噩兆,真跟打弟弟一样。(收回我的话,40级30血20耐20敏+3打刀7瓶奶,打了7次才过。前三次就是纯背板,后三次有点贪,经常血瓶白喝,最后一次基本掌握出手时机,就硬耗过去了。)

其实魂系列游戏特别吃角色强度(等级、装备),一些小怪你一刀砍死和一刀残血,完全就是两种难度。打BOSS,你挨一下就要喝药,和挨两下才需要喝药也是两倍的差距。

不过按照这么个玩法,的确没有什么节目效果。

讲真,还真就是看那些新手主播无能狂怒最有节目效果。

至于游戏本体,如今我也的确是玩上了,总体上来说符合我的期待。

作为一个中年人,我其实是在看了老头环试玩视频后才接触魂系列的。

原因有2,一是手残反映慢,玩这种游戏非常苦手;二是,我其实不太喜欢魂系列那种压抑的黑暗风格。

但老头环作为开放世界,虽然依旧以压抑阴郁为主,但也有光明广阔的场景。比如一开始做完新手指引推门而出的那一刻。

至于在难度与操作方面,远程技能的实用化,召唤物的存在,以及跳砍与伪盾反的出现,真的能够解决很多问题。

只是看你愿不愿意当一个“卑鄙的褪色者”。

远程技能包括法术与射击。我玩的武士,初始给的长弓非常给力。尤其记得推一座城堡图的时候,一开始不清楚套路,进入城堡被满地的炸药桶与两个放火球的法师直接秒了。复活后掏出长弓,一剑封喉,解决掉法师无伤过了。

还有初期的一个地牢,一个场景墙上爬着的与左右墙角蹲着的类似地精的怪物,近战5-6刀才能砍死。

第一次去直接围殴致死。

第二次,用弓箭一只只引过来,很轻松就过了。

至于近战武器,我是非常推荐初期见完老婆就能开箱子拿到的君王大剑。

这把武器虽然攻速低,成长性也低,但在初期真的非常实用。

尤其是在跳劈方面。

这一作跳劈虽然强但也看武器,比如武士上来给的打刀就属于跳劈对空,跳起来横着劈一刀,有时候都打不到站着的怪。而大剑则是竖着往地上砸,范围极大。

我举一个例子,就是我开地图第一次遇到红灵。就是等对方打完一套跳劈就完了。

我的战斗策略就是,遇事不决,举盾防御,然后跳劈。

至于BOSS战,依旧有难度,也许跳劈和法术都没啥作用,依靠的依旧是精准的闪躲后普攻(排除盾反)。

但我觉得这算是魂系列的乐趣之一。

如果随便什么BOSS战都能逃课,那也就没意思了。




  

相关话题

  为什么 macOS 上有流畅的 Windows 虚拟机,后者却没有流畅的 macOS 虚拟机? 
  计算机执行一条指令要多长时间? 
  在程序运行后,调试打断点时,反汇编看到的是虚拟地址还是物理地址? 
  如何实现一个安全的thread.stop的api? 
  如何评价微软官宣将会在 6.24 发布下一代 Windows 操作系统的信息? 
  龚神给微软 Linux 子系统写的支持 DirectX 9、11的代码到底属不属于“驱动”? 
  从小学习的都是linux系统,linux系统是全球主流。世界将会是什么样子? 
  如果现在微软重写Windows会怎么样? 
  Linux 为什么还要坚持使用宏内核? 
  被很多人不断坚持攻击的鸿蒙,为什么我的末流211操作系统老师在吹? 

前一个讨论
Nike 发布「禁用新疆棉花」的声明,在实际消费中,耐克会被抵制到什么程度?
下一个讨论
如何评价《戴森球计划》?





© 2025-01-08 - tinynew.org. All Rights Reserved.
© 2025-01-08 - tinynew.org. 保留所有权利