Что такое формат файла SO?
Файл .so содержит динамически загружаемую разделяемую библиотеку для приложений Unix и Linux. .so - это бинарный файл, используемый для предоставления доступа к общему коду и данным, которые одна или несколько программ могут использовать при запуске. Расширение расшифровывается как Shared Object (общий объект), что отражает тот факт, что после загрузки библиотеки в память её объекты - функции и данные - могут быть доступны нескольким процессам одновременно. Для файлов .so зарегистрирован MIME-тип application/x-sharedlib.
Библиотеки .so являются объектами ELF (сокращение от Executable and Linkable Format) - это стандартный бинарный формат, используемый в Linux и многих Unix-подобных системах для исполняемых файлов, скомпилированных объектов, разделяемых библиотек и дампов памяти (core dumps). Каждый корректный ELF-файл, включая файлы .so, начинается с четырехбайтового магического числа \x7FELF по смещению 0. Структура файла включает:
- Заголовок ELF - определяет архитектуру, порядок байтов (endianness) и разрядность (32-бит или 64-бит), а также количество записей в таблицах сегментов и разделов;
- Таблица заголовков программы - описывает сегменты памяти, используемые во время загрузки;
- Таблица заголовков разделов - описывает отдельные разделы, используемые компоновщиком и отладчиком;
- Данные, на которые ссылаются эти заголовки.
Сегменты используются во время выполнения программы и могут состоять из нескольких разделов; разделы используются во время операции компоновки. Файлы .so могут быть скомпонованы с программой на этапе компиляции или загружены во время выполнения через dlopen().
Имена файлов .so следуют соглашению, согласно которому имени библиотеки предшествует префикс lib - например, библиотека с именем abc будет иметь имя файла libabc.so, а при компоновке с ней используется флаг -labc. За суффиксом .so может следовать номер версии, например libabc.so.3 для файла основной версии или libabc.so.3.1.2 для сборки с полной версией. На практике libabc.so часто является лишь символической ссылкой, указывающей на реальный файл с версией, а libabc.so.3 сам может быть симлинком на последний совместимый выпуск. Версия, хранящаяся в динамической записи DT_SONAME, - это то, что записывает и проверяет динамический компоновщик ld.so. Некоторые низкоуровневые системные библиотеки, такие как сам ld.so, не следуют соглашению о префиксе lib.
В Windows эквивалентной концепцией является файл .DLL; в macOS - файл .dylib. Статические альтернативы в Linux архивируются в файлы .a.
Безопасность и защита
РИСК: MEDIUMФайл .so - это исполняемый нативный код, который запускается внутри любого загрузившего его процесса, поэтому вредоносная библиотека может делать всё то же самое, что и основная программа. Реальные риски: (1) подмена библиотеки - вредоносный .so, помещенный там, где загрузчик ищет в первую очередь, или злоупотребление LD_PRELOAD/LD_LIBRARY_PATH может внедрить код в легитимную программу; (2) скачивание отдельных файлов .so с сомнительных сайтов для исправления ошибок - они могут быть вредоносными или несовместимыми по ABI, что может сломать или скомпрометировать систему. Всегда устанавливайте библиотеки из подписанных репозиториев вашего дистрибутива. Удаление системных файлов .so (в /lib, /usr/lib) может сделать ОС или приложения неработоспособными.
Детали формата
в двух словахПрограммы, открывающие файлы SO
Технические подробности
глубокая спецификация| MIME-тип | application/x-sharedlib |
| Магические байты | 7F 45 4C 46 («\x7FELF») по смещению 0 - идентичная метка для всех ELF-файлов; поле e_type отличает общие объекты |
| Значение ELF e_type | ET_DYN (0x0003) - отличает общий объект от исполняемого файла (ET_EXEC = 0x0002) или перемещаемого объекта (ET_REL = 0x0001) |
| Разрядность | Байт EI_CLASS по смещению 4: 1 = 32-бит (Elf32), 2 = 64-бит (Elf64); оба варианта широко распространены в Linux |
| Порядок байтов | Байт EI_DATA по смещению 5: 1 = little-endian (ELFDATA2LSB), 2 = big-endian (ELFDATA2MSB); зависит от архитектуры |
| Позиционно-независимый код | Должен быть скомпилирован с флагом -fPIC, чтобы библиотека могла быть отображена на любой виртуальный адрес без конфликтов перемещения между процессами |
| Таблица динамических символов | Раздел .dynsym экспортирует и импортирует символы, видимые во время выполнения; .dynstr хранит соответствующие строки имен |
| PLT / GOT | Procedure Linkage Table и Global Offset Table обеспечивают ленивое (по умолчанию) или немедленное (-z now) разрешение символов при загрузке |
| soname (DT_SONAME) | Каноническое имя библиотеки, встроенное в динамический раздел ELF; ld.so записывает это имя при компоновке программы, что позволяет отслеживать версию ABI независимо от имени файла |
| Версионность символов | Разделы .gnu.version и .gnu.version_r позволяют использовать несколько версий символов в одном файле, обеспечивая обратно совместимую эволюцию ABI |
| Динамический компоновщик | Загружается через ld.so / ld-linux-x86-64.so.2; путь поиска управляется LD_LIBRARY_PATH, DT_RUNPATH или /etc/ld.so.conf + кэш ldconfig |
| Соглашение об именовании | lib<имя>.so[.мажор[.минор.патч]]; libabc.so обычно является симлинком для разработки → libabc.so.3 → libabc.so.3.1.2 |
| Встроенный путь поиска | Динамические записи DT_RPATH или DT_RUNPATH вшивают пути поиска библиотек в файл во время компоновки; DT_RUNPATH предпочтительнее, так как его можно переопределить через LD_LIBRARY_PATH |
| Инструменты проверки | readelf -a, objdump -d, nm --dynamic (binutils); ldd для вывода списка зависимостей; команда file определяет тип ELF и архитектуру |
| Выпущен | ELF format 1990s (System V Release 4); .so shared libraries are core to Linux/Unix |
| Открыть стандартное | Да · без роялти |
| Спецификация | refspecs.linuxfoundation.org |
Конвертации SO
Вопросы и ответы сообщества
спрошено пользователямиВопросов пока нет - станьте первым, кто спросит о файлах SO.