Hola, estoy tratando de anular sscanf() que se llama desde localtime() , pero no llama a sscanf() de mi biblioteca cargada sino que llama a sscanf() de glibc.
¿Hay algo que este olvidando?
El contenido de los archivos se menciona a continuación:
//preload_localtime.c #include <stdarg.h> #include <stdio.h> #include <time.h> #include <dlfcn.h> __attribute__((force_align_arg_pointer)) int sscanf(const char *str, const char *format, ...) { int ret; va_list ap; printf("test\n"); va_start(ap, format); ret = vsscanf(str, format, ap); va_end(ap); return ret; } __attribute__((force_align_arg_pointer)) int __isoc99_sscanf(const char *str, const char *format, ...) { int ret; va_list ap; printf("test\n"); va_start(ap, format); ret = vsscanf(str, format, ap); va_end(ap); return ret; } __attribute__((force_align_arg_pointer)) struct tm * localtime(const time_t *timep) { static struct tm *(*real_localtime)(const time_t *) = (void*)0; printf("my_local\n"); if (!real_localtime) real_localtime = dlsym(RTLD_NEXT, "localtime"); return real_localtime(timep); } //foo.c #include <stdio.h> #include <time.h> int main(void) { int i; //sscanf("42", "%d", &i); //printf("%d\n", i); time_t rawtime; struct tm * timeinfo; time (&rawtime); timeinfo = localtime (&rawtime); printf ("Current local time and date: %s", asctime(timeinfo)); return 0; }Pasos que estoy haciendo:
# gcc -fPIC -shared preload_localtime.c -o preload_localtime.so -ldl -D_GNU_SOURCE=1 #export LD_PRELOAD=$PWD/preload_localtime.so gcc foo.c -o foosalida que estoy obteniendo:
# ./foo my_local Current local time and date: Wed Mar 10 18:20:47 2021 Lo que se espera de la salida: también debe imprimir la test , desde printf("test\n"); de sscanf() anulado. Dado que localtime() internamente tiene una llamada a sscanf() y he anulado e instruido que use sscanf() también.
¿HAY alguna forma de anular otra llamada del sistema como en este ejemplo sscanf() que se llama internamente desde localtime() .
Jerarquía de llamadas de la siguiente manera:
localtime()->__tz_convert() ->__tzfile_compute() -->__tzset_parse_tz() -->parse_offset() -->sscanf()LD_PRELOAD funciona al ser el primer símbolo del mismo nombre encontrado por el enlazador dinámico, por lo que si el uso de un símbolo se puede resolver en tiempo de compilación, el enlace dinámico no lo afectará porque localtime y sscanf existen en el mismo binario, la llamada puede ser muy bueno, será estático: la llamada se puede resolver en tiempo de compilación y el enlazador dinámico no está involucrado en esta cadena de llamadas.