retn 4
是个函数返回指令。
以前一直纠结这个retn的寄存器操作顺序,手头正好在调试,详细跟了一下,豁然开朗,特分享。
先假设个环境:
retn 4未执行时,ESP=0013feb8;EIP=5d1d8b97;而[0013feb8]=7c974a19
执行retn 4之后:
首先
EIP=[0013feb8]
:即此时cpu先指挥EIP获取到栈中0013feb8起4个字节的值7c974a19,作为retn跳转的目标,然后cpu跳过去等着执行7c974a19地址下的命令。
此时,EIP=7c974a19
然后
因为retn 4里面有个4,此时cpu才让ESP栈+4+4,使得ESP=0013fec0。
为啥出现两个+4?另一个+4的原因在于:如果命令是retn,而不是retn 4,那ESP将当前值(0013feb8)给了EIP之后,自动会来一个+4,即ESP会为0013febc。
总结下来:
retn操作:先eip=esp,然后esp=esp+4
retn N操作:先eip=esp,然后esp=esp+4+N