Как читать авторский курс и нормативные материалы
Это учебные материалы, а не заключение о соответствии конкретного продукта. Организационные модели курса отделяйте от терминов стандарта: ППК в опубликованном проекте — машиночитаемый перечень, а живой реестр его версий является практикой сопровождения. Термин OSA в разных материалах имеет разный охват. Статус и обязательность нормативного документа проверяются отдельно; проект КАПО опубликован как проект первой редакции.
ldd readelf objdump
Почему это важно для SCA/OSA
Три классические утилиты бинарного анализа отвечают на разные вопросы, и путать их — значит получать неверный состав. ldd отвечает «что фактически загрузится на этом хосте», readelf — «что записано в самом файле», objdump — «как устроены секции и код». Для инвентаризации это не взаимозаменяемые инструменты, а разные срезы: один показывает рантайм с учётом окружения, другой — статичную запись, третий — детали уровня дизассемблера.
Выбор инструмента влияет и на достоверность, и на безопасность. Опираться на ldd там, где нужен readelf, опасно: ldd зависит от текущих LD_LIBRARY_PATH/RPATH и — что важнее — фактически задействует динамический загрузчик целевого бинаря. На чужом, недоверенном артефакте это уже не пассивное чтение.
Как это проявляется
Один и тот же бинарь, три инструмента, три разных ответа:
# ldd — резолвинг на ЭТОМ хосте: имя -> фактический файл (зависит от окружения)
$ ldd ./app
libssl.so.3 => /usr/lib/x86_64-linux-gnu/libssl.so.3 (0x00007f...)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f...)
# readelf — что записано в файле, без запуска и без окружения
$ readelf -d ./app | grep NEEDED
0x0...0001 (NEEDED) Shared library: [libssl.so.3]
# objdump — секции/заголовки; полезно для формата, опций сборки, отладочной инфы
$ objdump -p ./app | grep -E 'NEEDED|RUNPATH'
NEEDED libssl.so.3
RUNPATH $ORIGIN/../lib
ldd дал путь (но он верен только для этого хоста и окружения), readelf дал имя без пути (зато детерминированно и для любой архитектуры), objdump -p показал и имена, и пути поиска. Для воспроизводимой инвентаризации источник истины — readelf/objdump, а ldd — уточнение «куда оно реально резолвится здесь».
lddзапускает загрузчик бинаряlddработает, по сути, вызывая динамический загрузчик целевого файла, чтобы тот разрешил зависимости. На недоверенном бинаре это нежелательно (и исторически приводило к выполнению кода). Для инвентаризации недоверенных артефактов используйтеreadelf -d/objdump -p— они только читают файл.lddоставляйте для своих сборок, когда нужен фактический путь.
Слепая зона или приём
Общая слепая зона всех трёх — они видят только то, что попало в ELF динамически или в символы. Статически вшитый код (.a) ни ldd, ни readelf -d, ни objdump -p не покажут как зависимость — это зона статической линковки. А ldd вдобавок зависит от хоста: на машине с другим RPATH/LD_LIBRARY_PATH он выдаст другие пути, чем целевая среда.
Приём — комбинировать по роли: readelf -d как детерминированный список (DT_NEEDED, структура разобрана в ELF и разделы dynamic), objdump для деталей формата и опций сборки, ldd — только чтобы подтвердить фактический путь на доверенном хосте. Для одиночного бинаря этого набора достаточно; для пачки артефактов ручные утилиты неудобны — там нужен программный парсер (см. LIEF как программный анализ ELF).
Что делать на проекте
- Источником списка динамических зависимостей делать
readelf -d ... | grep NEEDED, а неldd— детерминированно и без исполнения. lddприменять только к своим, доверенным сборкам и только чтобы уточнить фактический путь резолвинга.- Перед анализом проверять формат:
file ./app— ELF ли это и та ли архитектура; иначе вывод утилит обманчив. objdump -pиспользовать, чтобы за один вызов увидеть иNEEDED, иRPATH/RUNPATH;objdump -h/readelf -S— чтобы понять, stripped ли бинарь (см. stripped binaries).- Помнить, что
lddна аудиторском хосте может дать пути, отличные от целевой среды, — версии подтверждать через пакетный менеджер, а не через путьldd. - Для массового разбора (десятки бинарей) переходить с ручных команд на скрипт поверх ELF-парсера.
Связь
- Модуль: М09. C/C++ legacy
- Практики: П22. ELF dynamic dependencies
- Нормативка: CISA Minimum Elements for SBOM · ГОСТ Р 56939-2024 · BSI TR-03183-2 v2.1.0
- Смежные заметки 06: ELF и разделы dynamic · динамическая линковка · LIEF как программный анализ ELF · stripped binaries · unresolved libraries