Как обмануть библиотеку * .so, используя недостающую функцию @ GLIBC_2.6? - PullRequest
1 голос
/ 03 ноября 2011

Мне нужно запустить относительно новый пакет на не очень новом RHEL 5.6.

У меня есть сторонняя библиотека (lib3rdparty.so), которая скомпилирована с glibc 2.6, а в RHEL 5.6 установлено только 2.5. Но в библиотеке есть только пара ссылок на sched_getcpu@@GLIBC_2.6. Я проверил это так

readelf -s lib3rdparty.so | egrep "@GLIBC_2.[6-9]"

чтобы найти ссылки на что-то более новое, чем GLIBC_2.5, которое установлено. Выход

0 FUNC    GLOBAL DEFAULT  UND sched_getcpu@GLIBC_2.6 (62)
0 FUNC    GLOBAL DEFAULT  UND sched_getcpu@@GLIBC_2.6

Итак, у меня есть только одна функция из GLIBC_2.6. Теперь я хочу заставить библиотеку думать, что у меня есть эта функция. Для этого я подделал небольшую библиотеку (libcheat.so), как упомянуто здесь . Теперь у меня есть файл libcheat.so, который при запуске через readelf покажет эту строку:

10 FUNC    GLOBAL DEFAULT   11 sched_getcpu@@GLIBC_2.6

С этой библиотекой мне удалось успешно создать исполняемый файл, который динамически связан с lib3rdparty.so. Без этой библиотеки я не могу ничего построить, потому что ld не может найти ссылку на sched_getcpu.

Но проблема с запуском этого файла: при попытке запустить файл появляется следующая ошибка:

 ./hello_world: version `GLIBC_2.6' not found (required by ./lib3rdparty.so)

Итак, я считаю, что есть один последний шаг, чтобы заставить его работать, но я не знаю, что делать. Я пытался использовать /etc/ld.conf.preload и экспортировать LD_LIBRARY_PATH, чтобы он указывал на мою библиотеку для загрузки раньше других. Но это не будет работать. Пытался запустить его через strace, но не получил значимого вывода.

Есть идеи?

Ответы [ 2 ]

0 голосов
/ 20 марта 2012

Хорошо, я полагаю, что должен упомянуть "последний шаг", который в моем случае включал исправление двоичных сторонних библиотек.

  1. Используя objdump, я нашел адрес, где lib3rdparty.so ищет GLIBC_2.6
  2. Используя hexedit, я заменил этот адрес на тот, куда GLIBC_2.5 был экспортирован (вы должны искать байты в обратном порядке).Также я заменил символ на 2.5.
  3. Используя objdump Я проверил, что все ссылки теперь используют GLIBC_2.5
  4. Мне нужно было перестроить libcheat.so, так как sched_getcpu теперь ссылался GLIBC_2.5, поэтому я использовал sched_getcpu@@GLIBC_2.5 в качестве встроенного ассемблера

После этого я поставил libcheat.so возле lib3rdparty.so, установил LD_LIBRARY_PATH в . и мой двоичный файл начал работать.Я не уверен, что все это будет работать правильно, но если вы натолкнулись на проблему такого рода, этот вопрос и ответ могут помочь.

0 голосов
/ 03 ноября 2011

Я не уверен, что выбранный вами обходной путь - лучший путь.Почему бы не предоставить новый glibc для приложения?Вы можете попытаться передать его, используя переменную окружения LD_PRELOAD.Для лучшей двоичной совместимости вы можете получить двоичный файл glibc из более новой версии дистрибутива или пересобрать более новую версию glibc для RHEL 5.6.

Также попробуйте поиграться с переменной окружения LD_DEBUG, чтобы увидеть, что такое динамическийкомпоновщик делает.

...