¿Cuál es el truco LD_PRELOAD?

341

Me encontré con una referencia a él recientemente en proggit y (a partir de ahora) no se explica.

Sospecho que esto podría ser, pero no estoy seguro.

Hank Gay
fuente
1
Realmente no es una respuesta, así que no la publicaré como una, pero ... Stephen Kell está usando LD_PRELOAD para su biblioteca liballocs en este video y si observa los bits anteriores, puede comprender mejor cómo / por qué. Parece que liballocs se está utilizando para que otros lenguajes dinámicos puedan comunicarse entre sí. Esta charla tiene algunas partes internas profundas explicadas en ella. youtu.be/LwicN2u6Dro?t=24m10s
Elijah Lynn

Respuestas:

415

Si establece LD_PRELOADla ruta de un objeto compartido, ese archivo se cargará antes que cualquier otra biblioteca (incluido el tiempo de ejecución C libc.so). Entonces, para ejecutar lscon su malloc()implementación especial , haga esto:

$ LD_PRELOAD=/path/to/my/malloc.so /bin/ls
JesperE
fuente
12
No tenía idea de que esto existía ... parece que sería un vector importante para los ataques de seguridad. ¿Alguna idea de cómo se asegura?
rmeador
141
Está asegurado por el hecho de que el cargador ignorará LD_PRELOAD si es ruid! = Euid - Joshua
Joshua
18
@Joshua: ¿qué son ruid y euid?
heinrich5991
20
@ heinrich5991 ID de
gsingh2011
59
Una cosa importante a tener en cuenta: generalmente desea especificar una ruta absoluta a LD_PRELOAD. La razón es que, al ser una variable de entorno, la heredan los procesos secundarios, que pueden tener un directorio de trabajo diferente al proceso principal. Por lo tanto, cualquier ruta relativa no podría localizar la biblioteca para precargarla.
Frerich Raabe
49

Puede anular los símbolos en las bibliotecas de valores creando una biblioteca con los mismos símbolos y especificando la biblioteca en LD_PRELOAD.

Algunas personas lo usan para especificar bibliotecas en ubicaciones no estándar, pero LD_LIBRARY_PATHes mejor para ese propósito.

Joshua
fuente
17
"Algunas personas lo usan para especificar bibliotecas en ubicaciones no estándar" ... ¿En serio? ¡Suena como "Algunas personas lo usan mal"!
Tom
66
LD_PRELOAD puede, en virtud del orden de carga, interceptar rutas codificadas especificadas por la aplicación.
Joshua
1
¿Sería un mal uso precargar una versión diferente de una biblioteca, suponiendo que sean compatibles?
z0r
2
He visto que solía cargar una variante depurada o instrumentada, o cargar una biblioteca que hace algo completamente diferente de la biblioteca base como para emular algún otro sistema.
Joshua
1
En el caso de que las bibliotecas no se compilen correctamente (solía encontrarse con esto con mysql todo el tiempo donde tenía un acoplamiento flojo a un libmysql_client genérico que sobrescribía el enlace simbólico de una versión anterior, dependiendo de la versión de perl que usaba, tenía que especificar / forzarlo con LD_PRELOAD ... truco útil. Si no recuerdo mal, valgrind usa esta técnica para proporcionar la capacidad de depuración a los archivos binarios sin necesidad de volver a compilar ... es bastante útil.
sintetizadorpatel
37

Con LD_PRELOADusted puede dar prioridad a las bibliotecas.

Por ejemplo, puede escribir una biblioteca que implemente mallocy free. Y al cargar estos con LD_PRELOADsu mallocy freese ejecutará en lugar de los estándar.

Ronny Brendel
fuente
pero que pasa si el programa usa calloc? ¿No lo estropearía todo?
Janus Troelsen
77
@JanusTroelsen si la biblioteca que escribe no implementa una parte determinada, esa parte se cargaría desde la biblioteca original.
Woodrow Barlow
@JanusTroelsen, en otras palabras, LD_PRELOAD le permite especificar qué implementación de un símbolo específico se utiliza. Si la biblioteca precargada no exporta un símbolo, se encontrará en otro lugar.
sherrellbc
1
@JanusTroelsen: Resulta que mallocy gratis están específicamente diseñados en glibc para permitir esto y el stock calloclogra llamar a su importado malloc. No intente esto con ninguna otra función. No funcionará tan bien.
Joshua
30

Como muchas personas mencionaron, usar LD_PRELOADpara precargar la biblioteca. Por cierto, puede VERIFICAR si la configuración está disponible por lddcomando.

Ejemplo: suponga que necesita precargar el suyo 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)

Por lo tanto, configure su entorno de precarga:

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

Verifique su biblioteca nuevamente:

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

LD_PRELOADenumera las bibliotecas compartidas con funciones que anulan el conjunto estándar, tal como lo /etc/ld.so.preloadhace. Estos son implementados por el cargador /lib/ld-linux.so. Si desea anular solo algunas funciones seleccionadas, puede hacerlo creando un archivo de objeto y configurandoLD_PRELOAD ; las funciones en este archivo de objeto anularán solo aquellas funciones dejando a otras como estaban.

Para obtener más información sobre las bibliotecas compartidas, visite http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html

Rajesh
fuente
3

Aquí hay una publicación de blog detallada sobre la precarga:

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

asn
fuente
13
Gracias por publicar tu respuesta! Tenga en cuenta que debe publicar las partes esenciales de la respuesta aquí, en este sitio, o su publicación corre el riesgo de ser eliminada. Consulte las Preguntas frecuentes donde menciona respuestas que son "apenas más que un enlace". Aún puede incluir el enlace si lo desea, pero solo como una 'referencia'. La respuesta debe ser independiente sin necesidad del enlace.
Taryn
3

es fácil exportar mylib.soa env:

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

deshabilitar :

$ export LD_PRELOAD=
JulienGenoud
fuente
77
ounset LD_PRELOAD
Morten
2

cuando se utiliza LD_PRELOAD, ese archivo se cargará antes que cualquier otra $export LD_PRELOAD=/path/liblib para cargarse previamente, incluso esto también se puede usar en programas

Sumith Senarathne
fuente
1

Usando la LD_PRELOADruta, puede forzar al cargador de aplicaciones a cargar el objeto compartido proporcionado, por encima del valor predeterminado proporcionado.

Los desarrolladores usan esto para depurar sus aplicaciones al proporcionar diferentes versiones de los objetos compartidos.

Lo hemos usado para hackear ciertas aplicaciones, anulando las funciones existentes usando objetos compartidos preparados.

dnahc araknayirp
fuente