调用/ return / jmp等后执行x86代码?

时间:2016-08-10 19:55:37

标签: assembly x86

我希望这个问题不是愚蠢的,因为它看似显而易见。 在我对缓冲区溢出进行一些研究时,我偶然发现了一个简单的问题:

在呼叫/返回/跳转后转到新的指令地址: CPU是否会在该地址执行OP代码,然后将一个字节移动到下一个地址并执行下一个OP代码,依此类推,直到达到下一个调用/返回/跳转?或者是否涉及更棘手的事情?

3 个答案:

答案 0 :(得分:1)

call指令将指令的地址保存(堆栈)到堆栈后。在那之后,它只是跳跃。它没有明确地告诉cpu寻找return指令,因为这将通过弹出(从堆栈)call首先保存的返回地址来处理。这允许多次调用和返回,或简单地说,嵌套调用

答案 1 :(得分:1)

有点夸张的解释(与那些评论相同):

CPU具有专用寄存器指令指针 eip,它指向下一条要执行的指令。

jmpcallret等在内部结束,类似于:
mov eip,<next_instruction_address>

当CPU正在处理指令时,它会将eip增加适当大小的上一次执行指令自动(除非被其中一个jmp / {{1}覆盖} / j[condition] / call / ret / ...说明)。

无论你指向int(通过何种方式),CPU都会尝试将该内存的内容作为下一个指令操作码执行,而不知道任何上下文(where / why)它来自这个新的eip)。实际上这种健忘症发生在执行的每条指令之前(我默默地忽略了现代内部x86架构,其中包含各种预执行队列和分支预测,转换为微指令等等......)...这是实施细节,对程序员来说非常隐蔽,通常只有通过糟糕的性能才能看到,如果你通过无意识地跳转来扰乱这种架构。所以它的CPU,eip这里&amp; now ,其他并不多。

注意:x86上的某些上下文可以通过监督代码(如OS)定义内存布局来提供,即。将某些内存区域标记为不可执行。 CPU检测到它eip指向这样的区域将发出故障信号,并进入陷阱&#34;处理程序(通常由OS管理,杀死干扰过程)。

答案 2 :(得分:0)

  

当CPU处理指令时,它会增加eip by   最后执行的指令的适当大小(除非   被其中一个jmp / j [condition] / call / ret / int / ...指令覆盖。

这就是我想知道的。

我很清楚他们的东西更多(NX Bit,Pipelining ect)。

感谢大家的回复