x86中BND RET的含义是什么?

17

我在分析一个CRT库的代码(特别是SEH prolog)时,突然遇到这个奇怪的指令bnd ret。有人能解释一下在c3(ret操作码)之前的f2前缀是什么意思吗?


1
@fuz 嗯,原帖的作者显然同意你的观点,这就是社区投票关闭的来源。 - Ross Ridge
7
我认为这个答案被关闭得太快了。bndrep 不同。在启用MPX的代码中,bnd 用于确保分支(和返回)被检查。如果不支持MPX,则它是一个无操作,因此在库函数中始终添加它可以避免必须发送两个库版本(带有和不带有MPX)。 - Igor Skochinsky
@IgorSkochinsky 感谢您为此提供了帮助! - NTAuthority
这是一个好问题,应该开放让人回答。目前还没有适当的答案。 - HJLebbink
1
我也在一个 __chkstk 实现中看到了一个 bnd jae(操作码为 f2 73)。 - Jonathan
显示剩余3条评论
1个回答

20

BND 前缀是 Intel MPX (Memory Protection Extensions) 的一部分,表示返回目标(或者通用的控制流指令)应该与 BND0BND3 寄存器中指定的边界进行比较,否则将生成异常,表明可能存在堆栈溢出、编程错误或恶意代码攻击等问题。

在不支持 Intel MPX 或者禁用 MPX 的处理器上,BND 前缀会作为一个无操作指令,因此不需要编译两个版本的代码(一个带有前缀,一个没有)。

请注意,BND 前缀的编码与 REPNE 前缀的编码相同(都是 F2h),因此旧的反汇编工具可能会显示该指令序列为 REPNE RET(或者 REPNE JMPREPNE CALL 等)。这种用法与 REP RET 惯用语 无关,其中前缀被假定为无操作行为,纯粹用于解决旧 CPU 的性能问题。


1
@Sep:在编写指令助记符时使用全大写是一种有效的代码格式替代方案。这也是英特尔在自己的手册中所采用的方式。我认为这个答案没有歧义;似乎没有其他可以改进的地方,因此这次编辑并不是很有用。(另外,如果我要对助记符或寄存器名称使用代码格式,我倾向于使用小写字母,如 bndrep ret)。全大写对阅读流程的干扰最小,而小写字母 bnd 会有些干扰,但不像 BND 那么明显。如果我*想让读者在浏览时注意到一个助记符,我会使用 ret - Peter Cordes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接