Що таке фокус LD_PRELOAD?


342

Нещодавно я наткнувся на посилання на проггіт, і це (на сьогодні) не пояснено.

Я підозрюю, що це може бути, але я не знаю точно.


1
Насправді не відповідь, тому я не опублікую її як одну, але ... Стівен Келл використовує LD_PRELOAD для своєї бібліотеки liballocs у цьому відео, і якщо ви переглянете попередні біти, ви можете краще зрозуміти, як / чому. Здається, liballocs використовується, тому інші динамічні мови можуть спілкуватися між собою. У цій розмові є глибокі внутрішні пояснення. youtu.be/LwicN2u6Dro?t=24m10s
Ілля Лінн

Відповіді:


415

Якщо встановити LD_PRELOADшлях спільного об'єкта, цей файл буде завантажений перед будь-якою іншою бібліотекою (включаючи час виконання C libc.so). Тож для запуску lsзі спеціальною malloc()реалізацією зробіть це:

$ LD_PRELOAD=/path/to/my/malloc.so /bin/ls

12
Я не мав уявлення, що це існує ... здається, це було б головним вектором для атак на безпеку. Будь-яка ідея, як це забезпечено?
rmeador

141
Це забезпечено тим, що навантажувач буде ігнорувати LD_PRELOAD, якщо руйнується! = Euid - Джошуа
Джошуа

18
@Joshua: що таке руїна та еїда?
heinrich5991

20
@ heinrich5991 Реальні та ефективні ідентифікатори користувачів: lst.de/~okir/blackhats/node23.html
gsingh2011

59
Одне важливе, що потрібно пам’ятати: зазвичай ви хочете вказати абсолютний шлях до LD_PRELOAD. Причина полягає в тому, що він є змінною оточуючого середовища, він успадковується дочірніми процесами - які можуть мати інший робочий каталог, ніж батьківський процес. Отже, будь-який відносний шлях не зможе знайти бібліотеку для попереднього завантаження.
Фріріх Раабе

49

Ви можете змінити символи в фондових бібліотеках, створивши бібліотеку з тими ж символами та вказавши бібліотеку в LD_PRELOAD.

Деякі люди використовують його для вказівки бібліотек у нестандартних місцях, але LD_LIBRARY_PATHкраще для цієї мети.


17
"Деякі люди використовують його для вказівки бібліотек у нестандартних місцях" ... Дійсно? Звучить так: "Деякі люди його неправильно використовують"!
Том

6
LD_PRELOAD може в порядку завантаження перехоплювати задані додатком тверді коди.
Джошуа

1
Чи було б неправильним передзавантажити іншу версію бібліотеки - якщо припустити, що вони сумісні?
z0r

2
Я бачив, як це використовувалося для завантаження налагодження або інструментального варіанту, або для завантаження бібліотеки, яка робить щось зовсім кардинально відрізняється від базової бібліотеки, як би емуляція якоїсь іншої системи.
Джошуа

1
У випадку, коли бібліотеки неправильно скомпільовані (використовувались для запуску цього з mysql весь час, коли у нього було вільне з'єднання з загальним libmysql_client, яке перезаписало симпосилання старішої версії - залежно від того, яку версію perl ви використовували, ви повинні були вказати / примушуйте його за допомогою LD_PRELOAD .. корисний трюк. Якщо я добре пам’ятаю, valgrind використовує цю техніку, щоб надати можливість налагодження бінарних файлів, не потребуючи перекомпіляції .., це досить корисно.
synthesizerpatel

37

З LD_PRELOADвами можна віддати перевагу бібліотекам.

Наприклад, ви можете написати бібліотеку, яка реалізує mallocта free. І завантажуючи їх LD_PRELOADсвоїми mallocі freeвиконуватимуться, а не стандартними.


але що робити, якщо програма використовує calloc? Чи не все це зіпсувало б?
Янус Троельсен

7
@JanusTroelsen, якщо бібліотека, яку ви пишете, не реалізує певну частину, ця частина буде завантажена з оригінальної бібліотеки.
Вудро Барлоу

@JanusTroelsen, Іншими словами, LD_PRELOAD дозволяє вказати, яка реалізація конкретного символу використовується. Якщо попередньо завантажена бібліотека не експортує символ, вона буде знайдена ще.
sherrellbc

1
@JanusTroelsen: Виявляється, що mallocбезкоштовно і спеціально розроблені в glibc, щоб це дозволило, і акція callocвдається зателефонувати вашим імпортованим malloc. Не намагайтеся це робити з будь-якими іншими функціями. Це не буде так добре.
Джошуа

30

Як згадували багато людей, використовуючи LD_PRELOADдля попереднього завантаження бібліотеку. До речі, ви можете перевірити, чи налаштування доступне lddкомандою.

Приклад: припустимо, вам потрібно попередньо завантажити власний libselinux.so.1.

> ldd /bin/ls
    ...
    libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f3927b1d000)
    libacl.so.1 => /lib/x86_64-linux-gnu/libacl.so.1 (0x00007f3927914000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f392754f000)
    libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f3927311000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f392710c000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f3927d65000)
    libattr.so.1 => /lib/x86_64-linux-gnu/libattr.so.1 (0x00007f3926f07000)

Таким чином, встановіть ваше середовище передзавантаження:

  export LD_PRELOAD=/home/patric/libselinux.so.1

Перевірте свою бібліотеку ще раз:

>ldd /bin/ls
    ...
    libselinux.so.1 =>
    /home/patric/libselinux.so.1 (0x00007fb9245d8000)
    ...

9

LD_PRELOADперелічує спільні бібліотеки з функціями, що перекривають стандартний набір, як і /etc/ld.so.preloadце. Вони реалізовані навантажувачем /lib/ld-linux.so. Якщо ви хочете змінити лише декілька вибраних функцій, ви можете це зробити, створивши переважаючий файл об'єкта та налаштуванняLD_PRELOAD ; функції цього файлу об'єктів замінять лише ті функції, залишаючи інші такими, якими вони були.

Для отримання додаткової інформації про спільні бібліотеки відвідайте http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html


3

Ось детальна публікація в блозі про попередню завантаження:

https://blog.cryptomilk.org/2014/07/21/what-is-preloading/


13
Дякуємо, що опублікували свою відповідь! Будь ласка, зауважте, що ви повинні розмістити основні частини відповіді тут, на цьому веб-сайті, або ваша публікація ризикує бути видаленою Дивіться поширені запитання, де в ній згадуються відповіді, які ледве перевищують посилання. Ви можете все-таки включити посилання за бажанням, але лише як "посилання". Відповідь має стояти самостійно, не потребуючи посилання.
Тарін

3

Експортувати mylib.soдо env легко :

$ export LD_PRELOAD=/path/mylib.so
$ ./mybin

відключити:

$ export LD_PRELOAD=

7
абоunset LD_PRELOAD
Мортен

2

коли використовується LD_PRELOAD, цей файл буде завантажений перед будь-якою іншою $export LD_PRELOAD=/path/libлінком для попереднього завантаження, навіть це можна використовувати і в програмах


1

Використання LD_PRELOAD шлях, ви можете змусити завантажувач додатків завантажувати наданий спільний об'єкт за вказаним типовим умовом.

Розробники використовують це для налагодження своїх додатків, надаючи різні версії спільних об'єктів.

Ми використовували його для злому певних програм, змінивши існуючі функції за допомогою підготовлених спільних об'єктів.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.