我们如何用我们自己的函数替换C标准库中的函数?
例如,我如何用我自己的strcpy()
替换标准库中的strcpy()
,并让所有调用链接到新实现而不是标准库中的实现?
我们如何用我们自己的函数替换C标准库中的函数?
例如,我如何用我自己的strcpy()
替换标准库中的strcpy()
,并让所有调用链接到新实现而不是标准库中的实现?
至少在使用GCC和glibc的情况下,标准C函数的符号是弱符号,因此您可以覆盖它们。例如,
strcpy.c:
#include <string.h>
#include <stdio.h>
char * strcpy(char *dst, const char *src)
{
char *d = dst;
while (*src) {
*d = *src;
d++;
src++;
}
printf("Called my strcpy()\n");
return (dst);
}
int main(void)
{
char foo[10];
strcpy(foo, "hello");
puts(foo);
return 0;
}
然后像这样构建:
gcc -fno-builtin -o strcpy strcpy.c
然后:
$ ./strcpy
Called my strcpy()
hello
注意这里 -fno-builtin
的重要性。如果您不使用它,GCC 将把 strcpy()
调用替换为一个内建函数,而 GCC 有很多内建函数。
我不确定这是否适用于其他编译器/平台。
strcpy()
函数有一个非常严重的缺陷。既然这不是真正的重点,我将其留给读者作为练习;)。 - FatalErrorstrcpy()
中,如果src
和dst
重叠,则循环条件永远不会为假。 - Philipstrcpy()
从来没有保证覆盖字符串的情况下可以正常工作,但是它确保在目标字符串末尾添加空字符。 ;) - FatalError如果你使用的是Linux系统,可以尝试使用LD_PRELOAD进行实验。
我不确定让连接器按照你的要求操作会有多难,但是这里有一个解决方案,它不需要改变任何连接器设置,而是使用预处理器宏,以便任何尝试调用strcpy的代码都会实际调用一个名为my_strcpy的函数:
mystuff.h:
#define strcpy my_strcpy
char * my_strcpy(char * dst, const char * src);
my_strcpy.c:
#include <mystuff.h>
char * my_strcpy(char * dst, const char * src);
{
...
}
my_code.c:
#include <mystuff.h>
int main()
{
/* Any call to strcpy will look like a normal call to strcpy
but will actually call my_strcpy. */
}
rintf()
的报告,漏洞和问题。 - Daniel Fischer