为什么弹出寄存器会更改IP指针

时间:2018-04-08 21:41:12

标签: assembly x86 reverse-engineering

我正在玩一些汇编代码

func:
    pop ax
    ret
main:
    push 0x44
    call func

我注意到ip指针现在指向堆栈中最后一项的0x44 我这样做是为了理解ROP技术 我需要了解这种行为,因为当我这样做时

func:
    ret
main:
   call func

它按预期工作,EIP指针指向原始代码 那么pop改变代码流的区别是什么? 并且pop ax是否将堆栈的最后一个值分配给ax

2 个答案:

答案 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。