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

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


Meine Frage ist folgende:


Wann wird die Adresse von Shared Objects in Programmen angegeben? Beim Verlinken? Wird geladen? Wenn ich die Speicheradresse des system finden wollte Befehl innerhalb von libc Innerhalb meines Programms konnte ich es leicht in gdb finden , aber 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, das es ermöglicht, anzuzeigen, wo Bibliotheken oder Funktionen in den Speicherbereich dieses Programms geladen werden, wenn es ausgeführt wird?


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


Antworten:


Bibliotheken werden von ld.so geladen (dynamischer Linker oder Laufzeitlinker, auch bekannt als rtld, ld-linux.so.2 oder ld-linux.so.* im Fall von Linux; Teil von glibc). Er ist als "Interpreter" deklariert (INTERP; .interp Abschnitt) aller dynamisch verknüpften ELF-Binärdateien. Wenn Sie also das Programm starten, startet Linux ein 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 einen tatsächlichen 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 von Bibliotheken zu Aufrufseiten, in vielen Fällen mit indirekten Aufrufen).


Die typische Ladeadresse einiger Bibliotheken erhalten Sie mit ldd Dienstprogramm. Es ist eigentlich ein Bash-Skript, das eine Debug-Umgebungsvariable von ld.so (eigentlich LD_TRACE_LOADED_OBJECTS=1) setzt im Falle von rtld von glibc) und startet ein Programm. Sie können es sogar auch ohne Bedarf des Skripts selbst tun, z. mit bash einfache Änderung der Umgebungsvariablen für Einzellauf:


 LD_TRACE_LOADED_OBJECTS=1 /bin/echo

Die 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 gleich. 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 den Offset von system Funktion innerhalb des libc.so mit nm Dienstprogramm von binutils. Ich denke, Sie sollten nm -D /lib/libc.so verwenden oder objdump -T /lib/libc.so und grep-Ausgabe.