在某个时候,英特尔将开始交付支持CET( C ontrol-flow E nforcement T 技术”的CPU),这将增加两个指令ENDBR64
和ENDBR32
。
这两个将被编码为
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
答案 0 :(得分:4)
旧版GDB将F3 0F 1E FA ENDBR64
解码为repz nop edx
。
在Core 2(Merom)上以64位模式单步执行不会导致体系结构状态发生任何变化,也不会产生任何错误/异常。 (在旧版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,例如原始的Pentium可能会出错。就像0f 1f
长时间的NOP。
顺便说一句,您尝试对其进行解码没有任何意义。 0f
是2字节操作码的“转义”字节,因此1e push ds
与其解码方式无关。这就是1e
自身解码的方式,而没有0f
转义字节。 (在64位模式下无效)。
答案 1 :(得分:1)
最近我自己遇到了ENDBR32
指令的问题。 VirtualBox版本6.0.14_Ubuntu r132055
错误地将ENDBR32
解码为非法操作码和STI
的序列。由于需要禁用中断,因此会产生各种错误。我想到的唯一解决方案是在启用-fcf-protection=branch
和-mmanual-endbr
选项的情况下调用GCC。