您可以处理程序本身中的一些动态链接。阅读 dlsym(3) 的手册页,并阅读 dlopen(3)、dlerror(3) 和 dlclose(3) 以了解其余的动态链接接口。
一个简单的例子——假设我想从 libc 覆盖 dup2(2)。我可以使用以下代码(我们称之为“dltest.c”):
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dlfcn.h>
int (*prev_dup2)(int oldfd, int newfd);
int dup2(int oldfd, int newfd) {
printf("DUP2: %d --> %d\n", oldfd, newfd);
return prev_dup2(oldfd, newfd);
}
int main(void) {
int i;
prev_dup2 = dlsym(RTLD_NEXT, "dup2");
if (!prev_dup2) {
printf("dlsym failed to find 'dup2' function!\n");
return 1;
}
if (prev_dup2 == dup2) {
printf("dlsym found our own 'dup2' function!\n");
return 1;
}
i = dup2(1,3);
if (i == -1) {
perror("dup2() failed");
}
return 0;
}
编译:
gcc -o dltest dltest.c -ldl
静态链接的 dup2() 函数会覆盖库中的 dup2()。即使该函数位于另一个 .c 文件中(并且被编译为单独的 .o),这仍然有效。
如果您的覆盖函数本身是动态链接的,您可能希望使用 dlopen() 而不是信任链接器以正确的顺序获取库。
编辑:我怀疑如果重写库中的不同函数调用重写函数,则调用原始函数而不是重写。我不知道如果一个动态库调用另一个动态库会发生什么。