2011-09-19 22 views
0

我使用LD_PRELOAD机制加载到二进制程序地址空间中的.so文件。强制使用libc函数在复制函数的情况下使用libc函数

binray程序(不是我的)有它自己的malloc函数的实现。

由于我的模块正在加载到该程序中,它使用程序的malloc而不是libc malloc,从而导致崩溃。

我自己编写了二进制程序(它是opensource),我看到将malloc函数更改为mymalloc函数可以修复问题。

由于在生产环境中,我不能更改二进制程序,我想找到其他解决方案。

在加载程序中存在相同函数的情况下,是否可以强制.so模块使用libc版本的malloc(或任何其他函数)?

任何帮助将不胜感激。

回答

0

您可以尝试使用ELF符号版本控制。看看你的libc malloc的定义:

$ objdump -T libc.so | grep malloc 
0006fef0 g DF .text 000001e7 GLIBC_2.0 malloc 

因此,如果您链​​接使用链接脚本的.so文件如:

GLIBC_2.0 { malloc; }; 

你可以得到你想要的。假设malloc的可执行版本当然没有使用相同的名称进行版本化(不太可能)。

更正:不幸的是,它不工作!定义符号时使用该版本。当您使用它时,它会从导出的表中获取版本。但在可执行文件中的优先...

注意:但请注意,此行为是由设计的ELF标准。这是为了确保同一进程中的所有模块使用相同的功能,所以它们可以共享内存,也就是一个模块malloc,另一个模块free。如果你的程序如此崩溃malloc然后两个之一:你的这么坏了;或程序被破坏。如果是第二个,那么任何其他被链接的模块也会崩溃。因此,也许你应该检查你的代码...

+0

感谢您的回答,但我仍然无法使其工作。还有其他建议吗? – liorix

+0

除非你找到使用dlopen/dlsym的malloc指针,否则我认为你不能这样做。它只是可执行文件的特权来覆盖任何外部公共符号。无论如何,你确定你没有滥用程序的malloc返回的内存吗? – rodrigo

0

你可以用dlsym()明确指出malloc()

#define __USE_GNU 1 /* needed for RTLD_NEXT */ 
#include <dlfcn.h> 

void* (*mymalloc)(size_t a); 

mymalloc = (void* (*)(size_t)) dlsym (RTLD_NEXT, "malloc"); 

当然,你必须为free()realloc()和其他任何你正在使用这样做。

+1

我认为RTLD_NEXT会返回程序的malloc,而不是libc malloc。 – blaze

+0

其实dlsym接收两个参数,模块句柄和符号,所以如果你调用'void * handle = dlopen(“libc.so”); dlsym(句柄,“malloc”);'你应该得到它。 – rodrigo

+0

@blaze:不,我已经尝试过了。 –