es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿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>

Tags:  , , , ,

Answer

  1. Avatar for 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 desde localtime(). 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 o ltrace para determinar qué llamada al sistema está realizando localtime() 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 como sscanf().

Comments are closed.