上周,SentinelOne宣布了其v5.0代理的早期可用性,它成为第一个本机支持Apple的新M1(又名Apple芯片或arm64 Macs)体系结构的终端安全代理。与其他MacsOS的EDR/XDR安全解决方案不同,有了本机支持,Sentinel代理无需在Apple的翻译软件层(称为Rosetta 2)下运行。
在这篇文章中,SentinelOne的研究人员解释了在这个领域中所有热门术语的含义,从“Rosetta2”和“Apple Silicon”到“arm64 architecture”和“Universal 2”二进制文件,并解释为什么在Apple Silicon上本机运行安全软件具有明显的性能和安全优势。
去年,苹果公司宣布将为Macs设备构建自己的CPU,而不是依靠英特尔作为其处理器,这一消息轰动一时。这些新设备于2020年末开始发售,并通过多个代号与Intel Macs进行了区别。
苹果公司为推销他们的新设备创造的第一个术语是“Apple silicon”,意思是指基于ARM公司设计的芯片的CPU芯片。苹果授权基础设计,并自行设计。很明显,他们不想把自己的芯片标榜为是ARM芯片,而更愿意用一个独特的品牌名称“Apple silicon”来体现其品牌价值。
当然,苹果公司已经在iOS系统中使用他们自己定制的ARM芯片很多年了,并用“A”和数字说明符来进行编号,比如A10、A11、A12等等(当前版本的iOS系统搭载的是A14芯片)。大概是为了保持这种编号的规定,第一个Macs ARM芯片被编码为“M1”。随着苹果不断迭代设计,我们希望看到M2和M3等产品。因此,除了被称为“Apple Silicon Macs,苹果的第一代非英特尔设备也被称为“M1 Mac”。
这就有必要是我们研究二进制文件——可执行文件格式,它是苹果和第三方软件的基础,可以在这些新的M1芯片上运行。当然,这些必须有一个与CPU架构兼容的格式。在英特尔设备上,我们有x86_64 Macsh-O可执行文件;对于M1/Apple silicon Macs,本机二进制格式是arm64e Macsh-O。
因此,我们有一个基于ARM的M1/Apple硅处理器架构和运行在上面的arm64二进制文件。这似乎很简单,但有一个问题:过去15年或更长时间里为英特尔Macs电脑编写的所有软件呢?不要忽视这样一个事实:至少在未来的两年内,苹果仍在销售和生产带有英特尔芯片的Macs电脑。同时拥有两个完全不兼容的软件目录的两个硬件产品线是站不住脚的。苹果需要找到一种方法,让在英特尔设备上构建的软件能够在新的M1设备上运行。
输入Rosetta 2和通用文件格式。
英特尔、ARM和对翻译软件的需求
Rosetta这个名字源于著名的“Rosetta Stone”,正是这块石碑让我们得以将埃及象形文字翻译成现代语言。苹果原始的Rosetta软件实际上帮助公司在2000年代中期将早期的架构PowerPC转化为英特尔。
由于 M1 芯片底层架构和过去不同,由此带来的应用生态兼容性问题是首先需要解决的,为此苹果也开启了为期两年的 Mac 过渡计划。具体来说,苹果借助的是 macOS 11 Big Sur 系统以及其内置的 Universal 2、Rosetta 2 和 Virtualizaion 三种技术来解决问题。不过话虽如此,可能还是会有小伙伴会比较犹豫,这些措施真的可以解决 M1 芯片 Mac 的软件兼容性问题吗?特别是原来在 x86 架构上的应用,开发者还没有及时做适配,能在 Mac 上很好地运行吗?
对于这个问题,其实苹果已经给出了专门的解决方案,就是 Rosetta 2。
Rosetta 2 是内置在 macOS 11 Big Sur 系统里的,在幕后工作,只有当你第一次下载一款 x86 应用,第一次打开时,才会提示你安装 Rosetta 2。
换句话说,Rosetta 2 的存在完全不会对你过去一直以来使用 Mac 的习惯造成影响,它几乎是无感的,悄悄做着翻译工作。
想要知道你使用的 App 到底是原生在 Mac 上运行的,还是经过 Rosetta 2“翻译”之后的,只要在 “应用程序”文件夹中找到这个应用的图标,右键打开菜单栏里的 “显示简介”,如果应用种类后面有一个 “Intel”,说明这个应用就是 x86 版本经过 Rosetta 2 翻译的。
基于这样的机制,Rosetta 2 能够帮助 x86 架构的应用在 M1 芯片的 Mac 上保持流畅快速的响应,从而获得很好的使用体验。
当然,Rosetta 2 做翻译的方案毕竟只是权宜之计,不会一直存在,只是在开发者们将自己的应用全面转到 M1 芯片原生状态之前扮演过渡的作用。
当时,Rosetta的研发者使用了一种通用的文件格式,它是一种“FAT”二进制文件,其中包含PowerPC和Intel二进制文件。无论CPU是PowerPC还是Intel,操作系统都从FAT通用二进制文件中提取正确的文件,并在CPU上本机运行它。但是,如果Intel CPU遇到只有PowerPC二进制文件的软件,它将执行Rosetta转换器,并将PowerPC二进制文件传递给Rosetta执行。
对于M1 Mac,苹果采取了类似的方法:开发者(比如SentinelOne)使用Universal 2二进制格式在一个版本中发布他们软件的Intel和arm64版本。使用Universal 2二进制格式,操作系统会检查它运行在哪个体系结构上,并自动选择适当的arm64(适用于M1 Mac)或Intel(适用于x86_64)片来执行。然而,如果M1 Mac遇到尚未进行本机转换的开发人员提交的Intel二进制文件,它就会将二进制文件传递给Rosetta 2转换机制来处理。
按着苹果公司的说法,整个过程对用户来说应该是“透明的”,在这里“透明”的意思是“不可见的”,而不是“明显的”。然而,Rosetta 2的工作方式与原始的Rosetta并不完全相同,这对性能和安全都有影响,用户应该注意这一点。
新的体系结构意味着终端安全性面临新的挑战
原始的Rosetta和Rosetta 2的主要区别在于进行翻译的时间。对于Rosetta 2,苹果希望避免在原始Rosetta机制下影响一些严重消耗资源的软件的性能问题,比如Adobe CS2。
最初的Rosetta的问题在于,每次运行该软件时都会翻译该软件,从而在每次启动时都反复给CPU造成负担。 Apple采用Rosetta 2的方法是,通过在软件首次启动时进行“提前”(AOT)翻译并将该翻译保存以供将来发布,来尽可能地避免这种情况。
虽然这是一种改进仿真软件性能的好方法,但也有缺点,特别是从安全软件的角度来看。
相对于翻译后的代码,本机arm64代码至少具有两个性能优势,而翻译后的代码与大型,复杂的程序(例如EDR产品)特别相关。
我们上面提到的Ahead-of-Time转换是通过名为oahd_helper的帮助程序进行的。该程序负责在首次运行x86_64二进制文件时创建转换后的AOT二进制文件。要翻译的x86_64代码的大小越大,启动时间越长。当需要oahd_helper转换非常大的Intel可执行文件时,这又会导致设备上的内存和CPU占用过多。
其次,对于需要在运行时解析的复杂程序代码的某些部分,无法进行完整的AOT转换。由于局部环境变量和条件的原因,有时直到运行时才能确定需要运行什么代码。虽然理论上开发人员可以提前编译所有可能的代码分支,但这既效率低下又容易出错。必要时确定运行什么代码并即时进行编译(即时编译或JIT编译)的效率和防错性要高得多。
在其他条件相同的情况下,当你在本机处理器上运行本机代码时,JIT编译是没问题的,但当代码必须通过Rosetta进行翻译时,这意味着尽管使用了AOT编译,但仍然需要进行一些即时编译。当这种情况发生时,内核将控制权转移给一个特殊的Rosetta翻译存根,由它来处理这项工作。简而言之,任何足够复杂的程序(如EDR解决方案)都需要通过Rosetta实时翻译至少一部分Intel代码,而与运行本机arm64代码的安全解决方案相比,这种翻译将导致性能损耗。
苹果也在自己的官方文件中也提到了这一事实:
“翻译过程需要时间,所以用户可能会认为翻译后的应用程序有时会启动或运行得更慢。”
通过设计,本机M1软件更安全
但是性能并不是唯一需要担心的事情。更重要的是,本机M1代码比通过Rosetta翻译运行英特尔代码更安全。这是因为macOS Big Sur(acOS Big Sur是苹果公司研发的桌面端操作系统,于北京时间2020年6月23日在2020苹果全球开发者大会上发布,该操作系统适用于一部分Mac电脑。)带来的变化之一只适用于Apple silicon Macs,即本机arm64代码不能在M1 Mac上执行,除非它有有效的代码签名。
除非附加了有效的签名,否则Apple Silicon Mac在任何情况下都不允许执行本机arm64代码。但是,翻译后的x86_64代码不受此限制:翻译后的x86_64代码完全可以通过Rosetta执行,而没有任何签名信息。
你可以在M1 Mac上用一个简单的“hello world”程序轻松验证这一点。如果首先将下面的程序编译为arm64e,请注意操作系统在尝试执行时是如何阻止它的,但是一旦我们重新编译了与x86_64可执行文件相同的源文件,就可以在没有代码签名且没有代码的情况下运行hello.out:
这就允许了软件篡改的可能性,即通过Rosetta(Rosetta)翻译仅以英特尔二进制代码运行的软件,其代码签名可能被删除,代码被修改,程序在没有有效开发者代码签名的情况下通过Rosetta(Rosetta)执行。
尽管尝试进行此类攻击的攻击者还有其他障碍需要清除,但仍然存在这样的情况:在M1 Mac上,本机arm64代码比翻译后的Intel代码在本质上更安全,因为后者无需进行任何代码签名检查就可以运行。
这自然就引出了一个问题:Rosetta本身是否可以用作攻击媒介。尽管所有组件都通过系统完整性保护进行了锁定,但Rosetta是一个多方面且复杂的机制,由许多联锁部件组成,每个部件都有潜在的攻击面。
在Rosetta的某些部件上,研究人员已经完成了一些初始的、出色的逆向工程,但关于这个转换层还有很多需要了解的地方,研究仍在进行中。
总结
毫无疑问,苹果在Rosetta 2上比原始Rosetta有了长足的进步,这也许可以解释为什么某些软件开发人员尚未进行过渡,也许还不了解本机M1支持的优势。其他开发人员可能更愿意让他们的解决方案在Rosetta下运行,以利用他们尚未或无法转换为ARM的旧式Intel模块的优势。
但是,如上所述,出于性能和安全方面的考虑,在Apple芯片上本机运行安全软件的好处显而易见。就像在其他地方,苹果可能会在某些地方禁用Rosetta 2,而不会引起人们的注意。最后,同样不可避免的是,正如最初的Rosetta在苹果最终完全从Intel的PowerPC架构过渡过来之后的几年就停产了,苹果最终将放弃对Apple silicon平台上的翻译软件的支持。
本文翻译自:
https://www.sentinelone.com/blog/why-your-macos-edr-solution-shouldnt-be-running-under-rosetta-2/