Вставить статически связанные двоичные файлы

Существует хорошо известная техника для вставки динамически связанных двоичных файлов: создание разделяемой библиотеки и использование переменной LD_PRELOAD. Но это не работает для статически связанных двоичных файлов.

Одним из способов является написание статической библиотеки, которая вставляет функции и связывает ее с приложением во время компиляции. Но это не практично, потому что перекомпиляция не всегда возможна (подумайте о сторонних двоичных файлах, библиотеках и т. Д.).

Поэтому мне интересно, есть ли способ вставить статически связанные двоичные файлы в один и тот же LD_PRELOAD, работающий для динамически связанных двоичных файлов, т.е. без изменений кода или повторной компиляции существующих двоичных файлов.

Я заинтересован только в ELF на Linux. Так что не проблема, если потенциальное решение не является "портативным".

3 ответа

Одним из способов является написание статической библиотеки, которая вставляет функции и связывает ее с приложением во время компиляции.

Одна из сложностей такого промежуточного устройства заключается в том, что он не может легко вызвать исходную функцию (так как она имеет то же имя).

Компоновщик --wrap=<symbol> Вариант может помочь здесь.

Но это не практично, потому что перекомпиляция

Перекомпиляция здесь не нужна, только перекомпоновка.

не всегда возможно (подумайте о сторонних двоичных файлах, библиотеках и т. д.).

Сторонние библиотеки работают нормально (перекомпоновка), но двоичные файлы сложнее.

Это все еще возможно сделать с использованием техники смещенного выполнения, но реализация довольно сложна, чтобы получить право.

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

Это невозможно (РЕДАКТИРОВАТЬ: по крайней мере, без большой работы - см. Комментарии к этому ответу) по двум причинам:

  • по умолчанию символы, определенные в исполняемом файле, не экспортируются, поэтому недоступны для динамического компоновщика (вы можете изменить это с помощью -export-dynamic или экспортировать списки, но это имеет неприятные побочные эффекты производительности или обслуживания)
  • даже если вы экспортируете необходимые символы, ELF требует, чтобы динамический symtab исполняемого файла всегда сначала просматривался во время разрешения символов (см. раздел 1.5.4 "Область поиска" в dsohowto); Симтаб из LD_PRELOADбиблиотека всегда будет следовать за исполняемым файлом и, следовательно, не сможет перехватить символы

То, что вы ищете, называется бинарным инструментарием (например, с использованием Dyninst или ptrace). Идея состоит в том, что вы пишете программу-мутатор, которая присоединяет (или статически переписывает) вашу исходную программу (называемую mutatee) и вставляет код по вашему выбору в определенные моменты в mutatee. Основная проблема обычно заключается в поиске точек ввода с использованием API, предоставляемого механизмом инструментовки. В вашем случае, так как вы в основном ищете статические символы, это может быть довольно сложным и, вероятно, потребует эвристики, если у мутанта нет лишних динамических символов.

Другие вопросы по тегам