Was ist der LD_PRELOAD-Trick?


341

Ich bin kürzlich auf proggit auf einen Hinweis darauf gestoßen, der (ab sofort) nicht erklärt wird.

Ich vermute, das könnte es sein, aber ich weiß es nicht genau.


1
Keine wirkliche Antwort, daher werde ich sie nicht als eine veröffentlichen, aber ... Stephen Kell verwendet LD_PRELOAD für seine liballocs-Bibliothek in diesem Video. Wenn Sie sich die vorherigen Teile ansehen, erhalten Sie möglicherweise ein besseres Verständnis dafür, wie / warum. liballocs scheint verwendet zu werden, damit andere dynamische Sprachen miteinander sprechen können. In diesem Vortrag werden einige tiefe Interna erklärt. youtu.be/LwicN2u6Dro?t=24m10s
Elijah Lynn

Antworten:


415

Wenn Sie LD_PRELOADden Pfad eines freigegebenen Objekts festlegen , wird diese Datei vor jeder anderen Bibliothek (einschließlich der C-Laufzeit libc.so) geladen . Gehen Sie folgendermaßen vor, um lsmit Ihrer speziellen malloc()Implementierung zu arbeiten:

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

12
Ich hatte keine Ahnung, dass dies existiert ... es scheint, als wäre es ein wichtiger Vektor für Sicherheitsangriffe. Irgendeine Idee, wie es gesichert ist?
Rmeador

141
Es wird durch die Tatsache gesichert, dass der Lader LD_PRELOAD ignoriert, wenn ruid! = Euid - Joshua
Joshua

18
@ Joshua: Was sind Ruid und Euid?
heinrich5991

20
@ heinrich5991 Echte und effektive Benutzer-IDs: lst.de/~okir/blackhats/node23.html
gsingh2011

59
Eine wichtige Sache, die Sie beachten sollten: Normalerweise möchten Sie einen absoluten Pfad zu angeben LD_PRELOAD. Der Grund dafür ist, dass es sich um eine Umgebungsvariable handelt, die von untergeordneten Prozessen geerbt wird, die möglicherweise ein anderes Arbeitsverzeichnis als der übergeordnete Prozess haben. Daher würde ein relativer Pfad die Bibliothek zum Vorladen nicht finden.
Frerich Raabe

49

Sie können Symbole in den Bestandsbibliotheken überschreiben, indem Sie eine Bibliothek mit denselben Symbolen erstellen und die Bibliothek in angeben LD_PRELOAD .

Einige Leute verwenden es, um Bibliotheken an nicht standardmäßigen Orten anzugeben, aber es LD_LIBRARY_PATHist besser für diesen Zweck.


17
"Einige Leute verwenden es, um Bibliotheken an nicht standardmäßigen Orten anzugeben" ... Wirklich? Klingt nach "Manche Leute benutzen es falsch"!
Tom

6
LD_PRELOAD kann aufgrund der Ladereihenfolge anwendungsspezifische fest codierte Pfade abfangen.
Joshua

1
Wäre es ein Missbrauch, eine andere Version einer Bibliothek vorab zu laden - vorausgesetzt, sie sind kompatibel?
z0r

2
Ich habe gesehen, dass es verwendet wurde, um ein Debug oder eine instrumentierte Variante zu laden oder um eine Bibliothek zu laden, die etwas völlig anderes als die Basisbibliothek tut, als ob sie ein anderes System emulieren würde.
Joshua

