Linux 中不使用 dlsym 的函数插入
我目前正在开发一个项目,需要跟踪多个系统调用和低级函数(例如 mmap
、brk
、sbrk。 到目前为止,我一直在使用函数插入来完成此操作:我编写了一个与要替换的函数同名的包装函数(例如
mmap
),然后将其加载到程序中设置LD_PRELOAD
环境变量。 我通过使用 dlsym 加载的指针调用实际函数。
不幸的是,我想要包装的函数之一 sbrk
由 dlsym
在内部使用,因此当我尝试加载该符号时程序崩溃。 sbrk
不是 Linux 中的系统调用,因此我不能简单地使用 syscall
来间接调用它。
所以我的问题是,如何在不使用 dlsym 的情况下从同名的包装函数调用库函数? 是否有任何编译器技巧(使用 gcc)让我引用原始函数?
I'm currently working on a project where I need to track the usage of several system calls and low-level functions like mmap
, brk
, sbrk
. So far, I've been doing this using function interposition: I write a wrapper function with the same name as the function I'm replacing (mmap
for example), and I load it in a program by setting the LD_PRELOAD
environment variable. I call the real function through a pointer that I load with dlsym
.
Unfortunately, one of the functions I want to wrap, sbrk
, is used internally by dlsym
, so the program crashes when I try to load the symbol. sbrk
is not a system call in Linux, so I can't simply use syscall
to call it indirectly.
So my question is, how can I call a library function from a wrapper function of the same name without using dlsym
? Is there any compiler trick (using gcc) that lets me refer to the original function?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
truss
在您的系统上不起作用吗? 它在 Solaris 上非常适合此类事情。Does
truss
not work on your system? It works perfectly for this kind of things here on Solaris.请参阅 ld 的选项
--wrap symbol
。 从手册页:另一种选择是可能查看 ltrace 的源代码,它或多或少做了同样的事情:-P。
不过,这里有一个想法。 您可以让
LD_PRELOAD
编辑的库更改 PLT 条目以指向您的代码。 从技术上讲,您仍然可以从代码中调用sbrk()
函数。see ld's option
--wrap symbol
. From the man page:The other option is to possibly look at the source for ltrace, it is more or less does the same thing :-P.
Here's an idea though. You could have your
LD_PRELOAD
'ed library change the PLT entries to point to your code. This you technically thesbrk()
function is still callable from your code nativly.您可以使用以下工具以不显眼的方式检查函数调用:
这些工具允许监视程序在调用函数时通知您,并允许您询问参数。
主要区别是:
You can examine function invocation unobtrusively using tools such as:
These tools allow a monitor program to inform you when a function is called, and allow you to interrogate the arguments.
The main differences are:
如果您正在使用 glibc 运行主机系统,则 libc 有一些我之前使用过的运行时动态链接器的内部后端。 如果我没记错的话,我认为它叫做“__libc_dlsym”。 (要检查,“$ readelf -s /usr/lib/libc.a | grep dlsym”应该有所帮助。)将其声明为具有与 dlsym 相同的参数和返回值的外部链接函数,并使用它来包装 dlsym 本身。
If you are running a host system with glibc, the libc has some internal back end to the runtime dynamic linker that I used some time ago. If I recall correctly, I think it's called '__libc_dlsym'. (To check, "$ readelf -s /usr/lib/libc.a | grep dlsym" should help.) Declare it as an externally linked function with the same arguments and return value that dlsym has and use it to wrap dlsym itself.