endbr64 指令实际上做了什么? [英] What does the endbr64 instruction actually do?

查看:144
本文介绍了endbr64 指令实际上做了什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试理解 GCC 生成的汇编语言代码,并且在包括 _start() 在内的许多函数的开头经常遇到此指令,但找不到任何说明其用途的指南:

I've been trying to understand assembly language code generated by GCC and frequently encounter this instruction at the start of many functions including _start(), but couldn't find any guide explaining its purpose:

31-0000000000001040 <_start>:
32:    1040:    f3 0f 1e fa             endbr64 
33-    1044:    31 ed                   xor    ebp,ebp

推荐答案

endbr64(和 endbr32)是 英特尔的控制流强制技术 (CET)(另见 英特尔软件开发人员手册,第 1 卷,第 18 章).

endbr64 (and endbr32) are a part of Intel's Control-Flow Enforcement Technology (CET) (see also Intel Software Developer Manual, Volume 1, Chapter 18).

英特尔 CET 提供针对面向返回编程 (ROP)Jump/Call-oriented Programming (JOP/COP) 攻击,操纵控制流程,以便将现有代码重用于恶意目的.

Intel CET offers hardware protection against Return-oriented Programming (ROP) and Jump/Call-oriented Programming (JOP/COP) attacks, which manipulate control flow in order to re-use existing code for malicious purposes.

它的两大特点是

  • 一个影子堆栈,用于跟踪返回地址和
  • 间接分支跟踪,endbr64 是其中的一部分.
  • a shadow stack for tracking return addresses and
  • indirect branch tracking, which endbr64 is a part of.

虽然 CET 只是在当前一代处理器中慢慢变得可用,但它已经被支持从 GCC 8 开始,默认插入 endbrXX 指令.操作码在较旧的处理器上被选择为无操作,因此如果不支持 CET,则该指令将被忽略;在禁用间接分支跟踪的支持 CET 的处理器上也会发生同样的情况.

While CET is just slowly becoming available with the current processor generation, it is already supported as of GCC 8, which inserts endbrXX instructions by default. The opcode is chosen to be a no-op on older processors, such that the instruction is ignored if CET is not supported; the same happens on CET-capable processors where indirect branch tracking is disabled.

那么 endbr64 有什么作用?

前提条件:

  • 必须通过将控制寄存器标志 CR4.CET 设置为 1 来启用 CET.
  • IA32_U_CET(用户模式)或 IA32_S_CET(主管模式)MSR 中设置用于间接分支跟踪的适当标志.
  • CET must be enabled by setting the control register flag CR4.CET to 1.
  • The appropriate flags for indirect branch tracking in the IA32_U_CET (user mode) or IA32_S_CET (supervisor mode) MSRs are set.

CPU 设置一个小型状态机来跟踪最后一个分支的类型.以下面的例子:

The CPU sets up a small state machine which tracks the type of the last branch. Take the following example:

some_function:
    mov rax, qword [vtable+8]
    call rax
    ...

check_login:
    endbr64
    ...
authenticated:
    mov byte [is_admin], 1
    ...
    ret

现在让我们简要地看一下两种情况.

Let's now briefly look at two scenarios.

无攻击:

  1. some_function虚方法表 vtable 并调用它.
  2. 由于这是一个间接调用,CET 状态机被激活并设置为在下一条指令上触发 (TRACKER = WAIT_FOR_ENDBRANCH).
  3. 下一条指令是endbr64,因此间接调用被认为是安全的";并继续执行(endbr64 仍然表现为无操作).状态机被重置(TRACKER = IDLE).
  1. some_function retrieves the address of the virtual method check_login from the virtual method table vtable and calls it.
  2. Since this is an indirect call, the CET state machine is activated and set to trigger on the next instruction (TRACKER = WAIT_FOR_ENDBRANCH).
  3. The next instruction is endbr64, so the indirect call is considered "safe" and execution continues (the endbr64 still behaves as a no-op). The state machine is reset (TRACKER = IDLE).

攻击:
攻击者以某种方式设法操纵 vtable,使得 vtable+8 现在指向 authenticated.

Attack:
An attacker somehow managed to manipulate vtable such that vtable+8 now points to authenticated.

  1. some_function 从虚方法表vtable 中检索authenticated 的地址并调用它.
  2. 由于这是一个间接调用,CET 状态机被激活并设置为在下一条指令上触发 (TRACKER = WAIT_FOR_ENDBRANCH).
  3. 下一条指令是 mov byte [is_admin], 1,而不是预期的 endbr64 指令.CET 状态机推断控制流被操纵并引发 #CP 错误,终止程序.
  1. some_function retrieves the address of authenticated from the virtual method table vtable and calls it.
  2. Since this is an indirect call, the CET state machine is activated and set to trigger on the next instruction (TRACKER = WAIT_FOR_ENDBRANCH).
  3. The next instruction is mov byte [is_admin], 1, not the expected endbr64 instruction. The CET state machine infers that control flow was manipulated and raises a #CP fault, terminating the program.

如果没有 CET,控制流操作将不会被注意到,攻击者将获得管理员权限.

Without CET, the control flow manipulation would have gone unnoticed and the attacker would have obtained admin privileges.

总而言之,英特尔 CET 的间接分支跟踪功能确保间接调用和跳转只能重定向到以 endbr64 指令开头的函数.

In summary, the indirect branch tracking feature of Intel CET ensures that indirect calls and jumps can only redirect to functions which start with an endbr64 instruction.

请注意,这不能确保调用正确的函数 - 如果攻击者更改控制流以跳转到以 endbr64<开头的其他函数/code> 同样,状态机不会抱怨并继续执行程序.然而,这仍然大大减少了攻击面,因为大多数 JOP/COP 攻击目标指令是中间函数(甚至直接跳转到"指令).

Note that this does not ensure that the right function is called - if an attacker changes control flow to jump to a different function which starts with endbr64 as well, the state machine won't complain and keep executing the program. However, this still greatly reduces the attack surface, as most JOP/COP attacks target instructions mid-function (or even jump right "into" instructions).

这篇关于endbr64 指令实际上做了什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