Apakah trik LD_PRELOAD itu?

341

Saya menemukan referensi untuk itu baru-baru ini di proggit dan (seperti yang sekarang) tidak dijelaskan.

Saya curiga ini mungkin, tapi saya tidak tahu pasti.

Hank Gay
sumber
1
Bukan jawaban yang benar-benar jadi saya tidak akan mempostingnya sebagai satu tapi ... Stephen Kell menggunakan LD_PRELOAD untuk pustaka liballocs-nya di video ini dan jika Anda menonton bit sebelumnya Anda mungkin mendapatkan pemahaman yang lebih baik tentang bagaimana / mengapa. liballocs tampaknya sedang digunakan sehingga bahasa dinamis lainnya dapat berbicara satu sama lain. Pembicaraan ini memiliki beberapa internal yang dijelaskan di dalamnya. youtu.be/LwicN2u6Dro?t=24m10s
Elijah Lynn

Jawaban:

415

Jika Anda menyetel LD_PRELOADke lintasan objek bersama, file itu akan dimuat sebelum perpustakaan lain (termasuk runtime C, libc.so). Jadi untuk menjalankan lsdengan malloc()implementasi khusus Anda , lakukan ini:

$ LD_PRELOAD=/path/to/my/malloc.so /bin/ls
JesperE
sumber
12
Saya tidak tahu ini ada ... sepertinya itu akan menjadi vektor utama untuk serangan keamanan. Adakah yang tahu bagaimana cara mengamankannya?
rmeador
141
Itu dijamin oleh fakta bahwa loader akan mengabaikan LD_PRELOAD jika rusak! = Euid - Joshua
Joshua
18
@ Yosua: apa yang rusak dan lancar?
heinrich5991
20
@ heinrich5991 Id pengguna yang nyata dan efektif: lst.de/ ~okir
blackhats
59
Satu hal penting yang perlu diingat: Anda biasanya ingin menentukan jalur absolut untuk LD_PRELOAD. Alasannya adalah bahwa itu menjadi variabel lingkungan, itu diwarisi oleh proses anak - yang mungkin memiliki direktori kerja yang berbeda dari proses induk. Jadi setiap jalur relatif akan gagal menemukan perpustakaan untuk dimuat sebelumnya.
Frerich Raabe
49

Anda bisa mengganti simbol di pustaka stok dengan membuat pustaka dengan simbol yang sama dan menentukan pustaka di LD_PRELOAD.

Beberapa orang menggunakannya untuk menentukan perpustakaan di lokasi yang tidak standar, tetapi LD_LIBRARY_PATHlebih baik untuk tujuan itu.

