arm64e

义项:ARM 架构的指针认证指令集变体
arm64e

arm64e是苹果公司在AArch64(arm64)基础上定义的一种应用二进制接口(ABI)与体系结构变体,其核心特征是在硬件层面启用指针认证(Pointer Authentication),用它来检测和防范内存中指针被意外或恶意篡改[1]。它并非独立的指令集架构,而是编译成ARMv8.3-A及其后续版本中与指针认证相关指令的一套低层调用约定[2]。搭载Apple A12及更新处理器的设备在系统层面支持arm64e,苹果自身的内核、系统应用与共享缓存均以此架构编译[3]。

目录
  1. 定义
  2. 原理
  3. 发展历程
  4. 应用
  5. 局限
  6. 参见

定义

arm64e是苹果为AArch64(arm64)平台定义的一种应用二进制接口变体,它在保留原有arm64调用约定的同时,追加了指针认证(Pointer Authentication)相关的约定与指令[4]。严格来说,它属于ABI而非指令集架构(ISA),因为真正定义指令的是ARMv8.3-A对AArch64的扩展,arm64e只是在编译器与运行时层面规定如何使用这些指令[2]。由于arm64e包含arm64的全部能力,arm64e设备可以直接运行arm64二进制文件,反向则不成立[5]。

在苹果的构建工具链中,arm64e被实现为一个AArch64子架构,默认对应apple-a12处理器,从而能够生成指针认证代码[6]。

原理

指针认证的基本思路,是在存储指针之前,向指针中未被地址使用的若干高位写入一段加密签名,即指针认证码(Pointer Authentication Code,PAC);读取指针时再由另一条指令移除并校验该签名。两次访问之间对被存储值的任何改动都会令签名失效,CPU会把认证失败视为内存损坏,通过置位高位使指针失效,进而导致程序崩溃。

每段PAC由原始指针值、一个最多64位的修饰值(modifier)以及一枚硬件的128位密钥共同派生,可写作 $PAC = H_K(A_p, M)$,其中 $K$ 为密钥,$A_p$ 为指针地址,$M$ 为修饰值[7][8]。ARMv8.3-A为此提供了若干密钥,包括指令用A密钥、指令用B密钥、数据用A密钥与数据用B密钥;常见指令有用于签名的PACIA、PACIB与用于认证的AUTIA、AUTIB,以及把认证与跳转合并执行的BLRAA、BLRAB等[7][9]。

修饰值的选取决定了防护的粒度。若修饰值包含指针的存储地址,则同一指针存放在不同位置会得到不同签名,攻击者无法直接把指针复制过去使用;若使用常量修饰值,则可通过声明或类型派生,例如对声明文本或类型文本取哈希得到16位常量[10][11]。在arm64e的约定中,返回地址使用每进程唯一的密钥并以栈指针派生的盐值签名,函数指针使用跨进程固定的密钥,虚方法表条目则使用全应用共享的密钥并以方法签名派生盐值。

发展历程

指针认证的硬件能力源自ARM在Armv8.3-A中对AArch64的扩展,该扩展加入检测指针值被篡改的功能,用于缓解栈破坏等攻击并提高面向返回编程(ROP)的难度[12]。相关支持在GCC与LLVM/Clang中以返回地址签名选项的形式出现,并陆续进入ARMv8.3及其后续的架构规范[8]。

苹果自Apple A12处理器起在芯片中引入这一技术,A12即用于iPhone XR、iPhone XS等机型[1]。2018年发布的Xcode 10.1加入了对arm64e的预览支持,开发者可在目标的架构设置中加入arm64e以构建该切片,但当时的App Store与TestFlight不接受含arm64e内容的提交,分发时Xcode会移除相关内容。

