Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 覆盖DLED库中的malloc/free_Linux_Malloc_Libc_Dlopen - Fatal编程技术网

Linux 覆盖DLED库中的malloc/free

Linux 覆盖DLED库中的malloc/free,linux,malloc,libc,dlopen,Linux,Malloc,Libc,Dlopen,我有一个共享库-插件。因此,它是由主机程序使用标志RTLD_LOCAL定义的dlopen,我在该库中定义了自己的内存操作函数: void *plugin_malloc(size_t size) { /* ... */ } void plugin_free(void *ptr) { /* ... */ } 我需要的是替换plugin中的所有malloc/free调用。因此使用我自己的plugin\u malloc/plugin\u free,我尝试使用GCC的别名属性扩展: void *mall

我有一个共享库-
插件。因此
,它是由主机程序使用标志
RTLD_LOCAL
定义的
dlopen
,我在该库中定义了自己的内存操作函数:

void *plugin_malloc(size_t size) { /* ... */ }
void plugin_free(void *ptr) { /* ... */ }
我需要的是替换
plugin中的所有
malloc/free
调用。因此
使用我自己的
plugin\u malloc/plugin\u free
,我尝试使用GCC的别名属性扩展:

void *malloc(size_t) __attribute__((alias("plugin_malloc"), used))
void free(void*) __attribute__((alias("plugin_free"), used))
但是,这仅在库链接到主机程序时有效,而不能使用
dlopen
方式

我在Linux上使用编译器GCC-4.8.5,我有
插件的源代码。因此
可以随意修改,但我不能修改主机程序,并且不仅在
插件中替换
malloc/free
。因此
而且在整个程序中也是可以接受的

那么,有什么解决办法吗?谢谢



编辑:我也没有权限修改主机程序的启动参数、环境变量,我能做的只是提供
插件。所以
给拥有主机程序的人,它们运行主机程序和
dlopen
my
插件。因此

考虑到您在使用
-fPIC
编译的共享库中提供了一对名为malloc和free的函数(例如,而不是plugin\u malloc),那么在调用客户端应用程序时,您只需
LD\u预加载它即可:

LD_PRELOAD=/path/mymalloc.so executable
或在呼叫您的客户之前将其导出:

export LD_PRELOAD=/path/mymalloc.so
executable
更多详情:

[更新]

考虑到您不能更改环境,只能替换动态库,而无需其他内容,因此您可以:

  • 查找malloc/free在内存中的位置
  • 将jmp的原始函数条目代码替换为您自己的函数
你的库需要一个初始化函数来完成这项肮脏的工作。检查构造函数属性。但是,可能不允许替换代码

另一种探索的可能性(oit?)是:如果代码使用glibc,那么可以尝试在库中提供一个

还有一个:在库init函数中获取应用程序控件,然后使用自定义设置再次执行该应用程序

考虑到你的限制,我现在不能提出任何其他的可能性

我需要的是替换plugin中的所有malloc/free调用。因此,使用我自己的plugin\u malloc/plugin\u free

这是一件小事

假设您有
foo.o
plugin\u malloc.o
链接到
plugin.so
foo.o
使用
malloc
free
,而
plugin.o
定义
plugin\u malloc
plugin\u free

然后:

瞧:
foo.o
中对
malloc
free
的所有引用都已被替换。享受

更新:

如果我调用一个glibc函数来分配内存,并且需要在代码中释放,那么程序就会崩溃。e、 g.char*s=strdup(“你好”);免费的;因为strdup调用glibc的malloc,但是后面的免费插件是我的免费插件

有几种方法可以满足您的其他约束:

  • 对于整个程序,您必须将所有
    malloc
    s和
    free
    s替换为您自己的(例如,通过
    LD_PRELOAD
    ,或通过将
    malloc
    实现静态链接到主可执行文件中),或
  • 您必须确保不调用任何通过
    malloc
    分配内存的函数,这些函数在
    free
    之后将被调用,或者
  • 对于对stdup
  • 或asprintf等的任何此类调用,当您要释放此内存时,必须调用
    \uu libc\u free
    ,而不是
    plugin\u free
    ,或者
  • plugin\u malloc
    中,用16个额外字节的头(用于对齐)填充所有分配的内存,将幻数写入块的开头,并将一个指针经过头返回给调用者。在plugin_free中,检查对齐是否正确,然后检查标题是否有幻数。如果有,从指针中减去16,然后使用剩余的
    plugin\u free
    释放内存。如果魔法数字不在那里,则假定指针不是来自
    插件\u malloc
    ,并对其调用
    \uu libc\u free
  • plugin\u malloc
    中跟踪您分配的所有块。在
    plugin\u free
    中检查该列表,如果指针不在列表中,则使用
    \u libc\u free
  • 既然你有插件的所有来源,解决方案2或3都应该是可行的,但显然需要你审核对
    free
    的每次调用,以查看内存来自何处

    变体4和5不需要这样的审计,但并没有将插件分配的内存与主程序分配的内存完全分开


    不要忘记其他分配内存的方法:
    realloc
    memalign
    posix\u memalign
    ,等等。

    你可以通过LD\u预加载技巧来实现这一点:@Leo对不起,我不能这样做,因为我没有运行该程序的权限,我所能做的就是提供
    插件。因此,
    给拥有主机程序的人,我在帖子中添加了此信息。抱歉,我不能这样做,因为我没有运行该程序的权限,我所能做的就是提供
    插件。因此
    对于拥有该主机程序的人,我将此信息添加到帖子中。不,你没有说你不能更改环境。是的,这是我的错,现在我将其添加到帖子中。所以。。。将
    .text
    段更改为可写,找到
    malloc/free
    的地址,然后在函数开始处编写
    JMP plugin\u malloc/plugin\u free
    指令?看起来是可行的,但这真的是一个肮脏的解决方案…它既肮脏又粗糙。看起来像是破解了别人的密码。然而,你的c
    objcopy --redefine-sym malloc=plugin_malloc --redefine-sym free=plugin_free foo.o foo2.o
    gcc -shared -fPIC plugin.o foo2.o -o plugin.so