加载/运行时打桩

加载/运行时打桩是最灵活的方式,无需重新编译程序即可拦截库函数调用。

加载时打桩(LD_PRELOAD):设置 LD_PRELOAD 环境变量,指定一个自定义共享库的路径。动态链接器在加载程序时,会优先在 LD_PRELOAD 指定的库中查找符号,从而覆盖标准库中的同名函数。

运行时打桩(dlsym):使用 dlsym(RTLD_NEXT, "malloc") 在运行时动态查找真正的 malloc 函数地址。RTLD_NEXT 是一个伪句柄,告诉动态链接器跳过当前库,从下一个库中查找目标符号。

代码示例

#define _GNU_SOURCE
#include <dlfcn.h>
 
void *malloc(size_t size) {
    static void *(*real_malloc)(size_t) = NULL;
    if (!real_malloc)
        real_malloc = dlsym(RTLD_NEXT, "malloc");
    printf("malloc(%zu) called\n", size);
    return real_malloc(size);
}

编译:需要编译为共享库,-ldl 链接 dl 库。使用时通过 LD_PRELOAD 加载:

gcc -shared -fPIC mymalloc.c -o mymalloc.so -ldl
LD_PRELOAD=./mymalloc.so ./myprogram

优点:可应用于任何已经编译好的二进制程序,无需其源代码。广泛用于性能分析工具(如valgrind)、内存检测和调试。

链接到

  • 上一个知识点:7.17 链接时打桩
  • 下一个知识点:无(本章最后一个知识点)