【问题标题】:redirecting a c function at runtime and calling the original function在运行时重定向 c 函数并调用原始函数
【发布时间】:2013-02-25 23:14:34
【问题描述】:

我的程序通过将 jmp 指令写入函数的前几个字节(仅 i386)将一个函数重定向到另一个函数。它按预期工作,但这意味着我不能再调用原始函数,因为它总是会跳转到新函数。

我能想到两种可能的解决方法:

  1. 新建函数,覆盖目标函数的jmp指令并调用。之后该函数写回 jmp 指令。 但我不确定如何传递参数,因为它们可以有任意数量。我想知道目标函数是否可以在其他地方跳转并跳过写回 jmp 指令(比如 throw catch?)。

  2. 创建一个新函数来执行我用 jmp 指令覆盖的代码。但我不能确定覆盖的数据是完整的指令。我必须知道要复制多少字节才能获得完整的说明。

所以,最后,我的问题:

  1. 还有其他我没想到的方法吗?

  2. 如何找到指令的大小?我已经查看了 binutils 并找到了 this 但我不知道如何解释它。

这是一个示例:

mov, 2, 0xa0, None, 1, Cpu64, D|W|CheckRegSize|No_sSuf|No_ldSuf, { Disp64|Unspecified|Byte|Word|Dword|Qword, Acc|Byte|Word|Dword|Qword }

第 2 列显示操作数 (2),最后一列包含有关操作数的信息,以逗号分隔

我还发现这个问题几乎相同,但我不能确定这 7 个字节是否包含完整的指令。 Writing a Trampoline Function

感谢任何帮助!谢谢。

【问题讨论】:

  • 您是否正在尝试做一些用函数指针无法做到的更简单(和更便携)的事情?
  • 我无法控制调用该函数的代码,所以,没有。我不能用函数指针来做。
  • 也许您应该针对您的问题提供更多信息,以便我们了解您选择此解决方案的原因。然后我们可以帮助您或提出更好的建议。
  • 我使用 hotpatch (github.com/vikasnkumar/hotpatch) 在正在运行的进程中加载​​共享库,现在我想将程序使用的函数重定向到共享库中的函数。

标签: c linux function redirect assembly


【解决方案1】:

Sebastian,您可以使用 hotpatch 中的 exe_load_symbols() 函数来获取符号列表及其在现有 exe 中的位置,然后查看是否可以在内存中覆盖它。我还没有尝试过。您也可以使用 LD_PRELOAD 环境变量来代替热补丁。

--维卡斯

【讨论】:

    【解决方案2】:

    这样的事情怎么样:

    假设这是原始函数:

    Instruction1
    Instruction2
    Instruction3
    ...
    RET
    

    将其转换为:

    JMP new_stuff
    old:
    Instruction2
    Instruction3
    ...
    RET
    ...
    new_stuff:
    CMP call_my_function,0
    JNZ my_function
    Instruction1
    JMP old
    my_function:
    ...
    

    当然,您必须考虑原始指令的大小(例如,您可以通过使用 objdump 反汇编来发现),以便第一个 JMP 完美匹配(使用 NOP 填充s 如果JMP 比原始指令短)。

    【讨论】:

    • 感谢您的帮助。获得原始指令的大小似乎非常困难。我不能使用 objdump,因为我必须知道函数的名称或二进制文件中的地址。进程中的地址和二进制文件中的地址可能不同。编辑:我尝试使用 libopcodes,但失败得很惨。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-02
    • 1970-01-01
    • 2012-05-12
    • 2018-01-21
    • 2020-12-15
    • 1970-01-01
    • 2016-10-11
    相关资源
    最近更新 更多