操作系统:32位,保护模式,非影子堆栈(Shadow-Stack)
填一下之前挖的坑
以下个人理解并不保证完全正确,请使用intel白皮书进行对照阅读
如有错误,还请指正
RET
机器指令:C3
近返回,一般函数调用的返回,call
对应 ret
,也是唯一的用途
-
RET
的本质是:从栈顶弹出 EIP (pop EIP),EIP是返回地注意:pop EIP没有这条指令,只是方便理解
如果是 RET n
这样的,那么之后还会 ESP + n (后面这种形式就不写了)
RETF (return far)
机器指令:CB
远返回,call far
对应的 retf
,当然分为两种情况
- 相同权限返回:从栈顶弹出 EIP >> CS (先 >> 后)
- 不同权限返回:从栈顶弹出 EIP >> CS >> ESP >> SS
权限是否相同指的是:当前段的特权级别和将要返回的段的特权权限是否相同(CPL和DPL是否相同)
tip:不同权限之间的跳转都是要进行权限检查和各种保护检查
IRET (interrupt return)
机器指令:CF66
中断返回,int n
对应 iret
;任务切换(nested task swith)的 call far
也用 iret
返回
- 这里会用到一个NT位 (在EFLAGS寄存器中),这个表示是否是嵌套的任务切换 (是否是call命令的任务切换)。这将会影响到返回的方式。
- NT = 0,从栈顶弹出 EIP >> CS >> EFLAGS >> ESP >> SS (类似于RETF)
- NT = 1,任务切换返回,使用到TSS表。详情请查看任务段调用及返回
IRETD
机器指令:CF
中断返回,同iret
- 32位下,IRETD和IRET至少执行结果是一样的,但是硬编码却略有不同
- 本来是专门为32位定制的,但是编译器却允许IRET有32位和16位两种返回方式。
(32位下,IRET 等价于 IRETD,且 IRET 比 IRETD 更常用)
书中原文:
IRET and IRETD are mnemonics for the same opcode. The IRETD mnemonic (interrupt return double) is intendedfor use when returning from an interrupt when using the 32-bit operand size; however, most assemblers use theIRET mnemonic interchangeably for both operand sizes.
参考书籍
参考 : (可以参考书中的代码)
英特尔2卷 Vol. 2A 3-525 //IRET IRETD
英特尔2卷 Vol. 2B 4-563 //RET RETF
这里只是简单描述一些比较重要的内容,更多详情请参看上面的书页