gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 16:06:08 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() 和 put() 函数,但相同的逻辑适用于 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/60046566/

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