gpt4 book ai didi

c - 如何覆盖标准的 libc 函数?

转载 作者:太空狗 更新时间:2023-10-29 15:02:13 26 4
gpt4 key购买 nike

例如,如果我想覆盖 malloc(),最好的方法是什么?

目前我知道的最简单的方法是:

malloc.h

#include <stdlib.h>
#define malloc my_malloc
void* my_malloc (size_t size);

foobar.c

#include "malloc.h"

void foobar(void)
{
void* leak = malloc(1024);
}

这种方法的问题是我们现在必须使用“malloc.h”而永远不能使用“stdlib.h”。有没有解决的办法?我特别感兴趣的是导入第 3 方库而不修改它们,而是强制它们调用我的自定义 libc 函数(如 malloc)。

最佳答案

简短的回答是您可能想使用 LD_PRELOAD 技巧:What is the LD_PRELOAD trick?

该方法基本上是在加载任何其他共享库之前在运行时插入您自己的自定义共享库,导出您想要覆盖的函数,例如 malloc()。当加载其他共享库时,您的符号已经存在并在解析从其他库对该符号名称的调用时获得优先权。在您的 malloc() 包装器/替换中,您甚至可以选择调用下一个 malloc 符号,这通常是实际的 libc 符号。

这篇博文有很多关于这种方法的综合信息:

http://samanbarghi.com/blog/2014/09/05/how-to-wrap-a-system-call-libc-function-in-linux/

请注意,示例覆盖了 libc 的 write() 和 puts() 函数,但相同的逻辑适用于 malloc():

LD_PRELOAD allows a shared library to be loaded before any other libraries. So all I need to do is to write a shared library that overrides write and puts functions. If we wrap these functions, we need a way to call the real functions to perform the system call. dlsym just do that for us [man 3 dlsym]: > The function dlsym() takes a “handle” of a dynamic library returned by dlopen() and the null-terminated symbol name, returning the address where that symbol is loaded into memory. If the symbol is not found, in the specified library or any of the libraries that were automatically loaded by dlopen() when that library was loaded, dlsym() returns NULL…

So inside the wrapper function we can use dlsym to get the address of the related symbol in memory and call the glibc function. Another approach can be calling the syscall directly, both approaches will work.

该博文还描述了一种我不知道的编译时方法,它涉及将链接器标志传递给 ld,“--wrap”:

Another way of wrapping functions is by using linker at the link time. GNU linker provides an option to wrap a function for a symbol [man 1 ld]: > Use a wrapper function for symbol. Any undefined reference to symbol will be resolved to “__wrap_symbol”. Any undefined reference to “__real_symbol” will be resolved to symbol.

LD_PRELOAD 的便利之处在于它可能允许您更改生产应用程序上的 malloc() 实现以进行快速测试,甚至允许用户选择(我在某些服务器应用程序中这样做)要使用的实现。 ' tcmalloc ' 例如,库可以很容易地插入到应用程序中,以评估重线程应用程序的性能提升(其中 tcmalloc 的性能往往比 libc 的 malloc 实现好得多)。

最后,如果您使用的是 Windows,也许可以试试这个:LD_PRELOAD equivalent for Windows to preload shared libraries

关于c - 如何覆盖标准的 libc 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28227266/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com