2

我有一个 dll,我想绕道它的导出函数之一,

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

我意识到我需要使用蹦床功能,我看过网上的例子。问题是:所有这些示例都显示了如何绕过 Windows API 函数,我需要对我通过 dll 导入完成的函数执行相同的操作。

欢迎任何帮助

--edit 澄清一下,我试图通过指针调用原始函数,但这不起作用。还尝试使用此堆栈溢出文章中的方法

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

编辑——解决了!不知道是什么解决了它,以此作为参考。

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

有效,还是谢谢

4

1 回答 1

4

我不使用 detours(我实际上讨厌它!),但是可以以通用方式绕过任何非热补丁功能,如下所示:

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

要挂钩的函数的开始:

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

会成为:

JMP MyFunction
//more code

0xE9可以通过在第一个字节写入然后将值写入(function_addr - patch_addr + sizeof(INT_PTR))下一个 DWORD来做到这一点。写入应该WriteProcessMemory在设置读/写/执行权限之后使用VirtualProtectEx

第二步:接下来,我们创建一个汇编接口:

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
    }

}

NextExecutionAddress 需要在运行时使用ModuleBase + RVA.


老实说,仅 EAT(导出地址表)挂钩 dll 的导出表,或者 IAT(导入地址表)挂钩您要过滤的调用函数的导入表,其方式更简单、更好(!)。Detours 应该具有这些类型的钩子的功能,如果没有,还有其他免费可用的库可以做到这一点。

另一种方法是使用 detour 来挂钩应用程序中的每个调用,使用 dll 将它们重新路由到您自己代码中的代理函数,这具有允许仅过滤某些调用的优点,而不是二进制文件中的所有内容(可以使用 来做同样的事情_ReturnAddress,但工作量更大),缺点是捕获要修补的位置(我使用 ollydbg + 自定义修补引擎)并且它不适用于非常规调用约定函数(比如那些#pragma auxWatcom 或 VC7+ 生成的优化调用)。

需要注意的一件重要事情:如果您挂钩多线程应用程序,您的补丁需要在应用程序暂停的情况下完成,或者使用原子完成InterlockedExchangeInterlockExchange64并且InterlockedExchangePointer(我将后者用于所有 IAT/EAT 挂钩,尤其是从“第三个”挂钩时党的过程')


看看你链接到的帖子,我认为那里的方法很糟糕,主要是由于汇编 :P 但是,你是如何调用你获得的这个指针的,它是如何获得的?

于 2010-12-02T10:50:41.647 回答