0

我正在尝试挂钩一个 linux 程序的功能。基本上使用 mprotect 搜索解除对函数的保护,然后将 jmp 放入原始函数地址中,重定向到我的函数挂钩。

但是我想复制原始函数,以便在不需要修改的函数时调用它。我会有这样的钩子

int CallHookedFunctionFoobar(int param1, int param2)
{
      if (g_somevariable)
           Foobar_original(param1, param2);
      else
           Foobar_modified(param1, param2);
}

所以我的问题是......我怎么知道函数的大小(以字节为单位),所以我可以将它 memcpy() 放到动态分配的缓冲区中执行它?

我考虑过可能嵌入一个小长度的反汇编程序并解析操作码,直到找到 RETN 光码,但我不确定它绝对适用于所有情况(例如,如果多个 RETN 驻留在同一个函数中:[)

因为我想这样做的另一个原因是因为同一个函数可能已被另一个库挂钩..

4

1 回答 1

3

首先,如果这是特定于 Linux 的,那么您的可执行文件很可能是ELF二进制文件。因此,您可以只解析 ELF 标头(libelf例如使用 )来查找/计算函数的长度。

但是,我不明白你为什么需要这个。我能想到的一种更简单的方法是即时修补函数,将其前几条指令替换为 a JMPorCALL到钩子函数,同时保存那些被覆盖的指令以供以后修补。就像是:

void call_hooked(void (*fn)(), unsigned char *ctx, size_t *n)
{
    unsigned char hook_patch[] = { 0x15, 0x20, 0x7f, 0x48 }; // I bluffed
    *n = sizeof(hook_patch);
    memcpy(ctx, fn, sizeof(hook_patch));
    memcpy(fn, hook_patch, sizeof(hook_patch));
    fn();
}

void call_orig(void (*fn)(), unsigned char *ctx, size_t n)
{
    memcpy(fn, ctx, n);
    fn();
}
于 2013-04-10T18:57:58.733 回答