此后随着PAC实现被发现弱点并被修复,苹果多次调整arm64e的ABI。iOS 14与Xcode 12(或clang 1200及更新版本)起,该ABI发生变更,新编译器产出的二进制与iOS 12.0至13.7上的arm64e实现不再兼容[13]。苹果自身的内核缓存、系统应用与整个动态链接共享缓存都以arm64e编译,而面向第三方的arm64e支持长期被认为尚未稳定[3]。

应用

arm64e主要运行在具备相应硬件的苹果平台上。使用Apple A12或更新A系列处理器的设备,例如iPhone XS、iPhone XS Max、iPhone XR与第二代Apple TV 4K,以及Apple Watch Series 4及更新机型、搭载Apple芯片的Mac与iPad均支持该架构。测试这类二进制必须在实体设备上进行,模拟器无法用于验证。

在系统层面,苹果把指针认证用于保护控制流:编译器会自动对间接分支相关的指针进行签名与认证,覆盖函数返回地址、C函数指针、C++虚函数以及经由全局偏移表(GOT)的符号导入等场景[11]。工具链还为确需手动处理的场景提供了ptrauth头文件与相关内建接口,用于剥离或重签指针。为兼顾新旧代码,应用可采用胖二进制的方式同时包含arm64与arm64e两个切片,以分别适配两套ABI[4]。

局限

指针认证只是一种近似的指针完整性机制,并不能提供完全的防护。攻击者可以通过重用已有的PAC来绕过校验,例如当两条函数返回地址使用相同的栈指针修饰值时,签名之间可能变得可互换[8]。在arm64e的实现中,常量修饰值被限制为16位,碰撞虽不常见但仍可能发生[10]。

签名机制也会对代码施加限制。当修饰值包含存储地址时,指针无法用memcpy这类逐字节复制的方式搬移,需要重新签名[11]。开启指针认证还可能暴露出既有代码中原本隐藏的问题,例如在C++中用与定义不同的声明调用虚方法,在arm64上往往能通过,在arm64e上却会触发认证失败。

此外,认证失败与其它非法内存访问的表象可能相似:高阶位被错误设置时,也可能表现出类似指针认证失败的症状,这给问题定位带来困难。ABI的多次调整也意味着不同版本工具链产出的arm64e二进制之间存在兼容性限制[13]。

参见

  • 指针认证 —— arm64e的核心机制,用于校验内存中的指针是否被篡改。

  • AArch64 —— arm64e所基于的64位ARM指令集体系结构。

  • 应用二进制接口 —— arm64e在概念上所属的范畴,规定二进制间的低层调用约定。

  • 控制流完整性 —— 指针认证常被用来实现的安全目标之一。

  • 面向返回编程 —— 指针认证着重提高其攻击难度的一类攻击方式。

  • Apple A12 —— 首个在硬件中包含指针认证支持、从而支持arm64e的苹果处理器。

参考资料

  1. [llvm-dev] [RFC] Pointer authentication for arm64e [引用日期2026-10-14]
  2. stackoverflow.com 上的网页 [引用日期2026-10-14]
  3. Revisions to Arm64e architecture for iOS framework [引用日期2026-10-14]
  4. JEP draft: Arm64e support for MacOS/AArch64 [引用日期2026-10-14]
  5. googlesource.com 上的网页 [引用日期2026-10-14]
  6. ToolChain [引用日期2026-10-14]
  7. iu.edu 上的网页 [引用日期2026-10-14]
  8. A! [引用日期2026-10-14]
  9. arm.com 上的网页 [引用日期2026-10-14]
  10. Pointer Authentication# [引用日期2026-10-14]
  11. What is arm64e? [引用日期2026-10-14]
  12. iu.edu 上的网页 [引用日期2026-10-14]
  13. arm64e Deployment - You signed in with another tab or window [引用日期2026-10-14]
词条评价
词条统计

浏览次数:4 次

阅读量:0 次 · 阅读完成量:0 次

最近更新:2026-10-13T21:00:57Z

历史版本

本条目引用的词条
指针认证 AArch64 应用二进制接口 控制流完整性 面向返回编程 Apple A12