Исполняемые файлы против общих объектов
Я заметил что-то, делая 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.