Библиотека изменения загружает порядок во время выполнения (как LD_PRELOAD, но во время выполнения)

Как я изменяю библиотеку, от которой загружается функция в течение времени выполнения?

Например, скажите, что я хочу заменить стандарт printf функция с чем-то новым, я могу записать свою собственную версию и скомпилировать его в общую библиотеку, затем поместить "LD_PRELOAD =/my/library.so" в среду прежде, чем выполнить мой исполняемый файл.

Но скажем, что вместо этого, я хочу изменить ту связь из самой программы. Конечно, это должно быть возможно... правильно?

Править
И не, следующее не работает (но если можно сказать мне, как ЗАСТАВИТЬ его работать, затем это было бы достаточно).

void* mylib = dlopen("/path/to/library.so",RTLD_NOW);
printf = dlsym(mylib,"printf");
7
задан tylerl 18 June 2010 в 22:07
поделиться

5 ответов

AFAIK, это невозможно. Общее правило таково: если один и тот же символ встречается в двух библиотеках, ld.so отдаст предпочтение той библиотеке, которая была загружена первой. LD_PRELOAD работает, проверяя, что указанные библиотеки загружены до любых неявно загруженных библиотек.

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

4
ответ дан 7 December 2019 в 14:29
поделиться

Вы не можете изменить это. В общем случае *NIX концепция связывания (или скорее отсутствие концепции) символ выбирается из первого объекта, где он встречается. (За исключением странной AIX, которая по умолчанию работает как OS/2.)

Программно вы всегда можете попробовать dlsym(RTLD_DEFAULT) и dlsym(RTLD_NEXT). man dlsym для получения дополнительной информации. Хотя это быстро выходит из-под контроля. Почему редко используется.

0
ответ дан 7 December 2019 в 14:29
поделиться

есть переменная окружения LD_LIBRARY_PATH, в которой компоновщик ищет библиотеки shred, добавьте свой путь в LD_LIBRARY_PATH, надеюсь, это сработает

-1
ответ дан 7 December 2019 в 14:29
поделиться

Следует сказать, что попытка замены функций из библиотеки libc в вашем приложении ведет к неопределенному поведению согласно ISO C / POSIX, независимо от того, делаете ли вы это статически или динамически. Он может работать (и в основном будет работать в GNU / Linux), но неразумно полагаться на его работу. Если вы просто хотите использовать имя «printf», но сделать что-то нестандартное в вашей программе, лучший способ сделать это - #undef printf и #define printf my_printf ПОСЛЕ включая любые системные заголовки. Таким образом, вы не мешаете внутреннему использованию функции библиотеками, которые вы используете ... и ваша реализация my_printf может даже вызывать системный printf, если / когда это необходимо.

С другой стороны, если ваша цель - помешать работе библиотек, где-то в будущем вы, вероятно, столкнетесь с проблемами совместимости. Лучшим подходом, вероятно, было бы выяснить, почему библиотека не будет делать то, что вы хотите, без переопределения функций, которые она использует, исправления ее и отправки исправлений вверх по течению, если они уместны.

1
ответ дан 7 December 2019 в 14:29
поделиться

Сохраните результат dlsym () в таблице поиска (массив, хеш-таблица и т. Д.). Затем #undef print и #define print , чтобы использовать вашу версию таблицы поиска.

-2
ответ дан 7 December 2019 в 14:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: