#define _GNU_SOURCE #include <stdio.h> #include <dlfcn.h> #include <stdlib.h> #include <stdarg.h> #include <string.h> // gcc -shared -fPIC my_printf.c -o libmy_printf.so -ldl #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int fd = 0; void log (char * buf) { if(!fd){ fd = open("log.txt", O_WRONLY|O_CREAT|O_APPEND); } write(fd, buf, strlen(buf)); write(fd, '\n', 1); sync(); } void str_remove(char *src, char *target){ char *p; char c[81]; char *dst[254]={0}; while((p = strstr(src,target)) != NULL) { //strstr 找不到返回 NULL *p = '\0'; // 指定连接下一步(连接函数)之前 a 的终止位置; strcpy (c, p+strlen(target)); // strcat 函数中的两个传入参数的内存地址不能重叠,所以这里用 c 当作 temp strcat (src, c); } } int printf(const char *format, ...) { va_list list; char *parg; typeof(printf) *old_printf; char *tmp = malloc(strlen(format) + 1); strcpy(tmp, format); /* remove some bad string */ str_remove(tmp, "$p"); str_remove(tmp, "$x"); str_remove(tmp, "hn"); str_remove(tmp, "ln"); str_remove(tmp, "$n"); log(tmp); // format variable arguments va_start(list, tmp); vasprintf(&parg, tmp, list); va_end(list); // get a pointer to the function "printf" old_printf = dlsym(RTLD_NEXT, "printf"); (*old_printf)("%s", parg); // and we call the function with previous arguments free(parg); free(tmp); } int snprintf(char *str, size_t size, const char *format, ...){ va_list list; char *parg; typeof(snprintf) *old_snprintf; char *tmp = malloc(strlen(format) + 1); strcpy(tmp, format); /* remove some bad string */ str_remove(tmp, "$p"); str_remove(tmp, "$x"); str_remove(tmp, "hn"); str_remove(tmp, "ln"); str_remove(tmp, "$n"); log(tmp); // format variable arguments va_start(list, tmp); vasprintf(&parg, tmp, list); va_end(list); // get a pointer to the function "printf" old_snprintf = dlsym(RTLD_NEXT, "snprintf"); (*old_snprintf)(str, size, "%s", parg); // and we call the function with previous arguments free(parg); free(tmp); }
|