如何使用 DetourAttachEx 创建蹦床功能? (与 MS 绕道而行)

Posted

技术标签:

【中文标题】如何使用 DetourAttachEx 创建蹦床功能? (与 MS 绕道而行)【英文标题】:how to create a trampoline function using DetourAttachEx? (with MS detours) 【发布时间】:2010-12-02 09:37:30 【问题描述】:

我有一个 dll,我希望绕过它的导出函数之一,

该 dll 不是 windows 的一部分。 我需要能够在我绕道之后调用真实函数(从绕道的函数中调用真实函数) 我知道函数的确切签名。 我已经可以绕行该函数了,但是现在我不能调用真正的函数。

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

欢迎任何帮助

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

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

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

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

作品, 还是谢谢

【问题讨论】:

你能解释一下你所说的绕道是什么意思吗?另外,我必须承认,作为一名专业软件工程师,我在十多年来从未听说过“蹦床功能”这个词。如果您只是试图从您的代码中调用第三方 DLL 中的函数,那么您需要说明的第一件事是您是否有头文件、LIB 文件,以及它是 OLE/COM/CLR DLL 还是不是。 好吧,我在 Google 上阅读了有关 Detours 和 OMG 的信息,这真是太可怕了。我不敢相信有人(微软?)实际上为此写了一个库?除了 A) 将病毒附加到程序和 B) 入侵 Windows 以尝试覆盖其正常行为之外,它还有什么用处,因为 Microsoft 不给您任何以任何正常方式执行此操作的机会?你到底想达到什么目的?从我读到的内容来看,函数的来源应该没有区别。你到底出了什么问题? 大多数人只是将它用于调试和日志记录。我正在尝试过滤该 dll 的功能之一。 @AlistairG:它们有很多用途,其中许多是恶意的或具有不正当意图的,而 64 位绕道库成本 $$$ 的事实表明了这一点。哎呀,MS自己以一种称为热补丁的方式使用它(通用函数挂钩,而不是Detours库)。 这和函数插入一样吗? 【参考方案1】:

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

第 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)) 来做到这一点。在使用VirtualProtectEx 设置读/写/执行权限后,应使用WriteProcessMemory 完成写入

第 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
    


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


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

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

需要注意的重要一点:如果您挂钩多线程应用程序,您的补丁需要在应用程序暂停的情况下完成,或者使用InterlockedExchangeInterlockExchange64InterlockedExchangePointer(我使用后者) IAT/EAT 挂钩,尤其是从“第三方进程”挂钩时)


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

【讨论】:

通过DetourAttach的第一个参数GetProcAddress获取。我将旧指针保存在全局函数指针中 @user527744: 听起来你创建了一个无限循环,因为DetourAttach 返回的指针指向绕道开始的地址,参见我上面的示例,应该很清楚这是如何发生的:) 当我第一次开始我的项目时,我想实现类似于你建议的东西,但是我决定不使用这种方法,因为:a。直接写入汇编是危险的 b.多线程进程很难做到 c.我害怕 x64 以及它如何影响汇编命令的大小。感谢您的回答,但我正在寻找的答案是使用 detours api(或类似的东西)的答案 @user527744:我的回答的第二部分可以使用,Detours 应该有 EAT/IAT 挂钩,如果没有你仍然可以使用它的补丁,你只需要自己扫描 thunk

以上是关于如何使用 DetourAttachEx 创建蹦床功能? (与 MS 绕道而行)的主要内容,如果未能解决你的问题,请参考以下文章

编写蹦床函数

什么是蹦床功能?

MonoTouch 6.0.8 发行说明中的​​“运行时蹦床”是啥意思?

cf1491C. Pekora and Trampoline

蓝桥杯集训100题scratch汉娜蹦床 蓝桥杯scratch比赛专项预测编程题 模拟练习题第08题

蓝桥杯集训100题scratch汉娜蹦床 蓝桥杯scratch比赛专项预测编程题 模拟练习题第08题