Исполняемые файлы против общих объектов

Я заметил что-то, делая find /bin -exec file {} \;:

file Команда сообщает о некоторых записях в /bin являются shared objects в то время как другие как executables, Например,

/ Бен / ntfsck:
ELF 64-битный общий объект LSB, x86-64, версия 1 (SYSV),
динамически скомпонованный (использует общие библиотеки), для GNU/Linux 2.6.24, BuildID[sha1]=312d93fd0d8653e7236a61db2e67b93c63225a00, раздетый

Тот же отчет для gawk

/ USR / бен / простак:
ELF 64-битный общий объект LSB, x86-64, версия 1 (SYSV),
динамически связанные (использует разделяемые библиотеки), для GNU / Linux 2.6.24,
BuildID [sha1] = 76bb13aac7e212164bd6e0d7b8a5d92db44543c9, раздетый

По сравнению file за /bin/echo является:

/ Бен / эхо:
64-битный исполняемый файл ELF для ELF, x86-64, версия 1 (SYSV),
динамически связанные (использует разделяемые библиотеки), для GNU / Linux 2.6.24,
BuildID [sha1] = 193e75fc13e9c4599e772b8d79125a5934cf601c, раздетый

По сути, я хочу знать, в чем разница между executable файлы и shared object файлы.

2 ответа

Решение

Tl; др

Нет никакой разницы, за исключением того факта, что скомпилированный исполняемый файл может быть связан с общим объектом, но не с исполняемым файлом.


В общем, есть два способа скомпилировать1 исполняемый файл:

  • Использование статической компоновки: внешние библиотеки, включенные в исходный код, компилируются, и скомпилированная библиотека (или объект в перспективе компоновщика) добавляется в сам исполняемый файл;
  • Использование динамического связывания: внешние библиотеки, включенные в исходный код, компилируются, но ссылка на скомпилированную библиотеку (или объект в перспективе компоновщика) добавляется в исполняемый файл (и скомпилированные библиотеки / объекты загружаются компоновщиком во время выполнения, если необходимо);

Есть преимущества / недостатки в использовании каждого из этих методов, но не в этом вопрос;

  • /bin/ntfsck а также /usr/bin/gawk являются общими объектами: это означает, что исполняемый файл может быть скомпилирован и затем связан с ними для использования их функциональных возможностей;
  • /bin/echo является исполняемым файлом: это означает, что исполняемый файл не может быть скомпилирован и затем связан с ним для использования его функциональных возможностей;

Так /bin/ntfsck а также /usr/bin/gawk являются технически скомпилированными библиотеками (или объектами в перспективе компоновщика), но, как можно было предвидеть, ничто не препятствует запуску общего объекта в качестве исполняемого файла.

Обратите внимание также на то, что file отчеты (для каждого из них):

динамически связан (использует общие библиотеки)

Это означает, что каждый из них динамически связан (и, вероятно, использует) с другими общими объектами.


1. "Компиляция" подразумевает более широкое признание, которое включает в себя предварительную обработку, компиляцию и компоновку.

Другое отличие состоит в том, что исполняемые файлы имеют определенное смещение адреса точки входа, то есть 0x08048000 для i386, 0x00400000 для x86 и 0x00010000 для охраны.

Общий объектный файл может быть библиотекой, но также и исполняемым файлом. Когда это исполняемый файл, такого смещения нет. Исполняемый объект общего объекта, так сказать, является позиционно-независимым исполняемым файлом (PIE), использующим рандомизацию размещения адресного пространства (ASLR). Таким образом, глядя на файл /proc/pid/maps, вы заметите, что расположение загруженных сегментов меняется в каждом исполнении в отличие от стандартных исполняемых файлов.

Идея, лежащая в основе этой функции, заключается в том, чтобы повысить безопасность исполняемых файлов, препятствуя злоумышленникам выполнять атаки, ориентированные на возврат. Многие сопровождающие решили создавать пакеты с включенным PIE по умолчанию, например, начиная с Fedora 23 или с Ubuntu 17.10.

Другие вопросы по тегам