edificio a.so eso también es un ejecutable


Así que probablemente todo el mundo sabe que el /lib/libc.so.6 de glibc se puede ejecutar en el shell como un ejecutable normal en cuyo caso imprime su información de versión y sale. Esto se hace a través de la definición de un punto de entrada en el .so. Para algunos casos podría ser interesante utilizar esto para otros proyectos también. Desafortunadamente, el punto de entrada de bajo nivel que puede establecer mediante la opción-e de ld es un poco demasiado bajo: el cargador dinámico no está disponible, por lo que no puede llamar a ninguna función de biblioteca adecuada. glibc por esta razón implementa la llamada al sistema write () a través de una llamada al sistema naked en este punto de entrada.

Mi pregunta ahora es, ¿puede alguien pensar en una buena manera de cómo uno podría arrancar un enlazador dinámico completo desde ese punto de entrada para que uno pueda acceder a funciones desde otro.]}

Author: Martin v. Löwis, 2009-09-20

3 answers

La opción Construir tu biblioteca compartida con -pie parece darte todo lo que quieres:

/* pie.c */
#include <stdio.h>
int foo()
{
  printf("in %s %s:%d\n", __func__, __FILE__, __LINE__);
  return 42; 
}
int main() 
{ 
  printf("in %s %s:%d\n", __func__, __FILE__, __LINE__);
  return foo(); 
}


/* main.c */
#include <stdio.h>

extern int foo(void);
int main() 
{ 
  printf("in %s %s:%d\n", __func__, __FILE__, __LINE__);
  return foo(); 
}


$ gcc -fPIC -pie -o pie.so pie.c -Wl,-E
$ gcc main.c ./pie.so


$ ./pie.so
in main pie.c:9
in foo pie.c:4
$ ./a.out
in main main.c:6
in foo pie.c:4
$

P.D. glibc implementa write(3) a través de la llamada al sistema porque no tiene ningún otro lugar para llamar (ya es el nivel más bajo). Esto no tiene nada que ver con ser capaz de ejecutar libc.so.6.

 44
Author: Employed Russian,
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
2009-09-20 17:13:56

No es una buena manera, pero crearía un pequeño ejecutable wrapper alrededor del .para que llame a la función de punto de entrada que quiero ejecutar.

 1
Author: Yawar,
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
2009-09-20 01:13:37

Supongo que tendría su ld -e punto a un punto de entrada que luego utilizaría la familia de funciones dlopen() para encontrar y arrancar el resto del enlazador dinámico. Por supuesto, tendría que asegurarse de que dlopen() en sí mismo esté enlazado estáticamente o podría tener que implementar suficiente de su propio stub de enlazador para llegar a él (utilizando interfaces de llamadas al sistema como mmap() tal como lo está haciendo libc en sí.

Nada de eso suena "agradable" para mí. De hecho, solo la idea de leer las fuentes glibc (y el código fuente ld-linux, como un ejemplo) suficiente para evaluar el tamaño del trabajo me suena bastante agotador. También podría ser una pesadilla de portabilidad. Puede haber grandes diferencias entre cómo Linux implementa ld-linux y cómo se hacen los enlaces bajo OpenSolaris, FreeBSD, etc. (No lo sé).

 0
Author: Jim Dennis,
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
2009-09-20 03:26:38