【问题标题】:How do old CPUs execute the new ENDBR64 and ENDBR32 instructions?旧 CPU 如何执行新的 ENDBR64 和 ENDBR32 指令?
【发布时间】:2019-05-13 21:40:46
【问题描述】:

在某个时候,英特尔将开始出货支持 CET(Control-flow Enforcement Technology)的 CPU,这增加了两个指令ENDBR64ENDBR32

这两个将被编码为

F3 0F 1E FA   for ENDBR64 and 
F3 0F 1E FB   for ENDBR32 respectively. 

这些将如何在较旧的 x86 CPU 上执行?
例如,Core i5 甚至是老式的 Pentium II?

更新:

F3 0F = prefix indicating newer instructions
1E = ENDBR
FA = ENDBR64

【问题讨论】:

  • 指令集参考将它们列为“保留 - NOP”。但是我不清楚 cpu 是否也知道获取最后一个字节。
  • @Jester 他们被记录为有一个 modr/m 字节,所以应该没问题。
  • 我不清楚是不是这样。 0F 1F 被列为 NOP /0 Ev,所以它确实有 modrm。但是0F 1E 只是NOP
  • 如果我有一个旧的 Pentium CPU,我会尝试这些,但我没有。这里有人碰巧有吗?
  • 您对问题的更新不是最佳的。英特尔手册第 3.1.1.2 节指出,字节序列 F3.0F 可以有多种含义。

标签: assembly x86 x86-64 control-flow


【解决方案1】:

较旧的 GDB 将 F3 0F 1E FA ENDBR64 解码为 repz nop edx

在 64 位模式下的 Core 2 (Merom) 上单步执行不会导致架构状态发生变化,也不会出现故障/异常。 (在旧 Ubuntu 15.10 安装上的 GDB 7.10 中测试)。


根据https://gist.github.com/Quasilyte/b60c94b9cb608d5b1a359d54f1be8aca
0f 1e /r是一个带ModRM的2字节操作码NOP r/m32, r32,与标准多字节0f 1f NOP that Intel documents相同。

它说它是用 Pentium Pro 添加的,所以任何 PII / PIII 或更高版本都可以。

https://github.com/NationalSecurityAgency/ghidra/issues/197#issuecomment-472906147 表示 AMD 记录了这些额外的 NOP 操作码;英特尔将它们列为“保留”。

rep 前缀对于它们不适用的操作码通常会被静默忽略。这使 Intel/AMD 可以灵活地使用 REP 作为未来指令的强制前缀的一部分来创建编码,不会在旧 CPU 上出现故障。


比 PPro 更早的 CPU,例如原始奔腾,可能会出错。就像0f 1f long NOP。


顺便说一句,您尝试对其进行解码是没有意义的。 0f 是 2 字节操作码的“转义”字节,因此 1e push ds 与解码方式无关。这就是1e 自己解码的方式,没有0f 转义字节。 (在 64 位模式下无效。)

【讨论】:

    【解决方案2】:

    我自己最近遇到了ENDBR32 指令的问题。 VirtualBox 版本6.0.14_Ubuntu r132055 错误地将ENDBR32 解码为非法操作码和STI 的序列。这会产生各种错误,因为我需要禁用中断。我想出的唯一解决方案是在启用-fcf-protection=branch-mmanual-endbr 选项的情况下调用GCC。

    VirtualBox debug console on the top, Objdump on the bottom

    【讨论】:

    • 解决了吗?哇。
    猜你喜欢
    • 2013-06-19
    • 2013-08-09
    • 2019-03-01
    • 2019-11-16
    • 2016-12-27
    • 2020-09-13
    • 2016-03-29
    • 2011-02-01
    • 2011-01-07
    相关资源
    最近更新 更多