绕道未正确清理堆栈

逆向工程 函数挂钩 调用约定
2021-07-02 20:17:20

我第一次尝试使用 Detours 来挂钩一个函数。我是逆向软件和挂钩的新手,所以我可能在这里错过了一些重要的东西。

我正在尝试将此功能用作挂钩:

typedef  int (__thiscall* func_type)(LPVOID*, LPVOID*, DWORD, BOOL);
LPVOID hookaddr = 0;
 int __fastcall testhook(LPVOID* pThis, void* _EDX, LPVOID* object, DWORD hp, BOOL self)
{
    std::cout << "Hooked"  << std::endl;

    func_type originalFunc = (func_type)hookaddr;

    return originalFunc(pThis, object, hp, self);
}

问题在于 hooked 函数似乎遵循__thiscall约定,而 Detours 似乎不允许这样做?我尝试在我注入的 dll 中混合__thiscall__stdcall/__fastcall约定,但无法获得任何工作。我要么得到错误的ecx值,要么由于无效的esp.

知道我可以在这里尝试什么吗?

1个回答

我找到了这个问题的解决方案,这很简单。我对挂钩函数签名和__fastcall让非成员函数与__thiscall约定一起工作技巧感到困惑在我最初的帖子中,函数签名中的前两个参数是使用ecxand传递的edx,但我忘记了使用堆栈传递的指针之一。正确的函数定义如下:

 int __fastcall testhook(LPVOID* pThis, void* _EDX, LPVOID* object, LPVOID* object2, DWORD hp, BOOL self)
{
    std::cout << "Hooked"  << std::endl;

    func_type originalFunc = (func_type)hookaddr;

    return originalFunc(pThis, object, object2, hp, self);
}

由于被调用者负责清理堆栈,因此提供不正确数量的参数会导致堆栈损坏(在我的情况下,在我的函数返回后,其中一个参数仍在堆栈中)。