Wann/wie lädt Linux gemeinsam genutzte Bibliotheken in den Adressraum?

Lesezeit: 5 Minuten

Ryans Benutzeravatar
Ryan

Meine Frage ist folgende:

Wann wird die Adresse von Shared Objects in Programmen angegeben? Beim Verlinken? Wird geladen? Wenn ich die Speicheradresse der finden wollte system Befehl innerhalb von libc In meinem Programm konnte ich es leicht finden gdbaber was ist, wenn ich das Programm nicht in einen Debugger bringen möchte?

Könnte sich diese Adresse von Lauf zu Lauf ändern? Gibt es ein anderes statisches Analysetool, mit dem angezeigt werden kann, wo Bibliotheken oder Funktionen beim Ausführen in den Speicherbereich dieses Programms geladen werden?

BEARBEITEN: Ich möchte diese Informationen außerhalb des Programms (dh mit Dienstprogrammen wie objdump Informationen einholen)

  • und dann gibt es prelinkwodurch sich die Reihenfolge erheblich ändert.

    – Ben Voigt

    27. Februar 2011 um 1:16 Uhr


Benutzeravatar von osgx
osgx

Bibliotheken werden geladen von ld.so (dynamischer Linker oder Laufzeitlinker, auch bekannt als rtld, ld-linux.so.2 oder ld-linux.so.* im Fall von Linux; Teil von glibc). Es wird als “Interpreter” (INTERP; .interp Abschnitt) aller dynamisch verknüpften ELF-Binärdateien. Wenn Sie also das Programm starten, startet Linux eine ld.so (in den Speicher laden und zu seinem Einstiegspunkt springen), dann ld.so lädt Ihr Programm in den Speicher, bereitet es vor und führt es dann aus. Sie können das dynamische Programm auch mit starten

 /lib/ld-linux.so.2 ./your_program your_prog_params

ld.so macht eine tatsächliche open und mmap aller benötigten ELF-Dateien, sowohl die ELF-Datei Ihres Programms als auch die ELF-Dateien aller benötigten Bibliotheken. Außerdem füllt es GOT- und PLT-Tabellen und löst Verschiebungen auf (es schreibt Adressen von Funktionen aus Bibliotheken, um Sites aufzurufen, in vielen Fällen mit indirekten Aufrufen).

Die typische Ladeadresse einiger Bibliotheken, die Sie erhalten können ldd Dienstprogramm. Es ist eigentlich ein Bash-Skript, das eine Debug-Umgebungsvariable von ld.so (eigentlich LD_TRACE_LOADED_OBJECTS=1 im Falle von rtld von glibc) und startet ein Programm. Sie können es sogar auch ohne die Notwendigkeit des Skripts selbst tun, z. B. mit der Verwendung von Bash zum einfachen Ändern von Umgebungsvariablen für einen einzelnen Lauf:

 LD_TRACE_LOADED_OBJECTS=1 /bin/echo

Das ld.so sieht diese Variable und löst alle benötigten Bibliotheken auf und gibt die Ladeadressen von ihnen aus. Aber mit diesem Variablensatz ld.so wird ein Programm nicht wirklich starten (nicht sicher über statische Konstruktoren von Programmen oder Bibliotheken). Wenn die ASLR-Funktion deaktiviert ist, ist die Ladeadresse meistens dieselbe. Moderne Linuxe haben oft ASLR aktiviert, um es also zu deaktivieren, verwenden Sie echo 0 | sudo tee /proc/sys/kernel/randomize_va_space.

