systemadmin.es » Capturar llamadas al sistema con LD_PRELOAD

Capturar llamadas al sistema con LD_PRELOAD

Mediante el uso de la variable de entorno LD_PRELOAD podemos cargar librerías dinámicas que sobrescriban llamadas al sistema. Vamos a ver como:

Un ejemplo en el que muy bien podemos utilizar LD_PRELOAD es cuando algún daemon no tiene la opción de funcionar sin pasar a background y luego no utiliza más la llamada fork().

Primero de todo creamos una función igual que la que queremos substituir con cualquier acción que queramos que se haga, en este caso no realizar el fork i devolver el zero:

#include <sys/types.h>
#include <unistd.h>

pid_t fork(void)
{
        return 0;
}

Para crear la librería dinámica lo haremos mediante el siguiente comando:

gcc -Wall -fPIC -shared -o forkfaker.so forkfaker.c

A continuación podremos ejecutar el daemon con la variable LD_PRELOAD:

LD_PRELOAD="./forkfaker.so" /usr/bin/daemon.ejemplo

En el caso que el daemon vaya a background pero después necesite realizar más forks no nos vale ya que los siguientes forks no funcionaran correctamente. Para ello podemos crear una librería que no realice el primer fork pero si todo el resto mediante la llamada a syscall() para realizar el fork real:

#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>

static int count=0;

pid_t fork(void)
{
        if (count < 1)
        {
                ++count;
                return 0;
        }
        return syscall(SYS_fork);
}

De esta manera podemos usar con daemontools cualquier daemon que pase a background y del cual no queramos modificar el código fuente. Un ejemplo sería el miniserv de webmin:

#!/bin/bash
LD_PRELOAD="/usr/local/lib/forkfaker.so" exec /usr/bin/perl /usr/local/webmin/miniserv.pl /usr/local/webmin/etc/miniserv.conf

En el caso que sea necesario más de un fork inicial sólo deberemos cambiar la condición del if que cuenta las veces que denegamos los forks.

Relacionados

Imprimir Imprimir

3 comments to “Capturar llamadas al sistema con LD_PRELOAD”

  1. ¡Sencillamente EXCELENTE!

  2. Hola,

    un poco tarde, pero buscando cosas sobre LD_PRELOAD salió este artículo. ¿No es posible sobreescribir funciones internas del programa con LD_PRELOAD? Es decir, imagina que en vez de fork queremos sobreescribir una función propia del programa:

    char* haz_cosas(char, int, char);

    ¿Hay alguna forma?

    Saludos y gracias

    Jordi Prats:

    Puedes sobrescribir llamadas a funciones de librerías, pero no el propio código. Si quieres modificar la ejecución de una función sin el código fuente deberías parchear el binario.

Deja un comentario:

XHTML - Tags permitidos:<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>