2010-10-27 8 views
9

Supongamos que tengo un binario ELF que está vinculado dinámicamente, y quiero anular/redirigir ciertas llamadas a la biblioteca. Sé que puedo hacer esto con LD_PRELOAD, pero quiero una solución que sea permanente en el binario, independiente del entorno, y que funcione para binarios setuid/setgid, ninguno de los cuales LD_PRELOAD puede lograr.Parche de código/símbolos en un binario ELF de enlace dinámico

Lo que me gustaría hacer es agregar código de archivos de objetos adicionales (posiblemente en secciones nuevas, si es necesario) y agregar los símbolos de estos archivos de objetos a la tabla de símbolos del binario para que la nueva versión del código utilizado en lugar del código de la biblioteca compartida. Creo que esto debería ser posible sin realizar ninguna reubicación en el código existente; a pesar de que están en el mismo archivo, estos deberían poder resolverse en el tiempo de ejecución de la manera habitual PLT (por lo que vale, solo me importan las funciones, no los datos).

Por favor no me responda a lo largo de la línea "¡No quieres hacer esto!" o "¡Eso no es portátil!" En lo que estoy trabajando es en una forma de interconectar binarios con implementaciones alternativas de bibliotecas compartidas ligeramente incompatibles con ABI. La plataforma en cuestión es i386-linux (es decir, 32 bits) si es importante. A menos que me equivoque sobre lo que es posible, podría escribir algunas herramientas para analizar los archivos ELF y realizar mis hacks, pero sospecho que hay una forma elegante de usar el enlazador GNU y otras herramientas para lograr esto sin escribir código nuevo.

+0

No sé si esto es trabaje cualquier cosa para usted, pero revise el comando del sistema 'nm' (probablemente ya lo sepa). Da bastante información acerca de un modo. – Marm0t

+0

¡Guau, el truco de LD_PRELOAD parece divertido! Yo también estoy buscando una manera de hacerlo en el binario sin embargo. Mi problema es que mi binario tiene un símbolo que el enlazador de BeagleBone no puede resolver. – CJxD

Respuesta

5

Sugiero elfsh et al. herramientas del proyecto ERESI, si desea instrumentar los archivos ELF por sí mismos. La compatibilidad con i386-linux no es un problema, ya que la utilicé para el mismo propósito.

Los procedimientos relevantes son here.

+0

Parece que llevará algo de lectura, pero creo que esta es la herramienta que estaba buscando. ¡Gracias! –

+0

¿Hay * alguna * documentación para ERESI? No puedo encontrar ningún "inicio", ejemplos, etc. –

+0

Hmm, parece que no hay ninguno (¿todos los enlaces apuntan a svn?). –

0

Puede manejar algunos de los enlaces dinámicos en su programa. Lea la página man para dlsym (3) en particular, y dlopen (3), dlerror (3) y dlclose (3) para el resto de la interfaz de enlace dinámico.

Un ejemplo simple: digamos que quiero anular dup2 (2) desde libc. Podría utilizar el siguiente código (vamos a llamarlo "dltest.c"):

#define _GNU_SOURCE 

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <dlfcn.h> 

int (*prev_dup2)(int oldfd, int newfd); 

int dup2(int oldfd, int newfd) { 
    printf("DUP2: %d --> %d\n", oldfd, newfd); 
    return prev_dup2(oldfd, newfd); 
} 

int main(void) { 
    int i; 

    prev_dup2 = dlsym(RTLD_NEXT, "dup2"); 
    if (!prev_dup2) { 
     printf("dlsym failed to find 'dup2' function!\n"); 
     return 1; 
    } 
    if (prev_dup2 == dup2) { 
     printf("dlsym found our own 'dup2' function!\n"); 
     return 1; 
    } 

    i = dup2(1,3); 
    if (i == -1) { 
     perror("dup2() failed"); 
    } 

    return 0; 
} 

compilar con:

gcc -o dltest dltest.c -ldl 

La función dup2 enlazado estáticamente() anula el dup2() de la biblioteca. Esto funciona incluso si la función está en otro archivo .c (y se compila como un archivo .o separado).

Si sus funciones principales están vinculadas dinámicamente, puede utilizar dlopen() en lugar de confiar en el enlazador para obtener las bibliotecas en el orden correcto.

EDIT: Sospecho que si una función diferente dentro de la biblioteca anulada llama a una función anulada, se llama a la función original en lugar de anularla. No sé qué sucederá si una biblioteca dinámica llama a otra.

+0

Estoy tratando de modificar binarios, no fuente. –

2

ld tiene la opción --wrap que le permite reemplazar un símbolo dado como malloc por un símbolo que llamaría __wrap_malloc. Con eso podrías escribir algunos stubs para las funciones que te interesan y vincularlas a la biblioteca en cuestión.

+0

De nuevo, esta pregunta se trata de aplicar parches a los archivos binarios, sin incluir las llamadas a la biblioteca en los programas que compilo. –

+0

R .: No veo por qué no puedes hacer lo que le pediste en tu pregunta con lo que propongo. A '__wrap_malloc' no es necesario llamar al antiguo' malloc', simplemente reemplaza un símbolo por otro símbolo. 'ld' es la mejor herramienta para manipular binarios que conozco, portátil, flexible, todo lo que pediste. Pero parece que tienes ciertos tipos de respuestas en tu cabeza que no se reflejan necesariamente en tu pregunta. –

+0

Si quiere decir que hay una forma de tomar un archivo ELF ejecutable existente y agregarle código para definir algunos símbolos que de otro modo se resolverían con código de biblioteca compartida, usando solo GNU 'ld', me gustaría saber cómo. Pero tenga en cuenta que los programas de entrada a los que se debe aplicar son archivos ejecutables ELF, no archivos .o' o fuentes. –

1

Parece que no puedo agregar comentarios a esta pregunta, por lo tanto publicarla como una "respuesta". Lo siento, hacer eso solo para ayudar a otras personas que buscan una respuesta.

Por lo tanto, me parece que tienen usecase similares, pero de forma explícita encontrar ninguna modificación a los binarios existentes inaceptables (para mí), así que estoy buscando planteamiento por aproximación independiente: Proxy shared library (sharedlib, shlib, so) for ELF?

Cuestiones relacionadas