Sie finden Offset von system Funktion innerhalb der libc.so mit nm Dienstprogramm von binutils. Ich denke, Sie sollten verwenden nm -D /lib/libc.so oder objdump -T /lib/libc.so und grep-Ausgabe.

  • wunderbare Informationen, danke. Kennen Sie gute Artikel, die erklären, wie dieser Prozess funktioniert (Generieren von GOT / PLT-Tabellen), oder würde Googeln zu ausreichenden Ergebnissen führen?

    – Ryan

    27. Februar 2011 um 1:07 Uhr

  • Wenn Sie anrufen möchten system mit absoluter Adresse können Sie dies tun, ohne GOT- und PLT-Tabellen zu verwenden. In meinem Punkt, das beste googeln für ld.so ist Codesuche: google.com/…

    – osgx

    27. Februar 2011 um 1:14 Uhr

  • Ja, ich weiß, dass Sie es tun können, ohne GOT und PLT zu verwenden, es war reine Neugier meinerseits! 🙂

    – Ryan

    27. Februar 2011 um 1:17 Uhr

  • Das war sehr informativ! Ich wusste nicht viel über ld.so und ldd!

    – Matt Tischler

    28. Februar 2011 um 2:20 Uhr

  • Diese Antwort ist darin falsch ld.so tut nicht Laden Sie das Hauptprogramm, der Kernel tut es. Der Kernel sieht sich auch keine an Abschnitte (die vollständig entfernt werden könnte), findet es den Interpreter in PT_INTERP Segment.

    – Angestellter Russe

    28. Mai 2017 um 15:48 Uhr

“Geh direkt zur Quelle und frage das Pferd…”

Drepper – So schreiben Sie gemeinsam genutzte Bibliotheken

Unverzichtbare Dokumentation für Autoren von Linux-Bibliotheken. Erklärt die Mechanik des Ladens im Detail.

Wenn Sie nur die Adresse einer Funktion möchten, ohne den Namen fest zu codieren, können Sie dies tun dlopen() Das Hauptprogramm:

void *self = dlopen(NULL, RTLD_NOW);
dlsym(self, "system"); // returns the pointer to the system() function

Wenn Sie nur die Adresse einer Funktion benötigen, deren Namen Sie zur Kompilierzeit kennen, verwenden Sie einfach void *addr = &system;

  • siehe Bearbeiten in OP, aber belassen Sie diese Antwort auf jeden Fall, da sie für eine andere Variante des möglicherweise vagen Titels hilfreich ist. (wie du darauf geantwortet hast)

    – Ryan

    27. Februar 2011 um 0:54 Uhr


  • Es ist möglich, dass keiner von beiden das tut, was OP will, da system wird wahrscheinlich zu einem PLT-Eintrag im Hauptprogrammbild aufgelöst, das den eigentlichen Sprung in die gemeinsam genutzte Bibliothek durchführt.

    – R.. GitHub HÖR AUF, EIS ZU HELFEN

    27. Februar 2011 um 0:54 Uhr

Das nm Befehl, verwendet auf libc.sozeigt Ihnen den Standort der system Symbol ein libc.so. Wenn jedoch ASLR aktiviert ist, wird die Adresse libc.so geladen wird, und damit die endgültige Adresse von system ändert sich zufällig jedes Mal, wenn Ihr Programm ausgeführt wird. Auch ohne ASLR müssen Sie die Adresse ermitteln libc.so wird bei geladen und versetzt die Adresse von system um diesen Betrag.

Ich würde empfehlen, dass Ihre Umgebung den Pfad LD_LIBRARY_PATH hat. Dies definiert, wo die gemeinsam genutzten Bibliotheken zu finden sind. Möglicherweise müssen Sie auch in /etc/ld.so.conf nachsehen. Sehen Sie sich diesen Beitrag an http://www.google.com/url?sa=t&source=web&cd=3&ved=0CCQQFjAC&url=http%3A%2F%2Fubuntuforums.org%2Fshowthread.php%3Ft%3D324660&ei=KqJpTey7JofEsAPE9_imBA&usg=AFQjCNEIbGGrTHp4fufRuj4Yfc58RTHcag&sig=AFQjCNEIbGGrTHp4fufRuj4Yfc58RTHcag&sig=

1407440cookie-checkWann/wie lädt Linux gemeinsam genutzte Bibliotheken in den Adressraum?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy