Dalam strace
output, jalur ke perpustakaan yang dapat dieksekusi panggilan dalam panggilan ke open()
. Apakah ini panggilan sistem yang digunakan oleh executable yang terhubung secara dinamis? Bagaimana dengan dlopen()
? open()
bukan panggilan saya kira akan berperan dalam pelaksanaan program.
23
ld-linux
dipetakan oleh kernel sebagai bagian dariexecve
panggilan sistem.dlopen tidak ada hubungannya dengan perpustakaan bersama seperti yang Anda pikirkan. Ada dua metode memuat objek yang dibagikan:
main
fungsi dipanggil, dan mengatur ruang proses aplikasi sehingga aplikasi akan menemukan fungsi perpustakaan. Ini melibatkanopen()
ing, yang kemudianmmap()
, diikuti dengan mengatur beberapa tabel pencarian.libdl
, dari mana Anda kemudian (menggunakan metode pertama) dapat memanggildlopen()
dandlsym()
fungsi. Dengan dlopen Anda mendapatkan pegangan ke perpustakaan, yang kemudian dapat Anda gunakan dengan dlsym untuk menerima pointer fungsi ke fungsi tertentu. Metode ini jauh lebih rumit untuk programmer daripada metode pertama (karena Anda harus melakukan setup secara manual, daripada memiliki linker melakukannya secara otomatis untuk Anda), dan juga lebih rapuh (karena Anda tidak mendapatkan kompilasi -pengecekan waktu bahwa Anda memanggil fungsi dengan tipe argumen yang benar seperti yang Anda dapatkan di metode pertama), tetapi keuntungannya adalah Anda dapat memutuskan objek yang dibagikan untuk dimuat saat runtime (atau bahkan apakah akan memuatnya sama sekali), membuat antarmuka ini dimaksudkan untuk fungsionalitas jenis plugin. Akhirnya, antarmuka dlopen juga kurang portabel daripada cara lain, karena mekanismenya bergantung pada implementasi yang tepat dari dynamic linker (karenanya libtool'slibltdl
, yang mencoba untuk menghilangkan perbedaan ini).sumber
Saat ini, sebagian besar sistem operasi menggunakan metode untuk perpustakaan bersama yang diperkenalkan pada akhir 1987 oleh SunOS-4.0. Metode ini didasarkan pada pemetaan memori melalui mmap ().
Mengingat fakta bahwa pada awal 1990-an, Sun bahkan menyumbangkan kode lama berbasis a.out (Solaris pada waktu itu sudah berbasis ELF) kepada orang-orang FreeBSD dan bahwa kode ini kemudian diserahkan ke banyak sistem lain (termasuk Linux) , Anda mungkin mengerti mengapa tidak ada perbedaan besar antara platform.
sumber
ltrace -S
analisis contoh minimal menunjukkan bahwammap
digunakan dalam glibc 2.23Di glibc 2.23, Ubuntu 16.04, berjalan
latrace -S
pada program minimal yang digunakandlopen
dengan:menunjukkan:
jadi kami segera melihat bahwa
dlopen
panggilanopen
+mmap
.Alat luar biasa ini
ltrace
melacak panggilan perpustakaan dan panggilan sistem, dan karenanya sempurna untuk memeriksa apa yang terjadi dalam kasus ini.Analisis yang lebih dekat menunjukkan bahwa
open
mengembalikan deskriptor file3
(yang berikutnya gratis setelah stdin, out dan err).read
kemudian menggunakan file descriptor itu, tetapi TODO mengapammap
argumen dibatasi hingga empat, dan kita tidak bisa melihat mana fd digunakan di sana karena itu adalah argumen ke-5 .strace
menegaskan seperti yang diharapkan itu3
adalah satu, dan tatanan alam semesta dipulihkan.Jiwa yang berani juga dapat menjelajah ke kode glibc, tetapi saya tidak dapat menemukan
mmap
setelah grep cepat dan saya malas.Diuji dengan contoh minimal ini dengan membuat boilerplate di GitHub .
sumber
strace
laporan panggilan sistem (yaitu fungsi yang diimplementasikan langsung oleh kernel). Pustaka dinamis bukan fungsi kernel;dlopen
adalah bagian dari pustaka C, bukan kernel. Pelaksanaandlopen
panggilan akanopen
(yang merupakan panggilan sistem) untuk membuka file perpustakaan sehingga dapat dibaca.sumber
ltrace
.ltrace -S
sempurna untuk menganalisis ini karena ia juga menampilkan syscalls