打开网易新闻 查看精彩图片

2023年,一个Mac管理实习生发现:M1/M2芯片上同时开3个macOS虚拟机,系统会直接报错。不是性能不够,是苹果在系统深处埋了计数器,超过2就拦死。

这条限制写在macOS软件许可协议的2.B.iii条款里,白纸黑字:每台Mac最多跑2个额外的macOS虚拟实例。但协议是一回事,技术怎么实现是另一回事。这位实习生想搞清楚——苹果到底在哪层代码里卡脖子?

用户层翻了个底朝天,限制根本不在那

用户层翻了个底朝天,限制根本不在那

他的第一反应是查Virtualization.framework,苹果官方虚拟化框架的所在地。/System/Library/Frameworks/Virtualization.framework,路径很直观,错误信息也是从这抛出来的。

但macOS Big Sur之后,苹果把框架合并进了dyld共享缓存,直接打不开。他用了Hopper Disassembler,把二进制从缓存里抠出来,逐行扫了几个小时。结论很挫败:错误信息确实来自框架,但"最多2台"这个数字, nowhere to be found。

框架里只有抛错的逻辑,没有计数的逻辑。就像你收到了快递拒收短信,但仓库根本没登记过你家地址——有人在更上游拦截了。

线索来自Hack Different Discord的jevinskie:去XNU内核里找,而且是Apple Silicon专属的那部分。Intel内核没有这条限制,对比两个版本的差异,能快速定位。

内核里的硬编码:2被写死在初始化函数里

内核里的硬编码:2被写死在初始化函数里

他把macOS Sonoma Beta 4的开发内核(版本号23A5301h)丢进IDA Pro,目标很明确:找Intel和Apple Silicon内核都有的VM相关函数,但实现不同的。

很快锁定hv_vm_*系列函数,苹果虚拟化栈的核心入口。其中hv_init()是初始化代码,一进去就看到了关键逻辑:

打开网易新闻 查看精彩图片

内核用了一个叫hv_app的变量,类型是int,初始值直接写成2。不是读配置文件,不是查许可证,是代码里硬编码的整数2。

这个变量在系统启动时初始化,之后每次创建虚拟机实例,内核就检查当前活跃VM数量是否小于hv_app。等于2的时候,第三个请求直接拒绝,返回错误码。

他做了进一步验证:修改开发内核里的这个整数值,重新签名加载,限制果然跟着变。改成5就能开5台,改成0就直接封死虚拟机功能。这不是策略层的技术限制,是有人把政策翻译成了if语句。

为什么苹果要锁这么死?

为什么苹果要锁这么死?

从技术角度看,Apple Silicon的虚拟化架构和Intel时代完全不同。M1/M2用ARM架构,苹果的虚拟化实现高度依赖硬件辅助虚拟化扩展,内存带宽和CPU核心分配都需要专门优化。

但2台这个数字明显不是性能瓶颈。M1 Ultra有20核CPU、128GB统一内存,跑2个轻量虚拟机连10%资源都吃不满。苹果选2,是因为SLA里写了2,技术实现直接对标法律文本。

对比Intel Mac的历史:苹果从未在Intel内核里硬编码虚拟机数量限制。同一台MacBook Pro,Intel时代用第三方虚拟化软件能开多少开多少,只要硬件扛得住。Apple Silicon时代,这个自由被收回了。

更深一层,Virtualization.framework是苹果强制推行的唯一官方路径。Parallels、VMware、UTM这些第三方工具,底层全部调用苹果的框架。框架锁死,整条链路都锁死。这不是生态开放,是管道垄断。

破解的可能性与代价

破解的可能性与代价

发现硬编码位置后,技术破解的路径其实很清晰:改内核、重签名、关闭系统完整性保护(SIP)。对于越狱社区和内核研究者,这套流程并不陌生。

打开网易新闻 查看精彩图片

但代价极高。Apple Silicon的启动链有安全启动(Secure Boot)和签名校验,修改内核需要把机器降到Permissive Security模式,每次系统更新都要重新打补丁。企业环境不可能接受,个人用户也风险自担。

更现实的方案是绕过:用Asahi Linux这类第三方系统,完全脱离苹果虚拟化栈。但那就跑不了macOS guest,对于需要测试多版本macOS的开发者,是条死胡同。

这位实习生的发现被整理成技术博客后,在社区引发了两极反应。一部分人兴奋于"终于找到病根",另一部分人沮丧于"苹果连这点自由度都不给"。

UTM项目的维护者在GitHub issue里回应:我们知道限制在哪,但绕过它等于和苹果打核战争,项目承担不起法律风险。开源社区能复现问题、能定位代码,但不敢动那个整数。

对比行业的开放与封闭

对比行业的开放与封闭

虚拟机数量限制不是苹果独有,但硬编码到内核的做法极为罕见。微软Hyper-V有类似的许可限制,但 enforcement 在管理工具层,换用PowerShell或第三方工具就能突破。VMware ESXi的vRAM限制曾引发众怒,但好歹是许可证服务器控制,企业买够授权就能解锁。

苹果的做法是把政策写进操作系统的心脏。你买了硬件、买了软件,但运行权限被一行代码裁定。这不是技术架构选择,是控制权宣言。

对于开发者群体,影响很具体:CI/CD流水线需要并行测试多个macOS版本,2台上限意味着要么买更多Mac mini做集群,要么接受串行测试的延迟。苹果官方的解决方案是Xcode Cloud,按分钟计费的托管服务——限制本地虚拟化,同时出售云端替代方案。

商业模式上说得通,但技术社区的感受是:我的机器,我不能完全控制。Apple Silicon的性能优势被生态锁定的代价对冲,这笔账每个人算法不同。

这位实习生的3个月探索,最终没有产出可用的破解工具。但他把定位过程完整公开,包括IDA的函数地址、内核版本差异、调试技巧。对于想继续深挖的人,这是一张地图。

苹果在macOS Sonoma后续版本里有没有移动这个硬编码的位置?有没有改成动态读取配置文件?社区还在跟踪。但内核代码的闭源属性意味着,每次系统更新都要重新逆向,这是一场不对称的消耗战。

你手里如果有M1/M2 Mac,现在就可以验证:开两个macOS虚拟机,正常;开第三个,报错信息弹出来。那个2不是建议值,是操作系统里的物理定律——至少在你动手修改内核之前。