¿Puedo hacer llamadas anidadas para funciones del sistema cargadas por LD_PRELOAD?
Hola, estoy tratando de anular sscanf()
que se llama desde localtime()
, pero no está llamando a sscanf()
de mi biblioteca cargada, sino a sscanf()
de glibc.
¿Estoy omitiendo algo?
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 isoc99sscanf(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 siguiendo:
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 foo
output que estoy obteniendo:
./foo
my_local
Current local time and date: Wed Mar 10 18:20:47 2021
El resultado esperado es:
Debería imprimir “test” también, desde printf("test\n")
de sscanf()
anulado. Ya que localtime()
tiene una llamada interna a sscanf()
y he anulado e instruido a usar también sscanf()
.
¿Hay alguna forma de anular otra llamada al sistema como en este ejemplo sscanf()
que se llama internamente desde localtime()
?
Jerarquía de llamadas como se muestra a continuación:
localtime() -> __tz_convert() -> __tzfile_compute() -> __tzset_parse_tz() -> parse_offset() -> sscanf()
</time.h></stdio.h></dlfcn.h></time.h></stdio.h></stdarg.h>
davy.ai
Parece que el enfoque que estás utilizando para anular
sscanf()
es correcto, pero puede haber algunos factores adicionales que influyen en el motivo por el cual no se llama desdelocaltime()
. Una posibilidad podría ser que la versión de glibc que estás utilizando tenga una prioridad más alta que tu biblioteca personalizada, lo que significa que siempre se llamará a la versión de glibc en lugar de a tu versión.En cuanto a tu pregunta sobre anular otra llamada al sistema que es realizada por una función que estás interceptando, es posible, pero puede requerir una instrumentación más compleja. En este caso, podría ser necesario utilizar una herramienta más avanzada como
strace
oltrace
para determinar qué llamada al sistema está realizandolocaltime()
y luego interceptar esa llamada directamente. Sin embargo, este enfoque probablemente sería más desafiante que interceptar una función de biblioteca estándar comosscanf()
.