我想在程序集中获取函数的返回地址,然后将该返回地址值与另一个值进行比较,而不会破坏堆栈或更改堆栈中的任何内容,
如何在装配中完成?
我正在使用x86
答案 0 :(得分:7)
如果使用stdcall约定返回地址存储在寄存器ebp +4的内容中,则通常在x86上。所以cmp ebp, whatever;
应该做的工作。 Actualy它不依赖于调用约定,而是因为它取决于你的编译器是否将push ebp作为函数的第一条指令,它通常会这样做。通常这个函数看起来像:
push ebp
mov ebp,esp
sub esp,size_of_local_variables
...
somehting something something
...
mov esp, ebp
pop ebp
ret
答案 1 :(得分:1)
您可以创建包装函数。
int the_real_function ( unsigned int a, unsigned int b )
{
//stuff
return(something);
}
创建几行汇编程序:
function_name:
save registers if needed
grab the return address here
if passed on stack copy parameters
call the_real_function
if return is stack based place it where needed
restore registers if needed
return
显然不是真正的asm代码。您希望检查的函数将重命名,然后asm将具有函数的名称,编译和链接以及对函数的所有调用都将通过包装器。要编写上述内容,您必须知道该目标,编译器,编译器选项等的调用约定。
答案 2 :(得分:1)
一般情况下,您需要手动或使用您的某些代码反汇编相关函数并分析反汇编(再次手动或使用代码中的某种启发式算法)来查看堆栈指针的行为和任何相关的寄存器(例如ebp)或该函数中的变量,直到启动需要返回地址的代码为止。
如果您手动完成所有操作,很容易找到返回地址位置并对其进行硬编码,但是生成的代码将非常脆弱,因为任何代码都会更改,编译方式的更改可能会破坏它。
OTOH,尽管代码更改和编译更改将在整个(或几乎总是)工作的代码中实现一个解决方案将变得非常乏味和困难。
您能否告诉我们您需要返回地址的原因?你试图解决的问题是什么?