在函数地址上使用JMP有什么影响?

时间:2012-11-24 22:27:57

标签: function assembly ida

当我遇到这样的事情时,我正在寻找IDA中的一个程序,因为我试图弄清楚某个功能是如何工作的:

; C_TestClass::Foo(void)
__text:00000000 __ZN14C_TestClass7FooEv proc near
__text:00000000                 jmp     __ZN14C_TestClass20Barr ; C_TestClass::Barr(void)
__text:00000000 __ZN14C_TestClass7FooEv endp
__text:00000000

任何人都可以向我解释在这样的情况下,跳到某个函数究竟会是什么? 我猜它是另一个函数的包装器吗?

2 个答案:

答案 0 :(得分:5)

跳跃通常是一种有效处理未内联的包装函数的方法。

通常情况下,您必须先读取所有函数参数并将其推回到堆栈中,然后再调用子函数。

但是当包装函数具有完全相同的原型时:

  1. 相同的通话约定
  2. 相同的参数(并以相同的顺序)
  3. 相同的返回类型
  4. 不需要所有通常的函数调用开销。你可以直接跳到目标。 (这些类别可能不是完全必要的,因为在某些其他情况下它仍然可能。)

    调用包装函数时设置的所有参数(在堆栈或寄存器中)都已经存在(并且兼容)子函数。

答案 1 :(得分:3)

这就是所谓的尾调用。编译器能够直接调用该函数并让 it 返回原始调用者而不会导致任何问题。例如:

int f(int x)
{
    ...
    return g(y);
}

编译器最后可以简单地jmp g,因为参数在f的参数所在的位置有空间,并且在返回f之前不会修改返回值打电话。