Обман Linux: исполняемые файлы и зависимые библиотеки через LD_PRELOAD

#c #c #linux #bash

#c #c #linux #bash

Вопрос:

Извините за название, не мог придумать ничего другого, чтобы описать проблему 🙂

Хорошо, итак, дело в следующем: я пытаюсь использовать проприетарное бесплатное приложение под Linux (и, следовательно, проблема; если бы у меня был исходный код, я мог бы его перестроить). Кроме того, я пытаюсь запустить его на неподдерживаемой версии Linux, и почти все компоненты приложения работают по отдельности, но не вместе (как они должны, если приложение запущено полностью).

Позвольте мне немного прояснить. Существует графический интерфейс, который отлично запускается в неподдерживаемой ОС. Затем из этого графического интерфейса вы можете вызвать множество инструментов командной строки — услужливо, графический интерфейс также выдает командную строку, вызываемую в каждом случае.

Теперь, вызываемые из графического интерфейса пользователя, некоторые из этих команд завершаются с ошибкой — однако, поскольку у меня вызвана фактическая командная строка (скажем: « extprogram -arg1 1 -arg2 2 ... «), я могу повторить их из терминала. Итак, я обнаружил, что приложение в целом содержит собственные библиотеки libc; и при использовании этих библиотек (некоторые из) команд (выполняемых с терминала) имеют тенденцию завершаться сбоем — однако я обнаружил, что из командной строки это обычно работает для тех, которые терпят неудачу:

 LD_PRELOAD=/usr/lib/libstdc  .so.6 extprogram -arg1 1 -arg2 2 ...

# or alternatively, this works too:
# LD_LIBRARY_PATH=/usr/lib extprogram -arg1 1 -arg2 2 ...
  

(другими словами, использование системного libstdc вместо поставляемого приложением, как правило, исправляет ситуацию)

 

Итак, теперь, если бы я мог убедить графический интерфейс вызывать эти инструменты с помощью « LD_PRELOAD «/» LD_LIBRARY_PATH » — я думаю, все будет работать нормально…

К сожалению, графический интерфейс не вызывает скрипт, который в дальнейшем вызывал бы эти исполняемые файлы, которые я мог бы изменить напрямую (насколько я мог видеть через grep ping) — по-видимому, это исполняемый файл GUI, который создает системные вызовы; Я пробовал « strace -ing, но я не могу найти что-то вроде временного скриптаили что-нибудь, что я мог бы изменить…

 

Итак, я подумал, может быть, я мог бы «обмануть», создав исполняемый скрипт bash; поэтому я перемещаю исполняемый файл и создаю скрипт, который должен вызывать перемещенный исполняемый файл с LD_ добавлением:

 mv extprogram extprogram.old
cat > extprogram <<EOF
LD_LIBRARY_PATH=/usr/lib extprogram $@
EOF
  

… но это не удается; по-видимому, приложение с графическим интерфейсом распознает, что что-то не так.

 

Итак, я подумал — возможно ли каким-то образом, возможно, иметь «оболочку» кода C / C , которая каким-то образом «загружала» этот исполняемый файл, но в «среде», которая имеет LD_LIBRARY_PATH=/usr/lib » set — и передает ему свои аргументы (а также возвращает возвращаемое значение)? Тогда я мог бы создать эту «оболочку» изначально в ОС с тем же именем, что и исходный исполняемый файл, и все это работало, не касаясь исходного исполняемого файла (кроме переименования).

Заранее большое спасибо за любые ответы,
приветствия!

Комментарии:

1. Запускается ли это приложение с графическим интерфейсом из какого-то скрипта-оболочки, который в первую очередь изменяет LD_LIBRARY_PATH?

2. Спасибо за комментарий, @bdonlan — я так думаю (на самом деле существует несколько графических интерфейсов, некоторые не запускаются через скрипт-оболочку — этот, который вызвал проблему). Я также попытался изменить материал в скрипте-оболочке (я должен был упомянуть об этом) без особого эффекта. Приветствия!

3. Если бы этот скрипт вызывался дважды, разве он не перезаписывался extprogram.old бы, чтобы оба extprogram и extprogram.old были модифицированными версиями, созданными сценарием?

Ответ №1:

Вы близки. Вы забыли о том, как сделать скрипт исполняемым. Также вы вызывали неправильную внешнюю программу. Наконец, я бы использовал абсолютный путь к старому скрипту, потому что вы не знаете, каким будет CWD для графического интерфейса.

 mv extprogram extprogram.old
cat > extprogram <<EOF
#!/bin/sh
LD_LIBRARY_PATH=/usr/lib exec /psth/to/extprogram.old "$@"
EOF
chmod  x extprogram
  

Комментарии:

1. ВООООТ!! Это работает !!! 🙂 Большое, большое спасибо за это @Chris ( примечание для себя: проклятые шебанги и все такое 🙂 )! Просто примечание, фактический сценарий, который, наконец, сработал для меня: » #!/bin/sh ; MYDIR=$(readlink -f "$(dirname "$0")") ; LD_LIBRARY_PATH=/usr/lib:$LD_LIBRARY_PATH $MYDIR/ext_program $@ ; » … Еще раз большое спасибо — ура!

2. Я исправил этот код для использования "$@" вместо $@ . (Последний сломается, если какой-либо из аргументов содержит пробелы.) Я также добавил «exec», чтобы процесс оболочки был заменен фактическим исполняемым файлом, который сохраняет статус выхода среди других приятных вещей.

Ответ №2:

использование системного libstdc вместо поставляемого приложением, как правило, исправляет ситуацию

Мне было бы любопытно узнать, какие проблемы возникают при использовании приложений, предоставляемых libstdc .so.6 приложением, но если система исправляет ситуацию, то гораздо более простым решением является удаление (переименование) проблемной библиотеки, а не выполнение всего решения оболочки-оболочки.

Если приложение не может найти «плохую» библиотеку, есть большая вероятность, что оно найдет системную.

Комментарии:

1. Спасибо за это, @Employed Russian — это вызвало проблемы такого рода: version 'GLIBCXX_3.4.11' not found (required by ... (а затем третий .so) — Я думаю, что я даже пытался переименовать библиотеку приложений — но тогда другие инструменты, которые ранее работали, начали бы отказывать в этот момент 🙂 Тем не менее, пока все хорошо — оболочка оболочки, похоже, работает для меня… Приветствия!