Qual é o truque LD_PRELOAD?

341

Me deparei com uma referência a ele recentemente sobre proggit e (a partir de agora) não está explicada.

Eu suspeito que isso poderia ser ela, mas eu não sei ao certo.

Hank Gay
fonte
11
Não é realmente uma resposta, então não vou publicá-la como uma, mas ... Stephen Kell está usando LD_PRELOAD para sua biblioteca liballocs neste vídeo e, se você assistir os bits anteriores, poderá entender melhor como / por que. O liballocs parece estar sendo usado para que outras linguagens dinâmicas possam se comunicar. Essa palestra tem alguns detalhes internos explicados. youtu.be/LwicN2u6Dro?t=24m10s
Elijah Lynn

Respostas:

415

Se você definir LD_PRELOADo caminho de um objeto compartilhado, esse arquivo será carregado antes de qualquer outra biblioteca (incluindo o tempo de execução C libc.so). Portanto, para executar lscom sua malloc()implementação especial , faça o seguinte:

$ LD_PRELOAD=/path/to/my/malloc.so /bin/ls
JesperE
fonte
12
Eu não tinha idéia que isso existia ... parece que seria um vetor importante para ataques de segurança. Alguma idéia de como está protegido?
Rmeador
141
Ele está protegido pelo fato do carregador irá ignorar LD_PRELOAD se ruid = euid - Joshua
Joshua
18
@ Josué: o que são ruid e euid?
precisa
20
@ heinrich5991 IDs de usuário reais e eficazes: lst.de/~okir/blackhats/node23.html
gsingh2011
59
Uma coisa importante a ter em mente: você geralmente deseja especificar um caminho absoluto para LD_PRELOAD. O motivo é que, sendo uma variável de ambiente, é herdada por processos filhos - que podem ter um diretório de trabalho diferente do processo pai. Portanto, qualquer caminho relativo falharia em localizar a biblioteca para pré-carregar.
Frerich Raabe 10/09
49

Você pode substituir símbolos nas bibliotecas de estoque criando uma biblioteca com os mesmos símbolos e especificando a biblioteca em LD_PRELOAD.

Algumas pessoas o usam para especificar bibliotecas em locais fora do padrão, mas LD_LIBRARY_PATHsão melhores para esse fim.

Joshua
fonte
17
"Algumas pessoas usam para especificar bibliotecas em locais fora do padrão" ... Sério? Parece "Algumas pessoas usam errado"!
Tom
6
O LD_PRELOAD pode, em virtude da ordem de carga, interceptar caminhos codificados especificados pelo aplicativo.
10139 Joshua
11
Seria um mau uso pré-carregar uma versão diferente de uma biblioteca - desde que sejam compatíveis?
Z0r 26/11/2013
2
Eu já vi isso usado para carregar uma variante de depuração ou instrumentada ou para carregar uma biblioteca que faz algo completamente radicalmente diferente da biblioteca base, como se fosse emular algum outro sistema.
27713 Joshua
11
No caso em que as bibliotecas não são compiladas corretamente (costumava se deparar com isso com o mysql o tempo todo, havia um acoplamento fraco a um libmysql_client genérico que sobrescreve o link simbólico de uma versão mais antiga - dependendo da versão do perl usada, você deve especificar / force-o com LD_PRELOAD .. truque útil Se bem me lembro, o valgrind usa essa técnica para fornecer a capacidade de depuração de binários sem a necessidade de recompilar .. é bastante útil.
synthesizerpatel
37

Com LD_PRELOADvocê pode dar precedência às bibliotecas.

Por exemplo, você pode escrever uma biblioteca que implemente malloce free. E carregando-os com o LD_PRELOADseu malloce freeserá executado em vez dos padrões.

Ronny Brendel
fonte
mas e se o programa usar calloc? isso não estragaria tudo?
Janus Troelsen
7
@JanusTroelsen se a biblioteca que você escreve não implementa uma determinada parte, essa parte será carregada da biblioteca original.
Woodrow Barlow
@JanusTroelsen, em outras palavras, LD_PRELOAD permite especificar qual implementação de um símbolo específico será usada. Se a biblioteca pré-carregada não exportar um símbolo, ela será encontrada em outro local.
precisa saber é o seguinte
11
@JanusTroelsen: Acontece que malloce grátis são projetados especificamente na glibc para permitir que isso e o estoque callocconsigam ligar para o importado malloc. Não tente fazer isso com outras funções. Não vai funcionar tão bem.
27419 Joshua
30

Como muitas pessoas mencionaram, usando LD_PRELOADpara pré-carregar a biblioteca. BTW, você pode VERIFICAR se a configuração está disponível por lddcomando.

Exemplo: suponha que você precise pré-carregar o seu próprio 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)

Portanto, defina seu ambiente de pré-carregamento:

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

Verifique sua biblioteca novamente:

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

LD_PRELOADlista bibliotecas compartilhadas com funções que substituem o conjunto padrão, da mesma forma /etc/ld.so.preloadque. Estes são implementados pelo carregador /lib/ld-linux.so. Se você deseja substituir apenas algumas funções selecionadas, pode fazer isso criando um arquivo e uma configuração de objeto de substituição LD_PRELOAD; as funções neste arquivo de objeto substituirão apenas as funções deixando as outras como estavam.

Para obter mais informações sobre bibliotecas compartilhadas, visite http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html

Rajesh
fonte
3

Aqui está uma postagem detalhada do blog sobre pré-carregamento:

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

asn
fonte
13
Obrigado por postar sua resposta! Observe que você deve postar as partes essenciais da resposta aqui, neste site, ou sua postagem corre o risco de ser excluída. Consulte as Perguntas frequentes, onde ele menciona respostas que são 'pouco mais que um link'. Você ainda pode incluir o link, se desejar, mas apenas como uma 'referência'. A resposta deve ser independente, sem a necessidade do link.
Taryn
3

é fácil exportar mylib.sopara env:

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

desabilitar :

$ export LD_PRELOAD=
JulienGenoud
fonte
7
ouunset LD_PRELOAD
Morten
2

Quando LD_PRELOAD é usado, esse arquivo será carregado antes de qualquer outra $export LD_PRELOAD=/path/liblib ser pré-carregada, mesmo que isso também possa ser usado em programas

Sumith Senarathne
fonte
1

Usando o LD_PRELOADcaminho, você pode forçar o carregador de aplicativos a carregar o objeto compartilhado fornecido, sobre o padrão fornecido.

Os desenvolvedores usam isso para depurar seus aplicativos, fornecendo versões diferentes dos objetos compartilhados.

Nós o usamos para hackear certos aplicativos, substituindo funções existentes usando objetos compartilhados preparados.

dnahc araknayirp
fonte