问题描述
我希望这个问题不会太愚蠢,因为它看起来似乎很明显.当我对缓冲区溢出进行一些研究时,我偶然发现了一个简单的问题:
I hope this question isn't to stupid cause it may seem obvious.As I'm doing a little research on Buffer overflows I stumble over a simple question:
在调用/返回/跳转后转到新的指令地址后:CPU是否会在该地址执行OP代码,然后将一个字节移至下一个地址并执行下一个OP代码,依此类推,直到到达下一个调用/返回/跳转?还是有一些更棘手的事情?
After going to a new Instruction Address after a call/return/jump:Will the CPU execute the OP Code at that address and then move one byte to the next address and execute the next OP Code and so on until the next call/return/jump is reached? Or is there something more tricky involved?
推荐答案
一些无聊的扩展解释(与这些注释相同):
A bit boringly extended explanation (saying the same as those comments):
CPU具有专用寄存器指令指针 eip
,它指向要执行的下一条指令.
CPU has special purpose register instruction pointer eip
, which points to the next instruction to execute.
A jmp
,call
,ret
等在内部以类似于以下内容的结尾:mov eip,<next_instruction_address>
.
A jmp
, call
, ret
, etc. ends internally with something similar to:mov eip,<next_instruction_address>
.
CPU处理指令时,它会自动将eip
递增最后执行的指令的适当大小 (除非被那些jmp
/j[condition]
/call
/ret
/int
/...说明).
While the CPU is processing instructions, it does increment eip
by appropriate size of last executed instruction automatically (unless overridden by one of those jmp
/j[condition]
/call
/ret
/int
/... instructions).
无论您以何种方式指向eip
,CPU都将尝试最好将该内存的内容作为下一条指令操作码执行,而不知道任何上下文(它从何而来/为何如此)新的eip
).实际上,这种失忆是在每条指令执行之前发生的(我无声地忽略了现代的内部x86体系结构以及各种预执行队列和分支预测,转换为微指令等.实施细节对程序员来说是非常隐蔽的,通常只有在性能不佳的情况下才能看到,如果您不经意地四处跳动会严重干扰该体系结构).因此,是CPU,eip
和此处&现在,
Wherever you point the eip
(by whatever means), CPU will try it's best to execute content of that memory as next instruction opcode(s), not aware of any context (where/why did it come from to this new eip
). Actually this amnesia sort of happens ahead of each instruction executed (I'm silently ignoring the modern internal x86 architecture with various pre-execution queues and branch predictions, translation into micro instructions, etc... :) ... all of that are implementation details quite hidden from programmer, usually visible only trough poor performance, if you disturb that architecture much by jumping all around mindlessly). So it's CPU, eip
and here&now, not much else.
注意:通过监督代码(例如OS)来定义内存布局,可以在x86上提供一些上下文.将内存的某些区域标记为不可执行. CPU检测到eip
指向该区域将发出故障信号,并落入陷阱"处理程序(通常也由OS管理,从而消除了干扰过程).
note: some context on x86 can be provided by defining the memory layout by supervising code (like OS), ie. marking some areas of memory as non-executable. CPU detecting it's eip
pointing to such area will signal a failure, and fall into "trap" handler (usually managed by OS also, killing the interfering process).
这篇关于调用/返回/jmp等后执行x86代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!