web-dev-qa-db-fra.com

Exécutables vs objets partagés

J'ai remarqué quelque chose en faisant find /bin -exec file {} \;:

la commande file signale que certaines entrées dans /bin sont shared objects, tandis que d'autres sont appelées executables. Par exemple,

/ bin/ntfsck:
ELF 64 bits LSB objet partagé, x86-64, version 1 (SYSV),
lié dynamiquement (utilise des bibliothèques partagées), pour GNU/Linux 2.6.24, BuildID [sha1] = 312d93fd0d8653e7236a61db2e67b93c63225a00, dépouillé

Même rapport pour gawk

/ usr/bin/gawk:
ELF 64 bits LSB objet partagé, x86-64, version 1 (SYSV),
lié dynamiquement (utilise des bibliothèques partagées), pour GNU/Linux 2.6.24,
BuildID [sha1] = 76bb13aac7e212164bd6e0d7b8a5d92db44543c9, dépouillé

En revanche, file pour /bin/echo est:

/ bin/echo:
ELF 64 bits LSB exécutable, x86-64, version 1 (SYSV),
lié dynamiquement (utilise des bibliothèques partagées), pour GNU/Linux 2.6.24,
BuildID [sha1] = 193e75fc13e9c4599e772b8d79125a5934cf601c, démonté

Essentiellement, je veux savoir quelle est la différence entre les fichiers executable et shared object.

13

Tl; dr

Il n'y a pas de différence, mis à part le fait qu'un exécutable compilé peut être lié à un objet partagé mais pas à un exécutable.


En général, il y a deux façons de compiler1 un exécutable:

  • Utilisation de la liaison statique: les bibliothèques externes incluses dans le code source sont compilées et la bibliothèque compilée (ou l’objet dans la perspective du lieur) est ajoutée à l’exécutable lui-même;
  • Utilisation de la liaison dynamique: les bibliothèques externes incluses dans le code source sont compilées mais n lien vers la bibliothèque compilée (ou l'objet dans la perspective de l'éditeur de liens) est ajouté à l'exécutable (et les bibliothèques/objets compilés sont chargés par le lieur au moment de l'exécution si nécessaire);

L'utilisation de chacune de ces méthodes présente des avantages/inconvénients, mais ce n'est pas le but de la question;

  • /bin/ntfsck et /usr/bin/gawk sont des objets partagés: cela signifie qu'un fichier exécutable peut être compilé, puis lié à ceux-ci pour utiliser leurs fonctionnalités.
  • /bin/echo est un exécutable: cela signifie qu'un exécutable peut ne pas être compilé puis lié à celui-ci pour utiliser ses fonctionnalités;

Donc /bin/ntfsck et /usr/bin/gawk sont des bibliothèques techniquement compilées (ou des objets dans la perspective de l'éditeur de liens), mais, comme on pourrait bien l'avoir vu, rien n'empêche qu'un objet partagé soit exécuté en tant qu'exécutable.

Notez également que file indique (pour chacun d’eux):

lié dynamiquement (utilise des bibliothèques partagées)

Cela signifie que chacun d'entre eux est lié de manière dynamique à (et utilise probablement) d'autres objets partagés.


1. "Compiler" dans son acception la plus large, qui inclut le prétraitement, la compilation et la liaison.

13
kos

Une autre différence est que exécutables possède un décalage d’adresse de point d’entrée défini, à savoir 0x08048000 pour i386, 0x00400000 pour x86 et 0x00010000 pour arm.

Un fichier objet partagé peut être une bibliothèque, mais également un exécutable. En tant qu'exécutable, il n'y a pas de décalage. Un exécutable objet partagé, pour ainsi dire, est un exécutable indépendant de la position (PIE) utilisant la randomisation du format d'espace d'adresse (ASLR). Ainsi, en regardant son fichier/proc/pid/maps, vous remarquerez que l'emplacement des segments chargés varie lors de chaque exécution contrairement aux exécutables standard.

Cette fonctionnalité vise à renforcer la sécurité des exécutables en empêchant les attaquants d’attaquer par des attaques par programmation. De nombreux responsables ont décidé de créer des packages avec PIE activé par défaut, par exemple depuis Fedora 23 ou avec Ubuntu 17.10.

4
florian