¿Cómo puedo reimplementar (o empaquetar) una función syscall en Linux?
Supongamos que quiero tomar completamente el control de la llamada al sistema open (), tal vez para envolver el syscall real y realizar algún registro. Una forma de hacer esto es usar LD_PRELOAD para cargar una biblioteca de objetos compartidos (hecha por el usuario) que toma el control del punto de entrada open ().
La rutina open() hecha por el usuario obtiene el puntero a la función glibc open()
por dlsym()
ing it, y llamándola.
La solución propuesta anteriormente es una solución dinámica, sin embargo. Supongamos que quiero vincular mi propio open()
envoltura estática. ¿Cómo lo haría? Supongo que el mecanismo es el mismo, pero también supongo que habrá un choque de símbolos entre el open()
definido por el usuario y el libc open()
.
Por favor, comparta cualquier otra técnica para lograr el mismo objetivo.
2 answers
Puede utilizar la función wrap proporcionada por ld
. De man ld
:
--wrap symbol
Utilice una función de envoltura para el símbolo. Cualquier referencia indefinida asymbol
se resolverá a__wrap_symbol
.Cualquier referencia indefinida a
__real_symbol
se resolverá asymbol
.
Así que solo tienes que usar el prefijo __wrap_
para tu función wrapper y __real_
cuando quieras llamar a la función real. Un ejemplo simple es:
malloc_wrapper.c
:
#include <stdio.h>
void *__real_malloc (size_t);
/* This function wraps the real malloc */
void * __wrap_malloc (size_t size)
{
void *lptr = __real_malloc(size);
printf("Malloc: %lu bytes @%p\n", size, lptr);
return lptr;
}
Aplicación de prueba testapp.c
:
#include <stdio.h>
#include <stdlib.h>
int main()
{
free(malloc(1024)); // malloc will resolve to __wrap_malloc
return 0;
}
Luego compile la aplicación:
gcc -c malloc_wrapper.c
gcc -c testapp.c
gcc -Wl,-wrap,malloc testapp.o malloc_wrapper.o -o testapp
La salida de la aplicación resultante será:
$ ./testapp
Malloc: 1024 bytes @0x20d8010
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-07 21:53:16
Los símbolos son resueltos por el enlazador en el orden en que los listamos en la línea de comandos, por lo que si listó su biblioteca antes de la biblioteca estándar, tendría precisión. Para gcc, debe especificar
gcc <BLAH> -nodefaultlibs <BLAH BLAH> -lYOUR_LIB <OTHER_LIBS>
De esta manera sus bibliotecas serían buscadas y encontradas primero.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-07 21:39:46