Joshua
sumber
17
"Beberapa orang menggunakannya untuk menentukan perpustakaan di lokasi yang tidak standar" ... Benarkah? Kedengarannya seperti "Beberapa orang salah menggunakannya"!
Tom
6
LD_PRELOAD dapat berdasarkan jalur pemuatan pesanan mencegat jalur hardcod yang ditentukan aplikasi.
Joshua
1
Apakah ini merupakan penyalahgunaan untuk memuat versi perpustakaan yang berbeda - dengan asumsi mereka kompatibel?
z0r
2
Saya pernah melihatnya memuat varian debug atau instrumen, atau memuat pustaka yang melakukan sesuatu yang sama sekali berbeda dari pustaka dasar seolah-olah meniru beberapa sistem lain.
Joshua
1
Dalam kasus di mana pustaka tidak dikompilasi dengan benar (digunakan untuk menjalankan ini dengan mysql sepanjang waktu di mana pustaka longgar ke libmysql_client umum yang menimpa symlink versi yang lebih lama - tergantung pada versi perl yang Anda gunakan, Anda harus menentukan / paksa dengan LD_PRELOAD .. trik yang berguna.Jika saya ingat dengan benar, valgrind menggunakan teknik ini untuk memberikan kemampuan debug ke biner tanpa perlu mengkompilasi ulang .. ini cukup berguna
synthesizerpatel
37

Dengan LD_PRELOADAnda dapat memberikan prioritas perpustakaan.

Misalnya Anda dapat menulis perpustakaan yang menerapkan mallocdan free. Dan dengan memuat ini dengan LD_PRELOADAnda mallocdan freeakan dieksekusi daripada yang standar.

Ronny Brendel
sumber
tetapi bagaimana jika program menggunakan calloc? bukankah itu mengacaukan segalanya?
Janus Troelsen
7
@ JanusTroelsen jika perpustakaan yang Anda tulis tidak menerapkan bagian tertentu, bagian itu akan diambil dari perpustakaan asli.
Woodrow Barlow
@ JanusTroelsen, Dengan kata lain, LD_PRELOAD memungkinkan Anda menentukan penerapan simbol tertentu mana yang digunakan. Jika perpustakaan yang dimuat sebelumnya tidak mengekspor simbol, itu akan ditemukan di tempat lain.
sherrellbc
1
@ JanusTroelsen: Ternyata mallocdan gratis dirancang khusus dalam glibc untuk memungkinkan ini dan stok callocmengelola panggilan Anda yang diimpor malloc. Jangan coba ini dengan fungsi lain. Itu tidak akan bekerja dengan baik.
Joshua
30

Seperti yang banyak orang sebutkan, gunakan LD_PRELOADuntuk preload library. BTW, Anda dapat PERIKSA jika pengaturan tersedia dengan lddperintah.

Contoh: misalkan Anda harus melakukan preload sendiri 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)

Jadi, atur lingkungan preload Anda:

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

Periksa perpustakaan Anda lagi:

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

LD_PRELOADdaftar pustaka bersama dengan fungsi yang mengesampingkan set standar, sama seperti /etc/ld.so.preloadhalnya. Ini diimplementasikan oleh loader /lib/ld-linux.so. Jika Anda ingin menimpa hanya beberapa fungsi yang dipilih, Anda dapat melakukan ini dengan membuat file dan pengaturan objek override LD_PRELOAD; fungsi-fungsi dalam file objek ini akan menimpa hanya fungsi-fungsi yang meninggalkan yang lain.

Untuk informasi lebih lanjut tentang perpustakaan bersama, kunjungi http://tldp.org/HOWTO/Program-Library-HOWTO/ Shared-libraries.html

Rajesh
sumber
3

Berikut ini adalah posting blog terperinci tentang preloading:

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

asn
sumber
13
Terima kasih telah mengirim jawaban Anda! Harap dicatat bahwa Anda harus memposting bagian-bagian penting dari jawaban di sini, di situs ini, atau posting Anda berisiko dihapus. Lihat FAQ di mana ia menyebutkan jawaban yang 'hampir tidak lebih dari sebuah tautan'. Anda masih dapat menyertakan tautan jika diinginkan, tetapi hanya sebagai 'referensi'. Jawabannya harus berdiri sendiri tanpa memerlukan tautan.
Taryn
3

mudah diekspor mylib.soke env:

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

untuk menonaktifkan:

$ export LD_PRELOAD=
JulienGenoud
sumber
7
atauunset LD_PRELOAD
Morten
2

ketika LD_PRELOAD digunakan, file akan dimuat sebelum $export LD_PRELOAD=/path/liblib lain untuk dimuat sebelumnya, bahkan ini dapat digunakan dalam program juga

Sumith Senarathne
sumber
1

Dengan menggunakan LD_PRELOADjalur, Anda dapat memaksa pemuat aplikasi memuat objek yang disediakan bersama, melebihi standar yang disediakan.

Pengembang menggunakan ini untuk men-debug aplikasi mereka dengan menyediakan berbagai versi objek yang dibagikan.

Kami telah menggunakannya untuk meretas aplikasi tertentu, dengan mengesampingkan fungsi yang ada menggunakan objek bersama yang disiapkan.

dnahc araknayirp
sumber