2012-02-02 680 views
6

¿Cómo podemos reemplazar una función de biblioteca estándar C con nuestra propia implementación de esa función?Cómo reemplazar la función de biblioteca estándar C?

Por ejemplo, ¿cómo puedo reemplazar strcpy() con mi propia implementación de strcpy() y tener todas las llamadas vinculadas a las nuevas implementaciones?

+0

¿Por qué quieres hacer esto? ¿Qué podría * posiblemente * ser el punto? –

+0

¿Realmente vale la pena el problema? Debería editar el archivo de cabecera string.h, cuya ubicación depende del sistema y el entorno que esté utilizando. Pero creo que sería mejor que escribieras una función separada. – Shredderroy

+0

@CodyGray, supongo, mirando FatalError [respuesta] (http://stackoverflow.com/questions/9107259/how-to-replace-c-standard-library-functioin#9107319), que podría reemplazar cada llamada en un ejecutable propio que imprime la depuración? O algo así, supongo. Probablemente no sea una buena práctica. Debería escribir una nueva función con un nombre diferente y cambiar todas las llamadas. – Anthony

Respuesta

12

Al menos con GCC y glibc, los símbolos para las funciones C estándar son débil y así puede anularlos. Por ejemplo,

strcpy.c:

#include <string.h> 
#include <stdio.h> 

char * strcpy(char *dst, const char *src) 
{ 
    char *d = dst; 
    while (*src) { 
    *d = *src; 
    d++; 
    src++; 
    } 
    printf("Called my strcpy()\n"); 

    return (dst); 
} 

int main(void) 
{ 
    char foo[10]; 
    strcpy(foo, "hello"); 

    puts(foo); 

    return 0; 
} 

y construirlo como esto:

gcc -fno-builtin -o strcpy strcpy.c 

y luego:

$ ./strcpy 
Called my strcpy() 
hello 

señalan la importancia de -fno-builtin aquí. Si no usa esto, GCC reemplazará la llamada strcpy() a una función incorporada, de la cual GCC tiene un número.

No estoy seguro de si esto funciona con otros compiladores/plataformas.

+0

Dato curioso, mi 'strcpy()' tiene un defecto bastante serio. Dado que no es realmente el truco aquí, lo dejaré como un ejercicio para el lector;). – FatalError

+3

Sin embargo, ese es el punto. Reemplazar las funciones probadas de la biblioteca con uno propio es casi 100% garantizado que tiene fallas graves. –

+0

En cuanto a la falla: en esta versión de 'strcpy()', la condición de bucle nunca será falsa si 'src' y' dst' se superponen. – Philip

5

Puede intentar jugar con LD_PRELOAD si está en Linux.

+0

Esta parece ser la manera correcta. [Aquí] (https://github.com/nibrahim/Random-hacks/tree/master/malloc-trace) es un ejemplo, pero la verdadera pregunta es ¿por qué? –

+0

Esto se llama interponer una biblioteca. Debe crear un módulo C que se compila como PIC (código de posición independiente) en un archivo .so. A continuación, establece LD_PRELOAD =/ruta/a/mystrcpy.so También puede lograr lo mismo llamando a dl_open() en su código. Es más fácil simplemente crear mystrcpy.c compilar eso en un módulo de objetos y llamar a todos los demás en su código, y vincularlo al módulo de objetos mystrcpy. También deberá usar una declaración externa para mystrcpy en todas partes. ver: http://stackoverflow.com/questions/426230/what-is-the-ld-preload-trick –

4

No estoy seguro de lo difícil que será hacer que el enlazador haga lo que desea, pero aquí hay una solución que no implica cambiar ninguna configuración del enlazador y utiliza macros de preprocesador para que cualquier código que intente llamar strcpy llama en realidad una función llamada my_strcpy:

mystuff.h:

#define strcpy my_strcpy 
char * my_strcpy(char * dst, const char * src); 

my_strcpy.c:

#include <mystuff.h> 
char * my_strcpy(char * dst, const char * src); 
{ 
    ... 
} 

my_code.c:

#include <mystuff.h> 

int main() 
{ 
    /* Any call to strcpy will look like a normal call to strcpy 
     but will actually call my_strcpy. */ 
} 
Cuestiones relacionadas