假设我想完全接管open()系统调用,也许要包装实际的syscall并执行一些日志记录。一种方法是使用LD_PRELOAD加载(用户制作的)共享对象库,该库将接管open()入口点。
然后,用户制作的open()例程open()通过dlsym()调用glibc函数来获取它的指针。
open()
dlsym()
但是,以上提出的解决方案是动态解决方案。假设我想open()静态链接我自己的包装器。我该怎么办?我猜想机制是一样的,但我也猜想用户定义open()和libc 之间会有符号冲突open()。
请分享其他任何技术来达到相同的目标。
您可以使用提供的包装功能ld。来自man ld:
ld
man ld
--wrap symbol对符号使用包装函数。对的任何未定义引用 symbol都将解析为__wrap_symbol。 对的任何未定义引用__real_symbol都将解析为symbol。
--wrap symbol对符号使用包装函数。对的任何未定义引用 symbol都将解析为__wrap_symbol。
--wrap symbol
symbol
__wrap_symbol
对的任何未定义引用__real_symbol都将解析为symbol。
__real_symbol
因此,您只需要__wrap_在包装函数中使用前缀,并__real_在要调用实函数时使用前缀即可。一个简单的例子是:
__wrap_
__real_
malloc_wrapper.c:
malloc_wrapper.c
#include <stdio.h> void *__real_malloc (size_t); /* This function wraps the real malloc */ void * __wrap_malloc (size_t size) { void *lptr = __real_malloc(size); printf("Malloc: %lu bytes @%p\n", size, lptr); return lptr; }
测试应用testapp.c:
testapp.c
#include <stdio.h> #include <stdlib.h> int main() { free(malloc(1024)); // malloc will resolve to __wrap_malloc return 0; }
然后编译应用程序:
gcc -c malloc_wrapper.c gcc -c testapp.c gcc -Wl,-wrap,malloc testapp.o malloc_wrapper.o -o testapp
结果应用程序的输出将是:
$ ./testapp Malloc: 1024 bytes @0x20d8010