2013-04-10 65 views
0

我试图挂钩一个Linux程序的功能。 基本上搜索使用mprotect取消保护功能,然后将jmp放入原来的函数地址中,重新指向我的函数钩子。内存复制功能

但是我想复制原始函数,以便在不需要修改函数时可以调用它。 我有一种勾这样

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

所以我的问题是...我怎么能知道一个函数的大小,以字节为单位,这样我就可以memcpy的()是动态分配的缓冲区执行它?我想过也许嵌入一个小长度的反汇编器并解析操作码,直到找到RETN optocode,但我不确定它是否可以在绝对所有情况下工作(例如,如果多个RETN驻留在同一个函数中: [)

,因为我想这样做,是因为同样的功能可以被其他图书馆迷上另一个原因..

+0

可能是重复的http://stackoverflow.com/questions/4546071/copy-a-function-in-memory-and-execute-it – jbr 2013-04-10 18:52:34

回答

3

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

但是,我不明白你为什么需要这个。我能想到的一个更简单的方法是即时修补该功能,将其前几条指令替换为钩子函数JMPCALL,同时保存这些被覆盖的指令以便稍后打补丁。喜欢的东西:

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(); 
} 
+1

,或者,更容易 - 覆盖PLT条目当然如果符号没有隐藏。 – 2013-04-10 19:06:26

+0

@VladLazarenko对,特别是考虑到这将与动态库一起使用的事实。 – 2013-04-10 19:07:47

+0

感谢您的信息。 的确我可以将信息保存在一个数组中并重新打补丁。尽管如此,我主要是为了学习的目的,并认为我可以去做父亲。 你能否提供更多有关ELF分析的信息?看起来很有趣。我如何检查ELF中的函数长度? 通过排序.symtab中的syms偏移量和下一个或...的func偏移量?请原谅我的无知。 你能提供一些基本的示例代码吗?谢谢,100万次。 – Yannick 2013-04-11 09:39:09