我目前正在开展一个项目,我需要跟踪多个系统调用和低级函数的使用情况,例如mmap
,brk
,sbrk
。到目前为止,我一直在使用函数插入来执行此操作:我编写了一个与我正在替换的函数(例如mmap
)同名的包装函数,并通过设置{将其加载到程序中{1}}环境变量。我通过我加载LD_PRELOAD
的指针调用实际函数。
不幸的是,我想要包装的函数之一dlsym
由sbrk
内部使用,因此当我尝试加载符号时程序崩溃。 dlsym
不是Linux中的系统调用,因此我不能简单地使用sbrk
间接调用它。
所以我的问题是,如何在不使用syscall
的情况下从同名的包装函数调用库函数?是否有任何编译器技巧(使用gcc)让我参考原始函数?
答案 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)
您可以使用以下工具不引人注意地检查函数调用:
这些工具允许监视程序在调用函数时通知您,并允许您查询参数。
主要区别是:
答案 2 :(得分:0)
如果你正在运行一个带glibc的主机系统,那么libc有一些内部后端到我前一段时间使用的运行时动态链接器。如果我没记错的话,我认为它被称为'__libc_dlsym'。 (要检查,“$ readelf -s /usr/lib/libc.a | grep dlsym”应该有帮助。)将它声明为具有相同参数的外部链接函数,并返回dlsym具有的值,并使用它来包装dlsym本身。
答案 3 :(得分:0)
truss
无法在您的系统上运行吗?它适用于Solaris上的这类内容。