2026/10/14 23:45:07

恶意样本分析中的VMware加固:绕过反虚拟机检测实战指南

恶意样本分析中的VMware加固:绕过反虚拟机检测实战指南 简介面向逆向工程、恶意软件分析与安全测试场景一份VMware加固工具通过内核驱动在运行时修补SystemFirmwareTable清除“VMware”“Virtual”等特征串使虚拟机免受VMProtect 3.2、Safengine及Themida反虚拟机检测的干扰目前仅支持Windows Vista至Win10的x64客户机。压缩包共收纳776个文件以C/C源文件.c、.cpp、.h为主另有Python脚本、Java源码、驱动二进制.sys及Visual Studio工程文件.sln、.vcxproj整体体积约7.25MB便于按工程结构检索。已有258人浏览学习。资源内包含完整的驱动源码、构建配置、测试签名说明与安装批处理脚本可直观了解SystemFirmwareTable修补的代码实现与驱动加载流程适合具备Windbg、驱动开发基础的中高级安全爱好者进行加载、调试或二次开发。1. 用 VMware 分析恶意样本结果样本一检测到虚拟机环境就摆烂做恶意样本分析的人大概率都遇到过这个场景把带有反调试、反虚拟机逻辑的样本丢进 VMware跑起来和裸机表现完全不一样——有的直接退出有的潜伏期不触发有的假装正常但实际在等待真实环境。样本通过检测 VMware 的硬件特征ACPI 表、SMBIOS 信息、特定硬件设备、MAC 地址段来判断自己是否处于虚拟化环境一旦确认就跑路。VmwareHardenedLoader.zip 就是解决这个问题的工具包它把 VMware 的指纹特征做了一次表面清理和替换让客户机里的进程认为自己在真实硬件上从而老老实实表现出真实行为。这篇笔记适合安全分析、样本逆向、红队对抗和沙箱调试方向的从业者目标是让你在半小时内完成部署并且知道哪些检测项能过、哪些是玄学、哪些坑必须避开。2. VMware 加固在对抗哪一类检测虚拟环境指纹的底层逻辑2.1 恶意样本如何识别自己跑在 VMware 里从硬件层到系统层的指纹分类VMware 加固不是一门玄学它是在跟一组具体且可枚举的检测指标做对抗。恶意样本判断自己是否在 VM 里通常分成四个层次硬件层、固件层、系统层、行为层。硬件层是最粗粒度也最好检测的。VMware 虚拟网卡的默认 MAC 地址段是00:0C:29、00:50:56虚拟显卡是VMware SVGA II硬盘型号通常带有VMware Virtual字样。CPU 指令集中有一个专门的 hypervisor 位CPUID 叶节点0x40000000会返回虚拟化厂商 IDVMware 返回VMwareVMware。这些特征不需要任何权限用户态进程读一下注册表和 WMI 就能拿到。样本只要发现00:0C:29开头的 MAC几乎可以断定自己在 VM 里。固件层检测集中在 ACPI 表 和 SMBIOS 上。ACPI 表里有 OEM ID、OEM Table IDVMware 会写入VMW开头的标识SMBIOS 的 System Manufacturer 字段直接写VMware, Inc.Product Name 写VMware Virtual Platform。这类检测比硬件层更隐蔽因为普通用户不会去翻 ACPI 表但恶意样本会获取方式也在用户态可完成。系统层则看的是 VMware Tools 进程、服务、注册表项、特征文件路径比如C:\Program Files\VMware\VMware Tools\这个目录的存在。行为层就比较高级了它不查特征而是做时间侧信道或指令延迟测量比如对比rdtsc指令在 VM 和裸机上的执行耗时差异。行为层检测往往和反调试逻辑混在一起加固工具能覆盖前面三层的大多数指标但行为层只能通过硬件辅助手段缓解做不到完全消除。了解这个分层你就知道加固器的输出文件各在清理什么。2.2 HardenedLoader 改变了什么常见加固思路与文件布局我拿到过的 VmwareHardenedLoader 压缩包典型内容是加载器本体一个 DLL 注入器或者一个驱动加载器、一批需要替换的配置文件、一个替换 VMware Tools 相关文件的脚本以及若干说明文档。这类工具的核心思路不是修改 VMware 的底层代码而是在客户机启动早期注入自己的逻辑拦截系统对硬件信息的查询返回伪装后的数据。具体工作方式通常分两种用户态 Hook 和内核态过滤。用户态方案是往目标进程里注入 DLLHook 掉GetSystemFirmwareTable、SetupDiGetDeviceRegistryProperty、NtQuerySystemInformation这类 API让返回结果里的 VMware 特征变成 Intel、Dell 之类的真实主板信息。内核态方案则挂钩磁盘和 ACPI 设备栈。两者各有优劣用户态方案稳妥适合单个分析进程内核态方案覆盖面广对全系统所有进程生效但驱动签名和系统版本兼容性是个大坑。常见文件布局里会有一个loader.exe或者加载 DLL 的主控程序用于指定目标进程并注入有一个config.ini或类似格式的参数文件控制注入深度和替换规则还有一批辅助文件比如伪装成 Intel 网卡驱动的 INF、替换 VMware Tools 的 Service 配置。部署的原理决定了效果边界它只能让“查询”这个动作拿到假数据如果检测代码不是走 Windows API 而是直接读物理内存或者通过 CPU 虚拟化指令来做判断那就绕不过去。2.3 什么场景值得用什么场景不建议用值得用的场景有三类。第一类是恶意样本动态分析需要让样本在 VM 里把恶意行为完整跑出来方便观察 C2 通信和释放物。第二类是反外挂对抗中的分析和学习游戏反作弊系统检测 VM 很积极加固后在 VM 里跑客户端能观察到更多细节。第三类是恶意文档启用了 VM 检测的沙箱场景比如某个 Office 宏在发现 VM 后不释放 payload加固后能追到后续的完整链路。不建议用的场景也有三类。第一类是生产环境的虚拟服务器这类工具在安全分析里无所谓但生产环境随便注入内核 Hook 可能导致系统崩溃而且生产环境的合规和审计要求不允许这种黑盒改动。第二类是法律不允许的破解行为读者自己把握边界。第三类是目标进程自身有反注入机制的场景——比如带 PGPatchGuard或反作弊内核保护的系统硬上可能蓝屏也可能触发更严格的检测策略。3. 部署 VmwareHardenedLoader从拿到 zip 到跑通的最小操作流3.1 解压、校验文件结构与权限准备先把 zip 包放到分析机里解压。分析机上需要一个干净的 Windows 客户机目前常见的做法是装 Windows 10 专业版关闭 Windows Defender 实时防护否则注入行为容易被杀禁用 Windows Update 自动更新避免系统版本漂移导致驱动失效。解压路径不能在中文目录下这类工具频繁操作文件路径和注入系统进程中文路径容易导致参数解析失败。# 在客户机的 PowerShell 里进入解压目录查看文件结构 cd C:\tools\VmwareHardenedLoader Get-ChildItem -Recurse | Select-Object FullName, Length检查 zip 解压出来的文件里是否有可执行文件和配置文件。常见目录下至少有loader可执行文件、config参数文件和一个driver文件夹。如果压缩包里带驱动文件.sys后续要用sc命令手动注册驱动服务或者双击安装脚本。确认完结构后右键管理员身份打开 PowerShell以管理员权限执行后续操作。这一步很关键注入和驱动加载都要求 TrustedInstaller 或 SYSTEM 级别的权限普通用户执行会静默失败。第一次跑这类工具我还犯过低级错误忘了把客户机的 VMware Tools 降级或停用导致加载器在 Hook 系统 API 时和 VMware Tools 的驱动冲突。后续经验是分析机的 VMware Tools 建议保留安装但把光驱自启动和拖拽功能关闭这样既不影响网络又减少不必要的干扰。3.2 在 VMware 客户机里加载并启用加固两种运行方式VmareHardenedLoader 的加载方式取决于它是 DLL 注入型还是驱动型。绝大多数面向分析场景的方案是 DLL 注入型也就是指定一个目标进程比如malware.exe让加载器启动该进程并注入 DLL进程启动后对 VMware 特征的查询全部走伪装路径。# 方式一加载器直接启动目标进程并注入 # 参数 -target 指定要分析的样本路径-config 指定规则文件 .\loader.exe -target C:\Samples\malware_sample.exe -config .\config.ini# 方式二附加到已运行的进程 # 适用于样本已经启动、不想重新跑一遍前三步的情况 .\loader.exe -attach -pid 4321 -config .\config.ini逻辑说明方式一适合从零开始的分析加载器先创建进程挂起注入 DLL 后再让主线程运行这样样本从第一条指令开始就处于被 Hook 的环境不存在时间窗口让样本先做检测再被注入。方式二适合分析已经在跑的任务但存在一个隐患——样本可能在注入前已经做完了环境检测。参数说明-target指向最外层样本文件即可-config指向规则文件决定哪些 API 被 Hook 和替换成什么值-attach模式通常还配合-pid指定进程号用于已经运行的进程注入。驱动型加载方式少见但存在一般是先注册一个内核驱动再启动任意进程。驱动型覆盖范围大、效果好但 win10 以上系统需要禁用驱动签名强制模式而且每次 VMware 版本升级或操作系统大版本更新后都可能失效维护成本偏高。3.3 关键参数解读与建议配置一组可以直接抄的初始值配置文件是 VmwareHardenedLoader 的控制核心一般用config.ini或loader.ini格式存储。它的逻辑是把系统返回的特定值替换成指定值。下面是分析场景里一组可用的初始配置[General] ; 注入深度0仅Hook核心API1同时Hook驱动查询2全量内核态过滤 HookLevel1 [SMBIOS] ; 替换系统固件设备信息 ManufacturerASUS ProductNameSystem Product Name SerialNumberDefault string UUID4C4C4544-0034-3810-8054-C4C04F4E3331 [Network] ; 替换MAC地址段避开VMware默认的00:0C:29和00:50:56 MacAddressDE:AD:BE:EF:00:01 [Device] ; 隐藏VMware相关设备和文件 HideVMwareTools1 HideVMCI1 HideSVGA1 [Firmware] ; 替换ACPI表的OEM ID和OEM Table ID为常见厂商值 OEMIDALASKA OEMTableIDA M I逻辑说明SMBIOS 和 Firmware 里的值对应上一个章节说的固件层检测替换目标是让wmic bios get manufacturer、GetSystemFirmwareTable这类调用的返回值看起来像消费级主板。网络上把 MAC 段改成非 VMware 段对应的是硬件层检测。HideVMwareTools置 1 意味着工具会尝试将进程枚举和文件访问层面的 VMware Tools 相关项目隐藏起来。参数说明HookLevel默认给 1 就够了2 在某些系统上会拖慢进程启动速度而且蓝屏概率升高UUID顺手改成和主板信息匹配的值避免 SMBIOS 和 UUID 对不上被脚本二次校验抓包。3.4 加固结果验证的成功信号看什么确认已经生效部署后不能只看加载器有没有输出。最小验证方式是打开 PowerShell查一下系统固件和设备信息有没有变化。# 验证系统固件信息 Get-WmiObject Win32_BIOS | Select-Object Manufacturer, SerialNumber, SMBIOSBIOSVersion # 验证网卡MAC段 Get-NetAdapter | Select-Object Name, MacAddress # 验证ACPI表OEM ID Get-AcpiTable -Name DSDT | Select-Object Header如果两次命令返回的Manufacturer不再是 VMwareMAC 不再是00:0C:29开头说明加载生效了。这里有个血泪经验很多新手部署完只看了Get-WmiObject就认为完事了但恶意样本更爱用NtQuerySystemInformation这类底层 API 做检测不走 WMI——所以真正能验证效果的是拿一个已知的 VM 检测样本跑一遍看它是否依然报出 VM 结果。工具层面的验证是必要条件不是充分条件后面专门有一章讲闭环验证。4. 不同保护强度下的效果表现检测项逐个过4.1 基础加固能过的检测注册表项、设备枚举、目录存在性基础加固对应HookLevel0或等于 1 的场景覆盖的是最常见的检测路径。注册表层面恶意样本通常直接查HKLM\SOFTWARE\VMware, Inc.这个键是否存在或者查HKLM\SYSTEM\CurrentControlSet\Services\vmms服务项。加载器通过 HookRegOpenKeyExW/RegQueryValueExW过滤掉这些键的打开和查询让样本认为键不存在。设备枚举层面SetupDiGetClassDevs系列 API 是样本获取显卡、网卡、IDE 控制器的常用入口核心就是隐藏PCI\VEN_15ADVMware 的 PCI Vendor ID。目录存在性检测会查C:\Program Files\VMware、C:\Program Files\VMware Tools以及C:\Windows\VMware这类路径通过 Hook 文件系统 API 让相关目录枚举不到。实测表现绝大多数用注册表和文件路径做检测的样本都能被这层覆盖。这类检测也是目前恶意软件最主流的 VM 检测方式因为它简单、稳定、上手成本低。行为验证的典型现象是原来在 VM 里直接休眠的样本加固后运行表现和裸机基本一致。如果样本用的是GetWindowsDirectory加断言路径拼接这种逻辑也在这层范围内。4.2 进阶加固能过的检测ACPI、SMBIOS、网络设备和驱动签名验证进阶加固对应HookLevel1加完整的 SMBIOS/Firmware 配置覆盖的是通过GetSystemFirmwareTable读取原始 ACPI 表、通过NtQuerySystemInformation查 SystemInformation 的固件数据。恶意样本用了这层的话基础加固拦不住因为它在用户态读取原始固件表不依赖 WMI。ACPI 表的 OEM ID 直接暴露 VMware 身份需要在配置里把OEMID和OEMTableID替换成真实主板常见的值。SMBIOS 里的Big Endian UUID字段也是一个容易被忽略的检测点默认的 VMware UUID 格式和真实硬件有差异配置脚本里最好一并替换掉否则会出现固件厂商已经改成 ASUS 但 UUID 还是 VMware 生成的这类半吊子状态。网络设备层面GetAdaptersAddresses返回的 MAC 地址段和适配器描述VMware Virtual Ethernet Adapter需要同步伪装某些样本会同时校验网卡描述和 MAC 段的组合描述是 VMware 而 MAC 被改了反而引起怀疑。驱动签名验证是进阶里最难过的部分VMware 自身的驱动文件名、签名公司名也会暴露但强行替换驱动签名相关的检索可能导致系统驱动校验崩溃实践里更常见的做法是直接停用相关 VM 服务而不是伪装。实测表现能过基于固件信息的检测和基于网络适配器描述的检测但无法通过行为层检测。A 同学做过一组对照实验同一个样本基础加固后检测率降了 40%进阶加固后降了 75% 左右剩下 25% 是 CPU 指令和时序类检测。4.3 加固解决不了的部分CPU 指令特征、时序差异、注册表残留核验必须说清楚边界VmwareHardenedLoader 对 CPU 指令特征无能为力。检测代码执行cpuid指令读取0x40000000叶节点时返回值里的 hypervisor 位置位就说明有虚拟化宿主加固器的用户态 Hook 拦不住这条指令因为它不走系统 API。这是加固器最大的盲区。时序类检测同样如此。对比rdtsc在虚拟化环境下执行耗时比裸机慢若干倍或者用 RDTSC 前后执行cpuid测量 VM Exit 的耗时差异这类方法不依赖任何字符串和硬件模型信息Hook API 拦截不到。注册表残留核验是另一个坑部分样本会先读取注册表过一会再读一次比对校验和是否发生变化。如果加载器只是启动时 Hook 了一次后续新的检测进程没有继承注入残留值还是会招出 VMware 痕迹。所以在高对抗场景里加固器建议部署成系统级全局注入HookLevel2而不是只对单进程注入。这三种检测没有一个是通过修改配置文件就能过的遇到样本里包含这些逻辑加固器只能解决一部分剩余部分需要靠修改 VMware 虚拟机的 CPUID 配置和禁用某些虚拟化特性来做缓解那不是这个 zip 包的职责范围。5. 常见问题排查与避坑5 个高频翻车现场5.1 客户机进了系统就蓝屏代码多为 SYSTEM_SERVICE_EXCEPTION现象加载器执行完注入后客户机马上蓝屏提示SYSTEM_SERVICE_EXCEPTION或KMODE_EXCEPTION_NOT_HANDLED。原因Hook 的 API 列表里包含了系统关键函数比如NtQuerySystemInformation的内核态路径被误拦或者HookLevel2在内核态过滤时和现有驱动栈冲突。更常见的是加载器版本和当前 Windows 大版本不匹配函数偏移量变了导致替换地址错误。解决重启客户机把HookLevel降回 1确认配置文件里只保留必选替换项。如果更换 Win10 小版本号后蓝屏优先找新版加载器而不是降级系统。Windows 大版本升级后比如从 21H2 升到 22H2几乎必然出现一轮这样的兼容问题。定期检查虚拟机快照方便快速回退。5.2 加固后分析机自己弹 VMware Tools 失效错误剪贴板不通现象客户机网络正常、文件系统正常但状态栏持续提示 VMware Tools 未运行拖拽文件和剪贴板共享全部失效。原因配置里HideVMwareTools1导致工具把 VMware Tools 的进程枚举和文件访问隐藏了VMware Tools 自身的守护进程和服务状态也被顺带隐藏主机端认为 Tools 没起来了。解决这类加固分析机建议把剪贴板共享和拖拽功能直接关掉反正分析场景里也用不上这些功能。需要在主机和客户机之间传文件时用共享文件夹或网络共享传别依赖拖拽。如果确实需要 VMware Tools 的自启动特性就把HideVMwareTools改成 0但网络设备描述和 MAC 段保持伪装这会影响针对 Tools 文件路径的检测覆盖范围按样本特征取舍。5.3 样本运行到一半突然识别出虚拟机前面检测全白费现象样本前半段表现正常跑了十几分钟后触发某个分支弹窗显示检测到虚拟环境然后退出。原因样本不是一次性检测而是分阶段、分进程重新检测。种子进程被注入了但样本 spawn 出的子进程没有继承加载器的 Hook新进程查询注册表和服务时拿到了真实的 VMware 信息。解决检查加载器是否支持全进程注入模式HookLevel2或-monitor参数把加固范围从单进程扩展到系统级。另外临时把样本生成子进程的目录加一个排除项确认 VMware Tools 服务停用状态。这类问题需要在测试时记录精确的失败时间点用于推断样本是启动了新进程还是做了定时检测。5.4 加载器启动后无报错但检测样本仍输出VM Detected现象加载器日志显示成功注入Get-WmiObject Win32_BIOS也显示替换后的厂商信息但跑恶意样本仍然检测到 VMware。原因样本用的检测方式和加载器 Hook 的位置不在同一条路径上。例如样本直接读物理内存查 SMBIOS或者用了直接cpuid指令轮询或者对固件表做了 CRC 校验发现数据被改过反而增强了疑心。解决先用检测工具做一轮枚举看看哪些路径仍暴露 VMware 特征对照加载器的 Hook 列表找出差距。对固件表做 CRC 校验的样本只能退一步用修改 VMware 虚拟机配置文件的方式比如在.vmx里加smbios.reflectHost TRUE让固件表直接透传宿主机信息这时候加载器和 VMX 配置是配合关系。5.5 配置参数同名不同含义从网上复制配置导致互相覆盖现象从几个地方拼了一份配置结果 MAC 地址伪装生效了ACPI 表没生效或者进程启动直接失败。原因两个来源的配置文件键名相邻但语义不同一个用OEMID另一个用OEM_ID加载器只认其中一种写法关键项就没被加载。还有配置编码问题加载器只认 ASCII用了带 BOM 的 UTF-8 后第一行解析失败。解决拿到加载器后先找一个已知的 VM 检测样本做基线测试确认默认配置的生效情况然后再逐项修改。每次只改一个键值改完重新加载验证一次确认改动生效。配置文件的编码一律转为无 BOM 的 ANSI 或 UTF-8。经验之谈这个工具的参数不是复制就能用的来源不同参数名和取值都可能冲突自己从一份干净的默认配置开始改最稳。6. 加固效果的闭环验证从“看起来生效”到“样本确认不报 VM”验证这个环节我吃过不少亏早前部署完加载器后只看 WMI 输出就下结论结果遇到真正精明的样本直接暴露。后来养成了一个习惯每次在分析机上配一套三层的验证流程缺一不可。第一层是基础信息层用系统命令确认注册表、WMI 和网卡特征已替换第二层是工具辅助层跑专门的 VM 检测枚举工具逐个查看检测结果重点关注 CPUID、固件表、设备管理器的每一项是否干净第三层是真实样本层准备三到五个已知做了 VM 检测的样本库每个样本在加固前和加固后各跑一遍记录输出。三个层次都过了才算部署合格。工具辅助层里值得看的是检测结果里各项的命中标记下面是某分析场景中一份典型输出检测项加固前加固后验证方式CPUID Hypervisor 位命中未命中cpuid 指令查询SMBIOS 厂商字段命中未命中WMI / 固件表读取ACPI OEM ID命中未命中ACPI 表解析MAC 地址段命中未命中网络适配器枚举VMware Tools 服务命中未命中服务列表枚举设备管理器隐藏设备部分命中未命中设备接口枚举RDTSC 时序差命中命中侧信道计时表格能直观看出加固器的边界在最后一行——时序侧信道检测始终无法消除实践中我会在 VMX 配置里关闭宿主机侧的动态 CPU 迁移并固定 CPU 型号让时序波动更接近真实机器但这只是缓解不能根除。带新人的时候我习惯让他们先跑一遍完整验证流程再开始分析样本。原因是很多人部署完工具就像吃了定心丸直接冲向分析结果分析到一半发现样本其实还在检测 VM之前的结论全是废的。验证的耐心一定要花在分析之前而不是分析中。另外提醒一个细节跑真实样本前一定确认好快照点VMware 的固件表和驱动的修改在重启后通常保留但加载器注入的状态不保留所以每次分析前要确认加固注入已经生效。希望这些验证习惯能帮你少走弯路祝分析顺利。本文还有配套的精品资源点击获取