概述在没有dlsym的Linux中的函数插入
我目前正在开发一个项目,在这个项目中我需要跟踪几个系统调用和像mmap , brk , sbrk这样的低级函数的使用。 到目前为止,我一直在使用函数插入来做这件事:我写一个与我要replace的函数名称相同的包装函数(例如mmap ),并通过设置LD_PRELOAD环境variables将其加载到程序中。 我通过一个用dlsym加载的指针调用真正的函数。
不幸的是,我想包装的function之一, sbrk ,由dlsym内部使用,所以当我尝试加载符号时,程序崩溃。 sbrk不是linux系统调用,所以我不能简单地使用syscall调用间接调用它。
所以我的问题是,如何不使用dlsym从同名的包装函数调用库函数? 有没有什么编译器技巧(使用gcc)让我参考原始函数?
如何与两个具有许多冲突函数的共享库链接
请参阅ld的选项 – –wrap symbol 。 从手册页:
– wrap符号使用符号的包装函数。 任何未定义的符号引用将被解析为“ __wrap_symbol ”。 对“ __real_symbol ”的任何未定义的引用将被解析为符号。
这可以用来为系统功能提供包装。 包装函数应该被称为“ __wrap_symbol ”。 如果它希望调用系统函数,它应该调用“ __real_symbol ”。
这是一个微不足道的例子:
voID * __wrap_malloc (size_t c) { printf (\”malloc called with %zun\”,c); return __real_malloc (c); }
如果使用–wrap malloc链接其他代码,则所有对“ malloc ”的调用将调用函数“ __wrap_malloc ”。 调用“__real_malloc”中的
“ __wrap_malloc ”将调用真正的“ malloc ”函数。
你也可以提供一个“ __real_malloc ”函数,这样没有–wrap选项的链接将会成功。 如果你这样做,你不应该把“ __real_malloc ”的定义放在与“ __real_malloc ”相同的文件中; 如果这样做,汇编程序可能会在链接器有机会将其包装到“malloc”之前解析调用。
另一个选择是可能查看ltrace的源代码,或多或少做同样的事情:-P。
这是一个想法。 你可以让你的LD_PRELOAD库改变plt条目来指向你的代码。 这在技术上, sbrk()函数仍然可以从您的代码本身调用。
您可以使用以下工具轻松地检查函数调用:
GDB
ltrace
SystemTap的
这些工具允许监视器程序在调用函数时通知您,并允许您询问参数。
主要区别是:
gdb是交互式的,但功能强大
ltrace使用简单,但只能打印函数名称
systemtap不是互动的,但它可以非常快速,而且功能强大。
如果您正在运行一个包含glibc的主机系统,那么libc的某些内部后端就是我之前使用的运行时动态链接程序。 如果我记得正确,我认为它被称为“__libc_dlsym”。 (要检查,“$ readelf -s /usr/lib/libc.a | grep dlsym”应该有帮助。)将它声明为外部链接的函数,它具有与dlsym相同的参数和返回值,并用它来包装dlsym本身。
truss不能在你的系统上工作吗? 它在Solaris上适用于这种类型的东西。
总结
以上是内存溢出为你收集整理的在没有dlsym的Linux中的函数插入全部内容,希望文章能够帮你解决在没有dlsym的Linux中的函数插入所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
请登录后查看评论内容