Как эта программа статически ссылается на.so по пути не по умолчанию
Программу, которую я использую, можно установить только с помощью специального установщика (IDA Freeware Demo). Я установил его в моем домашнем каталоге, все отлично работает.
Теперь я заметил, что при проверке программы с помощью ldd: она поставляется со своими собственными библиотеками Qt, которые помещаются в виде разделяемых библиотек в каталог установки (так что этот же каталог находится в его главном исполняемом файле, а не в /usr/lib или подобном).
$ ldd ida64
linux-vdso.so.1 => (0x00007ffec5fb9000)
libida64.so => /home/asdf/idafree-7.0/./libida64.so
libQt5PrintSupport.so.5 => /home/asdf/idafree-7.0/./libQt5PrintSupport.so.5
libQt5Widgets.so.5 => /home/asdf/idafree-7.0/./libQt5Widgets.so.5
....
(установить dir = /home/asdf/idafree-7.0/)
Теперь я задаюсь вопросом: как это сделать? Я выполняю программу напрямую, без какой-либо магии LD_LIB_PATH.
2 ответа
Это полностью отличается от статического связывания и не связано с ним. Хотя я предполагаю, что сценарий-оболочка может изменить LD_LIBRARY_PATH перед запуском программы, IDA этого не делает.
Когда разделяемая библиотека впервые компонуется из составляющих ее объектных файлов, можно указать путь выполнения, т. е.
--set-rpath
(Краткая форма
-r
) флаг. Это сообщает загрузчику, что нужно искать в указанном каталоге, прежде чем искать в другом месте. Путь может быть жестко запрограммирован или может использовать флаг.
The
$ORIGIN
флаг позволяет загрузчику разрешить текущий путь к исполняемому файлу, что, в свою очередь, позволяет rpath более легко работать из любого каталога. Скорее всего, IDA была просто построена с таким флагом, как
-Wl,-r,$ORIGIN
. Если бы библиотеки Qt находились в подкаталоге, это было бы просто
-Wl,-r,$ORIGIN/qtlibdir
.
Также есть утилиты, которые могут редактировать это поле после линковки, например patchelf.
Всю эту информацию можно найти в руководстве ld. https://man7.org/linux/man-pages/man1/ld.1.html
Простое объяснение, как запустить исполняемый файл, требующий уникального LD_LIBRARY_PATH, например, путь к библиотекам в текущем каталоге /:
Короткий: export LD_LIBRARY_PATH=.
где точка (.) означает "текущий каталог"
Обычно также включается система LD_LIBRARY_PATH: export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
"Жесткое кодирование", например, ida64
: Функция в исполняемом файле, который должен быть запущен первым, устанавливает уникальный LD_LIBRARY_PATH . ... Другой пример: firefox
,