基本概念
arm64e
基于ARMv8.3
架构,相对于arm64
增加了一系列功能,其中最重要的一个是:指针验签
ARMv8.3
在苹果A12
CPU
上可用(2018年9月以后发布的iPhone
机型,如iPhone XR/XS
)AArch64
是ARMv8-A
以后支持的一种64位运行模式
AArch32
是32位运行模式,早期的ARM架构都支持
指针验签
- 是一种安全防御机制
- 能保证控制流不被篡改(
CFI
),也提供有限的数据完整性保证 - 对程序运行过程中操作的指针内容进行签名,并在使用前验签,以防止被恶意篡改
解决的问题
- 内存溢出攻击
- 黑客在掌握内存溢出漏洞后,会试图修改间接跳转的指针地址以重定向到他指定的代码位置,然后通过
ROP
、JOP
等方式构造特定的指令执行序列来完成攻击流程
- 黑客在掌握内存溢出漏洞后,会试图修改间接跳转的指针地址以重定向到他指定的代码位置,然后通过
- 指针验签通过防止指针重定向来避免内存溢出攻击
攻击方式:
- 攻击者首先找到一系列需要的指令片段(
gadgets
)
- 攻击者希望执行以下指令:
- 攻击者实际找到的指令片段:
- 攻击者需要按一定的顺序调用这些指令片段,一般有以下两种方式:
ROP
(Return-Oriented Programming
):重定向方法return
时执行的目标,通过控制方法返回的顺序来控制执行流程JOP
(Jump-Oriented Programming
):重定向方法调用的目标,构造一系列方法跳转顺序来控制执行流程
工作原理
- 对所有的代码段指针都增加一段签名
- 部分数据段指针也会签名
- 在所有间接跳转前验签
- 数据段指针是在读内存前验签
- 签名数据存在指针数据的高位部分
- 指针一共
64
位,其中高位的25
位没有使用,就用这些位来存放签名数据 - 签名算法为:
hash(pointer, key, salt)
,其中:- key是有限的集合(
ABI
决定) - 主要变量在
salt
(ABI
决定),取决于:- 是否支持
地址多样性
salt
中含有存储指针的变量地址信息- 同一指针的不同实例也会有不同的签名
- 指针拷贝需要重新签名
- 与
memcpy
不兼容,导致拷贝开销增大
- 如何选择较小的常量数值
16
位整型常数- 对变量声明取
hash
- 对变量类型取
hash
- 是否支持
- 以下涉及跳转的代码都会受到验签保护(编译器决定)
return
- 盐值来自自栈指针(
sp
)哈希,整个进程唯一
- 盐值来自自栈指针(
c
函数指针- 盐值是所有进程唯一的,方便各进程共享库代码
switch
c++
虚函数- 盐值来自方法签名,所有
app
之间共享
- 盐值来自方法签名,所有
- 导入函数(
GOT
) - 其他
- key是有限的集合(
- 指针一共
- 签名、验签流程
- 指针内容(如:
c方法地址
) - 签名:根据签名算法得到签名,填充到指针数据高位
- 指令:
PACIA Xd, Xn
- 指令:
- 验签:取出高位的签名数据,验证后,将高位清零,使指针成为系统合法的指针
- 指令:
AUTDB Xd, Xn
- 指令:
- 指针内容(如:
编译生成产物和流程示意:
LLVM IR:
机器指令:
参考资料
最后,欢迎大家关注我的微信公众号,有空多多交流
今天的文章arm64e 架构简介——指针验签分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/17226.html