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