首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >endbr64指令的实际作用是什么?

endbr64指令的实际作用是什么?
EN

Stack Overflow用户
提问于 2019-07-05 23:28:00
回答 2查看 23.6K关注 0票数 59

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

代码语言:javascript
复制
31-0000000000001040 <_start>:
32:    1040:    f3 0f 1e fa             endbr64 
33-    1044:    31 ed                   xor    ebp,ebp
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-09-17 15:49:25

endbr64 (和endbr32)是Intel's (CET)的一部分(另请参阅Intel Software Developer Manual, Volume 1, Chapter 18)。

英特尔CET提供针对Return-oriented Programming (ROP)Jump/Call-oriented Programming (JOP/COP)攻击的硬件保护,这些攻击会操纵控制流,以便出于恶意目的重新使用现有代码。

它的两个主要特性是

  • 用于跟踪返回地址和
  • 间接分支跟踪的shadow stackendbr64是其中的一部分。

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

那么endbr64做了什么呢?

Preconditions:

必须通过将控制寄存器标志CR4.CET设置为1来启用

  • CET。
  • 设置了IA32_U_CET (用户模式)或IA32_S_CET (管理程序模式)MSR中间接分支跟踪的相应标志。

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

代码语言:javascript
复制
some_function:
    mov rax, qword [vtable+8]
    call rax
    ...

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

现在让我们简要地看一下两个场景。

无攻击:

  1. some_function从下一条指令中检索虚拟方法(TRACKER = WAIT_FOR_ENDBRANCH).
  2. The check_login的地址并调用它。virtual method table vtable由于这是一个间接调用,

状态机被激活,并设置为在下一条指令时触发,下一条指令为endbr64,因此间接调用被认为是“安全的”,并继续执行( endbr64仍表现为无操作)。状态机被重置为(TRACKER = IDLE).

攻击:

攻击者以某种方式操纵了vtable,使vtable+8现在指向authenticated

  1. some_function从虚拟方法表(TRACKER = WAIT_FOR_ENDBRANCH).
  2. The authenticated中检索vtable的地址并调用它。
  3. 由于这是一个间接调用,CET状态机被激活并设置为在下一条指令时触发,下一条指令是mov byte [is_admin], 1,而不是预期的endbr64指令。CET状态机推断控制流被操纵并引发#CP错误,从而终止程序。

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

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

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

票数 15
EN

Stack Overflow用户

发布于 2019-07-06 08:44:56

它代表"End Branch 64 bit“--或者更准确地说,以64位终止间接分支。

下面是操作:

代码语言:javascript
复制
IF EndbranchEnabled(CPL) & EFER.LMA = 1 & CS.L = 1
  IF CPL = 3
  THEN
    IA32_U_CET.TRACKER = IDLE
    IA32_U_CET.SUPPRESS = 0
  ELSE
    IA32_S_CET.TRACKER = IDLE
    IA32_S_CET.SUPPRESS = 0
  FI
FI;

另外,该指令被认为是NOP

CET特性用于确保您的间接分支实际上到达了有效位置。这就提供了额外的安全性。以下是英特尔关于它的一段话:

ENDBRANCH (详见第73节)是一条新指令,用于标记程序中间接调用和跳转的有效跳转目标地址。此指令操作码被选择为旧机器上的NOP,以便使用ENDBRANCH新指令编译的程序继续在旧机器上运行,而无需执行CET。在支持CET的处理器上,ENDBRANCH仍然是NOP,主要由处理器流水线用作标记指令,以检测控制流违规。CPU实现了一个状态机,用于跟踪间接jmp和call指令。当看到其中一条指令时,状态机将从IDLE状态转移到WAIT_FOR_ENDBRANCH状态。在WAIT_FOR_ENDBRANCH状态下,程序流中的下一条指令必须是ENDBRANCH.如果看不到ENDBRANCH,处理器将导致控制保护异常(#CP),否则状态机将返回IDLE状态。

票数 58
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56905811

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档