一尘不染

没有dlsym的Linux中的函数插入

linux

我目前工作的一个项目,我需要跟踪的几个系统调用和类似的低层次功能的使用mmapbrksbrk。到目前为止,我一直在使用函数插入进行此操作:我编写了一个与要替换的函数同名的包装函数(mmap例如,),并通过设置LD_PRELOAD环境变量将其加载到程序中。我通过加载的指针调用实函数dlsym

不幸的是,我要包装的函数之一由sbrk内部使用dlsym,因此当我尝试加载符号时程序崩溃。sbrk在Linux中不是系统调用,因此我不能简单地使用syscall它来间接调用它。

所以我的问题是,如何在不使用同名包装函数的情况下调用库函数dlsym?是否有任何编译器技巧(使用gcc)可以让我引用原始功能?


阅读 467

收藏
2020-06-02

共1个答案

一尘不染

参见ld的option --wrap symbol。从手册页:

--wrap symbol对符号使用包装函数。任何未定义的符号引用都将解析为“ __wrap_symbol”。任何对“
__real_symbol”的未定义引用都将解析为符号。

这可以用来为系统功能提供包装。包装函数应称为“ __wrap_symbol”。如果希望调用系统功能,则应调用“ __real_symbol”。

这是一个简单的示例:

void *
__wrap_malloc (size_t c)
{
    printf ("malloc called with %zu\n", c);
    return __real_malloc (c);
}

如果您使用–wrap malloc将其他代码与此文件链接,则所有对“ malloc”的调用都会调用函数“ __wrap_malloc”。在
__wrap_malloc”中对“ __real_malloc”的调用将调用真实的“ malloc”函数。

您可能还希望提供一个“ __real_malloc”函数,以便不带–wrap选项的链接将成功。如果这样做,则不应将“
__real_malloc” 的定义与“ ”放在同一文件中__wrap_malloc;如果您这样做,则汇编程序可能会在链接程序有机会将其包装到“
malloc”之前解决该调用。

另一个选择是可能查看ltrace的源,或多或少地执行相同的操作:-P。

这是个主意。您可以让您LD_PRELOAD的ed库将PLT条目更改为指向您的代码。sbrk()从技术上来说,这仍然可以从您的代码天然地调用该函数。

2020-06-02