Linux中没有dlsym的函数插入

时间:2009-06-15 21:22:02

标签: c linux function-interposition dlsym

我目前正在开展一个项目,我需要跟踪多个系统调用和低级函数的使用情况,例如mmapbrksbrk。到目前为止,我一直在使用函数插入来执行此操作:我编写了一个与我正在替换的函数(例如mmap)同名的包装函数,并通过设置{将其加载到程序中{1}}环境变量。我通过我加载LD_PRELOAD的指针调用实际函数。

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

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

4 个答案:

答案 0 :(得分:14)

查看ld的选项--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”代替。该   在中打电话给“__real_malloc”   “__wrap_malloc”将称之为真实   “malloc”功能。

     

您可能希望提供一个   “__real_malloc”功能也是如此   没有--wrap选项的链接   将会成功。如果你这样做,你   不应该把定义   “__real_malloc”与...相同的文件中   “__wrap_malloc”;如果你这样做的话   汇编程序可以解决之前的呼叫   链接器有机会将其包装   “malloc的”。

另一种选择是可能会查看ltrace的来源,它或多或少都是同样的事情:-P。

这是一个想法。您可以让LD_PRELOAD'ed库更改PLT条目以指向您的代码。从技术上讲,sbrk()函数仍然可以从您的代码中自行调用。

答案 1 :(得分:2)

您可以使用以下工具不引人注意地检查函数调用:

  • GDB
  • ltrace
  • 的systemtap

这些工具允许监视程序在调用函数时通知您,并允许您查询参数。

主要区别是:

  • gdb是互动的,但功能强大
  • ltrace简单易用,但您只能打印功能名称
  • systemtap不是交互式的,但它可以非常快,并且功能强大。

答案 2 :(得分:0)

如果你正在运行一个带glibc的主机系统,那么libc有一些内部后端到我前一段时间使用的运行时动态链接器。如果我没记错的话,我认为它被称为'__libc_dlsym'。 (要检查,“$ readelf -s /usr/lib/libc.a | grep dlsym”应该有帮助。)将它声明为具有相同参数的外部链接函数,并返回dlsym具有的值,并使用它来包装dlsym本身。

答案 3 :(得分:0)

truss无法在您的系统上运行吗?它适用于Solaris上的这类内容。