【问题标题】:How to hook C++ functions with asm如何用 asm 挂钩 C++ 函数
【发布时间】:2011-11-05 14:36:24
【问题描述】:

我想挂钩一个 C++ 函数。但是我不想使用ms detours的蹦床机制,而不是我想完全修补它。我可以获得函数所在的 DLL 的句柄,并且我有正确的偏移量(imageBase stuff ...)。那么怎么钩呢?而且我不知道参数的数据类型(var_4 和 arg_0),还是不需要它们?一般来说,我想用我自己的函数替换以下函数(我的函数几乎相同,只改变了一行):

sub_39001A40    proc near

    var_4       = dword ptr -4
    arg_0       = dword ptr  4
        push    ecx
        cmp dword_392ADAB4, 0
        jnz short loc_39001A4F
        call    loc_39024840

loc_39001A4F:
        push    esi
        mov esi, [esp+8+arg_0]
        lea eax, [esp+8+var_4]
        push    eax
        push    esi
        call    dword_392ADA98
        mov ecx, [esp+10h+var_4]
        add esp, 8
        add dword_392ADA80, ecx
        adc dword_392ADA84, 0
        add dword_392ADA90, esi
        pop esi
        adc dword_392ADA94, 0
        add dword_392ADA7C, 1
        pop ecx
        retn
sub_39001A40    endp

很糟糕,我只能挂钩函数,这些函数的名字我知道用 ms detours。我不能用弯路钩住这些 asm 函数,因为我需要传递参数的数据类型来创建函数结构!

编辑::::

“弯路到底有什么问题?”

我写道:“我不想使用 ms detours 的蹦床机制,而不是我想完全修补它。”和“这很糟糕,我只能用 ms detours 挂钩我知道的函数。我不能用 detours 挂钩那些 asm 函数,因为我需要传递参数的数据类型来创建函数结构!”而且我没有 C++ 文件的源代码。我只有十六进制转储。

“Trampoline 是一个实际的技术术语 :) 我只是想知道为什么 @lua 不能使用它。”

我写:再读一遍我的句子,如果你仍然不明白为什么,我的英语很糟糕。

“只覆盖命名函数应该可以工作,当然您可能需要重新实现整个 DLL(取决于它是否对您有任何进一步的用途)。鉴于您对汇编程序的掌握,您可能会使用十六进制编辑器来编辑(副本)您正在寻求颠覆的原始 DLL。”

我想挂钩函数,因为我不想编辑文件。我无法覆盖我的函数,因为我不知道参数的数据类型和函数的名称。

@asveikau:感谢你的真正帮助,但我不想使用蹦床机制,我想覆盖函数。

【问题讨论】:

  • 走弯路到底有什么问题?
  • @bdonlan,我显然低估了这里的 lua。我认为蹦床被用作对 ms 机制膨胀的贬义词。看来detours其实是一个我一无所知的知名程序。
  • Trampoline 是一个实际的技术术语 :) 我只是想知道为什么 @lua 不能使用它。
  • @lua: 你到底想在函数中改变什么(注意不同的流水线编译成不同长度的指令,所以取决于你想要改变什么可能真的很容易或真的很难)?
  • 这里的问题是一个不错的例子,我猜stackoverflow.com/q/29093398/1067003

标签: c++ assembly hook reverse-engineering


【解决方案1】:

一个很好的技巧是将前几条指令替换为:

push dword xxxx ; where xxx = new code location
ret

这有点像混淆的jmp。我这样写是因为它的汇编版本很容易在运行时用指针替换 push 操作数。它组装成:

68 XX XX XX XX c3

其中“XX XX XX XX”是您的小端地址。

然后您可以创建一个“调用旧版本的函数”代码位置,其中前几条指令是您用上面的序列替换的指令,然后跳转到原始代码中的下一条有效指令。

【讨论】:

  • 困难的部分,当然,是正确地重新定位原始指令,当函数可能跳回到它自己的开始时,等等......
  • 另请注意,这与 detours 使用的方法基本相同。
  • @bdonlan - 是的,这很可能是 detours 所做的,是的,如果指令的前 6 个字节再次被引用,无论是通过跳转还是通过其他方式,它确实有限制。如果我不得不猜测的话,我会说后者在 C 代码中并不常见,因为大多数函数都会以设置帧指针等无聊的东西开始。 YMMV。
【解决方案2】:

只覆盖命名函数应该可以工作,当然您可能需要重新实现整个 DLL(取决于它是否对您有任何进一步的用途)。鉴于您对汇编程序的掌握,您可能会使用十六进制编辑器来编辑(副本)您正在寻求颠覆的原始 DLL。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 2014-10-22
    • 2022-01-23
    相关资源
    最近更新 更多