如何使用DetourAttachEx创建一个trampoline函数? (与MS绕道而行)

时间:2010-12-02 09:37:31

标签: c++ c hook detours

我有一个dll,我希望绕道其导出的一个函数,

  • dll不是Windows的一部分。
  • 我需要能够在绕道后调用真正的函数(从一个绕道而来的函数中调用真正的函数)
  • 我知道该功能的确切签名。
  • 我已经能够绕过这个功能,但是现在我不能称之为真正的功能。

我意识到我需要使用蹦床功能,我在网上看过例子。 问题是:所有这些例子都显示了如何绕道一个Windows API函数,我需要为一个函数做同样的事情我得到彻底的dll导入。

欢迎任何帮助

- 编辑 为了澄清,我试图用它的指针调用原始函数,但这不起作用。 还尝试使用此堆栈溢出article

中的方法

它甚至没有崩溃,但看起来它会进入一个无限循环(我假设因为在原始函数中有一个跳转到绕道的那个)

编辑 - 解决了! 不知道是什么解决了它, 使用this作为参考。

  • 停止使用getProcadder,而是开始使用DetourFindFunction
  • 清理了代码(非常确定我清除了导致问题的原因)

作品, 无论如何,谢谢

1 个答案:

答案 0 :(得分:4)

我不使用弯路(我实际上讨厌它!),但是绕过任何非热修补功能都可以通用的方式完成,如下所示:

第1步: 在函数的开头插入一个JMP <your code>,需要5个字节,可能多一点,以便与最近的指令对齐。作为一个例子

要挂钩的函数的开始:

SUB ESP,3C
PUSH EDI
PUSH ESI
//more code

会变成:

JMP MyFunction
//more code

可以通过在第一个字节写入0xE9然后在以下DWORD中写入值(function_addr - patch_addr + sizeof(INT_PTR))来执行此操作。在使用WriteProcessMemory

设置读/写/执行权限后,应使用VirtualProtectEx完成写入

第2步: 接下来,我们创建一个汇编界面:

void __declspec(naked) MyFunc()
{

    __asm
    {
        call Check             ;call out filter func
        test eax,eax           ; test if we let the call through
        je _EXIT
        sub esp,3c             ; its gone through, so we replicate what we overwrote
        push edi
        push esi
        jmp NextExecutionAddress ; now we jump back to the location just after our jump
    _EXIT:
        retn                   ; note, this must have the correct stack cleanup
    }

}

需要使用ModuleBase + RVA在运行时填充NextExecutionAddress。


老实说,它的方式更简单,更好(!)只是EAT(导出地址表)挂钩dll的导出表,或IAT(导入地址表)挂钩导入表什么是调用你想要的函数过滤。 Detours应该有这些类型的钩子的功能,如果没有,还有其他免费提供的库。

另一种方法是使用绕道来挂钩应用程序中的每个调用,使用dll将它们重新路由到您自己代码中的代理函数,这样做的好处是可以只过滤某些调用,而不是过滤所有调用一个二进制文件(可以使用_ReturnAddress执行相同操作,但这样做更多),但缺点是捕获要修补的位置(我使用ollydbg +一个自定义修补引擎),它不适用于非 - 常规调用约定函数(如Watcom中使用#pragma aux生成的函数或VC7 +生成的优化调用)。

需要注意的一件重要事情是:如果您需要挂钩多线程应用,则需要暂停应用,或者使用InterlockedExchangeInterlockExchange64InterlockedExchangePointer完成补丁:我将后者用于所有IAT / EAT钩子,特别是在从“第三方过程”中挂钩时)


看看你链接到的帖子,我觉得这个方法很糟糕,主要是因为可以说:P但是,你是如何调用你获得的这个指针,以及它是如何获得的?