在运行时重定向c函数并调用原始函数

时间:2013-02-25 23:14:35

标签: c linux function redirect assembly

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

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

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

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

  3. 所以,最后,我的问题:

    1. 还有另一种我没想到的方式吗?

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

    3. 以下是一个示例:

      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),最后一列显示有关操作数的信息,用逗号分隔

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

      任何帮助表示赞赏!感谢。

2 个答案:

答案 0 :(得分:1)

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

- 维卡斯

答案 1 :(得分:0)

这样的事情怎么样:

让我们说这是原始功能:

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如果JMP比原始指令短,则为{{1}}。