Cos'è il trucco LD_PRELOAD?


342

Mi sono imbattuto recentemente in un riferimento a proggit e (per ora) non è stato spiegato.

Ho il sospetto che questo potrebbe essere, ma non lo so per certo.


1
Non proprio una risposta, quindi non la posterò come tale, ma ... Stephen Kell sta usando LD_PRELOAD per la sua libreria liballocs in questo video e se guardi i bit precedenti potresti capire meglio come / perché. sembra che liballocs sia utilizzato in modo che altri linguaggi dinamici possano parlarsi. In questo discorso sono stati spiegati alcuni interni profondi. youtu.be/LwicN2u6Dro?t=24m10s
Elijah Lynn

Risposte:


415

Se si imposta LD_PRELOADil percorso di un oggetto condiviso, quel file verrà caricato prima di qualsiasi altra libreria (incluso il runtime C libc.so). Quindi per eseguire lscon l' malloc()implementazione speciale , procedere come segue:

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

12
Non avevo idea che esistesse ... sembra che sarebbe un vettore importante per gli attacchi alla sicurezza. Qualche idea su come sia protetto?
Direttore

141
È garantito dal fatto che il caricatore ignorerà LD_PRELOAD se ruid! = Euid - Joshua
Joshua

18
@Joshua: cosa sono i ruid e l'euid?
heinrich5991,

20
@ heinrich5991 ID utente reali ed efficaci: lst.de/~okir/blackhats/node23.html
gsingh2011

59
Una cosa importante da tenere a mente: di solito si desidera specificare un percorso assoluto a LD_PRELOAD. Il motivo è che essendo una variabile di ambiente, è ereditata da processi figlio, che possono avere una directory di lavoro diversa rispetto al processo padre. Pertanto, qualsiasi percorso relativo non riuscirebbe a individuare la libreria da precaricare.
Frerich Raabe,

49

È possibile sovrascrivere i simboli nelle librerie di titoli creando una libreria con gli stessi simboli e specificando la libreria in LD_PRELOAD.

Alcune persone lo usano per specificare le librerie in posizioni non standard, ma LD_LIBRARY_PATHè meglio a tale scopo.


17
"Alcune persone lo usano per specificare le librerie in posizioni non standard" ... Davvero? Sembra "Alcune persone lo usano male"!
Tom,

6
LD_PRELOAD può intercettare i percorsi hardcoded specificati dall'applicazione in base all'ordine di caricamento.
Giosuè,

1
Sarebbe un uso improprio precaricare una versione diversa di una libreria - supponendo che siano compatibili?
z0r

2
L'ho visto usato per caricare un debug o una variante strumentata, o per caricare una libreria che fa qualcosa di radicalmente diverso dalla libreria di base come per emulare qualche altro sistema.
Giosuè,

1
Nel caso in cui le librerie non siano compilate correttamente (usato per incontrarsi con mysql per tutto il tempo in cui aveva un accoppiamento libero con un libmysql_client generico che sovrascriveva il link simbolico di una versione precedente - a seconda della versione di perl che hai usato devi specificare / forzalo con il trucco utile di LD_PRELOAD .. Se ricordo bene, valgrind usa questa tecnica per fornire capacità di debug ai binari senza dover ricompilare .. è abbastanza utile
synthesizerpatel

37

Con LD_PRELOADte puoi dare la precedenza alle biblioteche.

Ad esempio è possibile scrivere una libreria che implementa malloce free. E caricandoli con il LD_PRELOADtuo malloce freeverranno eseguiti anziché quelli standard.


ma cosa succede se il programma utilizza calloc? non rovinerebbe tutto?
Janus Troelsen,

7
@JanusTroelsen se la libreria che scrivi non implementa una determinata parte, quella parte verrebbe caricata dalla libreria originale.
Woodrow Barlow,

@JanusTroelsen, In altre parole, LD_PRELOAD ti consente di specificare quale implementazione di un simbolo specifico viene utilizzata. Se la libreria precaricata non esporta un simbolo, verrà trovata altrimenti.
sherrellbc,

1
@JanusTroelsen: Si scopre che malloce gratuito sono specificamente progettati in glibc per consentire questo e lo stock callocriesce a chiamare il tuo importato malloc. Non provarlo con altre funzioni. Non funzionerà così bene.
Giosuè il

30

Come molte persone hanno detto, usando LD_PRELOADper precaricare la libreria. A proposito, puoi CONTROLLARE se l'impostazione è disponibile tramite lddcomando.

Esempio: supponi di dover precaricare il tuo 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)

Quindi, imposta il tuo ambiente di precarico:

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

Controlla di nuovo la tua libreria:

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

9

LD_PRELOADelenca le librerie condivise con funzioni che sovrascrivono il set standard, proprio come /etc/ld.so.preloadfa. Questi sono implementati dal caricatore /lib/ld-linux.so. Se si desidera sovrascrivere solo alcune funzioni selezionate, è possibile farlo creando un file oggetto e un'impostazione di sostituzione LD_PRELOAD; le funzioni in questo file oggetto sovrascriveranno solo quelle funzioni lasciando gli altri come erano.

Per ulteriori informazioni sulle librerie condivise, visitare http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html


3

Ecco un post dettagliato sul blog sul precaricamento:

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


13
Grazie per aver pubblicato la tua risposta! Tieni presente che dovresti pubblicare qui le parti essenziali della risposta, su questo sito, oppure i tuoi messaggi rischiano di essere eliminati Vedi le FAQ in cui menziona risposte che sono "a malapena più di un link". Se lo desideri, puoi comunque includere il link, ma solo come "riferimento". La risposta dovrebbe essere autonoma senza il collegamento.
Taryn

3

è facile esportare mylib.soin env:

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

disabilitare :

$ export LD_PRELOAD=

7
oppureunset LD_PRELOAD
Morten il

2

quando viene utilizzato LD_PRELOAD, quel file verrà caricato prima di qualsiasi altra $export LD_PRELOAD=/path/liblibreria da precaricare, anche questo può essere usato anche nei programmi


1

Utilizzando il LD_PRELOADpercorso, è possibile forzare il caricatore dell'applicazione a caricare l'oggetto condiviso fornito, rispetto al valore predefinito fornito.

Gli sviluppatori lo usano per eseguire il debug delle loro applicazioni fornendo diverse versioni degli oggetti condivisi.

Lo abbiamo usato per hackerare determinate applicazioni, sovrascrivendo le funzioni esistenti usando oggetti condivisi preparati.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.