有哪些替代x86 call指令的方法?也许可以像将返回地址压入栈中然后跳转这样的方式?
另外,是否有命令可以获取内存中的当前位置?
call
指令实际上为您执行此操作。例如,call my_func
将执行类似以下的操作:
push ret_address
jmp my_func
接下来的ret
调用只是在某种意义上使用了你刚刚推送到jmp
中的地址进行返回。你不想使用call
是否有特定原因,或者它对你不可用?要获取当前内存位置,可以尝试读取eip
寄存器(无法写入)。
push return_address (push eax if address in eax)
jmp call_address
请记得如果该特定调用存在参数,也要将参数推送。
什么是内存中的当前位置?我想你是指当前指令指针。你不能直接获取它,但可以使用异常处理程序(SEH handler)在引起已处理异常时获取该值。
E8 <offset> # relative
FF <address> # absolute
其中FF
表示绝对“跳转”,而E8
确实是相对于当前的eip
。
因此,如果您有例如:
E8 32 45 ab 6f
call 0x3245ab6f
push %eip
add $0x3245ab6f, %eip
而不是
push %eip
jmp $0x3245ab6f
call
指令会将自身的下一条指令地址(即超过自身长度的地址)压入栈中。由于 x86 架构中没有可见的 %eip
寄存器,因此您应该在伪代码中注释说明您的 %eip
是已经增加了 call
指令长度后的 EIP 寄存器。 (但是,是的,相对位移是相对于指令结尾即返回地址的,就像 64 位 RIP 相对寻址一样。) - Peter Cordes