1
In dem Fall, in dem Bibliotheken nicht korrekt kompiliert wurden (wird verwendet, um dies mit mysql die ganze Zeit zu tun, wenn es eine lose Kopplung mit einem generischen libmysql_client hatte, der den Symlink einer älteren Version überschrieb - abhängig davon, welche Version von Perl Sie angegeben haben / erzwinge es mit LD_PRELOAD .. nützlicher Trick. Wenn ich mich richtig erinnere, verwendet valgrind diese Technik, um Binärdateien Debugging-Fähigkeit zu bieten, ohne neu kompilieren zu müssen .. es ist sehr nützlich.
Synthesizerpatel

37

Mit LD_PRELOAD Sie Bibliotheken Vorrang geben.

Zum Beispiel können Sie eine Bibliothek schreiben, die mallocund implementiert free. Und indem Sie diese mit LD_PRELOADIhrem laden mallocund freewerden statt der Standard ausgeführt.


aber was ist, wenn das Programm verwendet calloc? würde das nicht alles durcheinander bringen?
Janus Troelsen

7
@JanusTroelsen Wenn die von Ihnen geschriebene Bibliothek keinen bestimmten Teil implementiert, wird dieser Teil aus der ursprünglichen Bibliothek geladen.
Woodrow Barlow

@JanusTroelsen, Mit anderen Worten, mit LD_PRELOAD können Sie angeben, welche Implementierung eines bestimmten Symbols verwendet wird. Wenn die vorinstallierte Bibliothek kein Symbol exportiert, wird es an anderer Stelle gefunden.
Sherellbc

1
@JanusTroelsen: Es stellt sich heraus, dass mallocund free speziell in glibc entwickelt wurden, um dies zu ermöglichen, und der Bestand callocschafft es, Ihre importierten aufzurufen malloc. Versuchen Sie dies nicht mit anderen Funktionen. Es wird nicht so gut funktionieren.
Joshua

30

Wie viele Leute bereits erwähnt haben, wird die LD_PRELOADBibliothek vorgeladen. Übrigens können Sie PRÜFEN, ob die Einstellung auf lddBefehl verfügbar ist .

Beispiel: Angenommen, Sie müssen Ihre eigenen vorladen 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)

Stellen Sie daher Ihre Preload-Umgebung ein:

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

Überprüfen Sie Ihre Bibliothek erneut:

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

9

LD_PRELOADlistet gemeinsam genutzte Bibliotheken mit Funktionen auf, die den Standardsatz überschreiben /etc/ld.so.preload. Diese werden vom Loader implementiert /lib/ld-linux.so. Wenn Sie nur einige ausgewählte Funktionen überschreiben möchten, können Sie dies tun, indem Sie eine überschreibende Objektdatei und -einstellung erstellen LD_PRELOAD. Die Funktionen in dieser Objektdatei überschreiben nur die Funktionen, die andere unverändert lassen.

Weitere Informationen zu gemeinsam genutzten Bibliotheken finden Sie unter http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html


3

Hier ist ein ausführlicher Blog-Beitrag zum Vorladen:

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


13
Vielen Dank für Ihre Antwort! Bitte beachten Sie, dass Sie die wesentlichen Teile der Antwort hier auf dieser Website veröffentlichen sollten, da sonst die Gefahr besteht, dass Ihr Beitrag gelöscht wird . In den häufig gestellten Fragen werden Antworten erwähnt, die "kaum mehr als ein Link" sind. Sie können den Link weiterhin einfügen, wenn Sie dies wünschen, jedoch nur als 'Referenz'. Die Antwort sollte für sich allein stehen, ohne den Link zu benötigen.
Taryn

3

Es ist einfach, mylib.sonach env zu exportieren :

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

Etwas deaktivieren :

$ export LD_PRELOAD=

7
oderunset LD_PRELOAD
Morten

2

Wenn LD_PRELOAD verwendet wird, wird diese Datei vor jeder anderen Bibliothek geladen $export LD_PRELOAD=/path/lib, die vorgeladen werden soll. Dies kann auch in Programmen verwendet werden


1

Mithilfe des LD_PRELOADPfads können Sie den Anwendungslader zwingen, das bereitgestellte freigegebene Objekt über den bereitgestellten Standard zu laden.

Entwickler verwenden dies zum Debuggen ihrer Anwendungen, indem sie verschiedene Versionen der freigegebenen Objekte bereitstellen.

Wir haben es verwendet, um bestimmte Anwendungen zu hacken, indem wir vorhandene Funktionen mit vorbereiteten gemeinsam genutzten Objekten überschrieben haben.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.