我正在玩一些汇编代码
func:
pop ax
ret
main:
push 0x44
call func
我注意到ip指针现在指向堆栈中最后一项的0x44
我这样做是为了理解ROP
技术
我需要了解这种行为,因为当我这样做时
func:
ret
main:
call func
它按预期工作,EIP指针指向原始代码
那么pop
改变代码流的区别是什么?
并且pop ax
是否将堆栈的最后一个值分配给ax
?
答案 0 :(得分:1)
要理解这段代码,看一下真正的程序流程可能会有所帮助(反转代码的顺序并假设线性流程):
main: ; entry point IP = main
push 0x44 ; 0x44 on top of stack
call func ; PUSH 'next cur IP'(=func) on the stack
func:
pop ax ; POP 'next cur IP' from the stack(=this)
ret ; return to current stack value (=0x44 = IP) which is probably invalid
这与获取当前IP的以下技术非常相似:
由于没有指令来获取指令指针(IP)的当前值,因此以下代码是获取其值的便捷解决方法:
call next ; call next address
next:
pop ax ; POP the current value of the IP (AX=this address)
答案 1 :(得分:0)
EIP是一个注册。堆栈上的值不是EIP(尚未),如果您通过执行ret
将其弹出到EIP中,它是一个返回地址或可能成为EIP的值。
将ret
视为x86如何拼写pop eip
。
执行push 0x44
会使EIP寄存器增加2,即指令的长度。
如果您在0x44
指向它时执行ret
,则使用ESP
作为返回地址,那么EIP将变为0x44
。
请注意,IP是EIP的低16位。除非你真的是指低16位,否则写EIP而不是IP。