Могу ли я добавить поддержку библиотеки существующего общего объекта?
У меня есть система "fsimage.so", для которой требуется mkdirp, который просто живет в libgen.so. Но fsimage.so этого не знает. Например:
# ldd /usr/lib/python2.4/vendor-packages/fsimage.so
libfsimage.so.1.0 => /usr/lib/libfsimage.so.1.0
libxml2.so.2 => /lib/libxml2.so.2
libgcc_s.so.1 => /usr/sfw/lib/libgcc_s.so.1
libpthread.so.1 => /lib/libpthread.so.1
libz.so.1 => /lib/libz.so.1
libm.so.2 => /lib/libm.so.2
libsocket.so.1 => /lib/libsocket.so.1
libnsl.so.1 => /lib/libnsl.so.1
libc.so.1 => /lib/libc.so.1
libmp.so.2 => /lib/libmp.so.2
libmd.so.1 => /lib/libmd.so.1
# ./test
Traceback (most recent call last):
File "./test", line 26, in ?
import fsimage
ImportError: ld.so.1: isapython2.4: fatal: relocation error: file /usr/lib/python2.4/vendor-packages/fsimage.so: symbol mkdirp: referenced symbol not found
# LD_PRELOAD=/usr/lib/libgen.so ./test
Usage: ./test
Естественно, если бы у меня были источники и т.д., я мог бы просто связать его снова и добавить "-lgen", и он добавит libgen.so как зависимость.
Но как упражнение в хакерстве, скажем, у меня нет источников, и просто хотел добавить, что fsimage.so также нужно загрузить libgen.so. Использование elfedit/objcopy и т.д., Это невозможно? Я не думаю, что я могу использовать "ld" для использования. Также как ввод и написать новую .so с дополнительной библиотекой?
# elfdump /usr/lib/python2.4/vendor-packages/fsimage.so|grep NEEDED
[0] NEEDED 0x5187 libfsimage.so.1.0
[1] NEEDED 0x5152 libxml2.so.2
[2] NEEDED 0x5171 libgcc_s.so.1
Первая попытка, легко на меня:)
Ответы
Ответ 1
Спасибо, "Занятый русский", вы дали мне информацию, необходимую для поиска глубже. Solaris уже поставляется с "elfedit", поэтому, если другие хотят знать, это инструкции
# elfedit libfsimage.so.1.0.0 libfsimage.so.1.0.0-new
> dyn:value DT_NEEDED
index tag value
[0] NEEDED 0x4f81 libpthread.so.1
[1] NEEDED 0x4fac libxml2.so.2
[2] NEEDED 0x4fc2 libgcc_s.so.1
> dyn:value -add -s DT_NEEDED libscf.so
index tag value
[35] NEEDED 0x500d libscf.so
> dyn:value DT_NEEDED
index tag value
[0] NEEDED 0x4f81 libpthread.so.1
[1] NEEDED 0x4fac libxml2.so.2
[2] NEEDED 0x4fc2 libgcc_s.so.1
[35] NEEDED 0x500d libscf.so
> :write
> :quit
# ldd libfsimage.so.1.0.0-new
libpthread.so.1 => /lib/libpthread.so.1
libxml2.so.2 => /lib/libxml2.so.2
libgcc_s.so.1 => /usr/sfw/lib/libgcc_s.so.1
libscf.so => /lib/libscf.so
libz.so.1 => /lib/libz.so.1
libm.so.2 => /lib/libm.so.2
libsocket.so.1 => /lib/libsocket.so.1
libnsl.so.1 => /lib/libnsl.so.1
libc.so.1 => /lib/libc.so.1
libuutil.so.1 => /lib/libuutil.so.1
libgen.so.1 => /lib/libgen.so.1
libnvpair.so.1 => /lib/libnvpair.so.1
libsmbios.so.1 => /usr/lib/libsmbios.so.1
libmp.so.2 => /lib/libmp.so.2
libmd.so.1 => /lib/libmd.so.1
Ответ 2
Не легко.
Большинство систем UNIX
(AIX
является заметным исключением) рассматривают *.so
"конечный" продукт ссылки и не подходят в качестве ввода для любой дополнительной ссылки.
Чтобы добавить новый тег DT_NEEDED в динамический раздел fsimage.so
, вам нужно будет переписать его раздел .dynamic
. Удаление записи из .dynamic
относительно просто - вы можете просто "сдвинуть" другие записи вверх и заменить последнюю запись на DT_NULL
.
С другой стороны, добавление новой записи требует добавления в файл целого нового раздела .dynamic
, а затем обновление всех указателей (смещений) в fsimage.so
, чтобы указать на новый раздел. Это требует "глубокого" понимания формата ELF.
Существуют существующие инструменты для этого, например. rpath
, но у меня был смешанный успех.
Ответ 3
Вы можете использовать PatchELF. Выпуск 0.9 выходит с 29 февраля 2016 года и позволяет вам:
- Измените динамический загрузчик ( "ELF-интерпретатор" ) исполняемых файлов
- Измените RPATH исполняемых файлов и библиотек
- Сократить RPATH исполняемых файлов и библиотек
- Удалить объявленные зависимости от динамических библиотек (DT_NEEDED
записей)
- Добавить объявленную зависимость от динамической библиотеки (DT_NEEDED)
- Заменить заявленную зависимость от динамической библиотеки с другой (DT_NEEDED)
- Изменить SONAME динамической библиотеки
В вашем случае:
$ patchelf --add-needed /usr/lib/libgen.so /usr/lib/python2.4/vendor-packages/fsimage.so