在运行时重定向 c 函数并调用原始函数
Posted
技术标签:
【中文标题】在运行时重定向 c 函数并调用原始函数【英文标题】:redirecting a c function at runtime and calling the original function 【发布时间】:2013-02-25 23:14:34 【问题描述】:我的程序通过将 jmp 指令写入函数的前几个字节(仅 i386)将一个函数重定向到另一个函数。它按预期工作,但这意味着我不能再调用原始函数,因为它总是会跳转到新函数。
我能想到两种可能的解决方法:
新建函数,覆盖目标函数的jmp指令并调用。之后该函数写回 jmp 指令。 但我不确定如何传递参数,因为它们可以有任意数量。我想知道目标函数是否可以在其他地方跳转并跳过写回 jmp 指令(比如 throw catch?)。
创建一个新函数来执行我用 jmp 指令覆盖的代码。但我不能确定覆盖的数据是完整的指令。我必须知道要复制多少字节才能获得完整的说明。
所以,最后,我的问题:
还有其他我没想到的方法吗?
如何找到指令的大小?我已经查看了 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) 在正在运行的进程中加载共享库,现在我想将程序使用的函数重定向到共享库中的函数。 【参考方案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,但失败得很惨。以上是关于在运行时重定向 c 函数并调用原始函数的主要内容,如果未能解决你的问题,请参考以下文章