56 votes

la construction d'une .c'est donc aussi un exécutable

Donc, tout le monde le sait probablement que glibc /lib/libc.so.6 peut être exécutée dans le shell comme un exécutable normal dans quels cas il imprime ses informations de version et quitte. Cela se fait via la définition d'un point d'entrée dans l' .donc. Pour certains cas, il pourrait être intéressant de l'utiliser pour d'autres projets. Malheureusement, le faible niveau des points d'entrée que vous pouvez définir par ld de l'option-e est un peu trop bas niveau: le chargeur dynamique n'est pas disponible si vous ne pouvez pas appeler une des fonctions de la bibliothèque. la glibc pour cette raison implémente la fonction write() de l'appel système par l'intermédiaire d'un nu de l'appel système dans ce point d'entrée.

Ma question est maintenant, comment peut-on penser d'une belle manière comment on peut démarrer une dynamique complète de l'éditeur de liens à partir de ce point d'entrée de sorte que l'on pouvait accéder à des fonctions à partir d'autres .c'est donc?

56voto

Employed Russian Points 50479

La construction de votre bibliothèque partagée avec -pie option s'affiche pour vous donner tout ce que vous voulez:

/* 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. S. glibc implémente write(3) via le système d'appel car il n'a pas d'autre endroit où l'appel (c'est le plus bas niveau déjà). Cela n'a rien à voir avec être en mesure d'exécuter libc.so.6.

1voto

Yawar Points 2393

Pas une belle façon, mais je voudrais créer un petit exécutable du wrapper autour de la .afin que les appels à la fonction de point d'entrée je veux courir.

1voto

Jim Dennis Points 5454

Je suppose que vous auriez votre ld -e point à un point d'entrée qui serait ensuite utiliser l' dlopen() famille de fonctions de trouver et d'amorcer le reste de l'éditeur de liens dynamique. Bien sûr, vous devez vous assurer que dlopen() lui-même était lié statiquement ou vous pourriez avoir à mettre en œuvre assez de votre propre éditeur de liens de stub pour obtenir (à l'aide de l'appel système des interfaces telles que mmap() tout comme la libc lui-même est en train de faire.

Rien de tout cela sonne "gentil" de moi. En fait, juste la pensée de la lecture de la glibc sources (et l' ld-linux code source, par exemple), il faut évaluer l'ampleur de la tâche semble assez cendrée pour moi. Il pourrait également être une portabilité cauchemar. Il peut y avoir de grandes différences entre la façon dont Linux implémente ld-linux et comment les liens sont fait sous OpenSolaris, FreeBSD, et ainsi de suite. (Je ne sais pas).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X