Invocando um script com ld-linux.so?

Invocando um script com ld-linux.so?

Acabei de baixar um tararquivo que supostamente inclui tudo o que é necessário para executar um programa que podemos chamar de some_binary. Extraí seu conteúdo e vejo o seguinte:

  • Um binário (vamos chamá-lo some_binary)
  • Uma libpasta com várias bibliotecas dinâmicas (arquivos .so), como/lib/ld-linux-x86-64.so
  • e um script de shell chamadosome_binary.sh

O script possui o seguinte conteúdo:

#!/bin/bash
`dirname "$0"`/lib/ld-linux-x86-64.so.2   `dirname "$0"`/some_binary "$@"

e executá-lo como ./some_binary.sh some argumentsparece funcionar ./some_binarycorretamente. Curiosamente, executando o seguinte script:

#!/bin/bash
LD_LIBRARY_PATH=$CWD/LIB:$LD_LIBRARY_PATH
./some_binary "$@"

como ./my_script.sh some argumentsnão funciona. Isso resulta em erros de realocação (símbolos indefinidos), provavelmente devido ao carregamento incorreto das bibliotecas em./lib

Além disso, executar as duas instruções a seguir na linha de comando resulta em segmentation fault:

> LD_LIBRARY_PATH=$CWD/LIB:$LD_LIBRARY_PATH
> ./some_binary some arguments

Com isso, minhas perguntas são:

  1. O que o primeiro script faz?
  2. Por que obtenho resultados diferentes nessas três tentativas? e por que não posso simplesmente adicionar $pwd/libe LD_LIBRARY_PATHexecutar some_binarydiretamente?

Responder1

O programa vem com seu própriocarregador dinâmico. É muito raro que os programas precisem de seu próprio carregador dinâmico: normalmente o que está no seu sistema também funcionará. Isto pode ser necessário se o programa foi vinculado a uma biblioteca padrão diferente da GNU libc ou se foi vinculado a uma GNU libc compilada com configurações estranhas.

Pode ser suficiente informar ao carregador onde encontrar as bibliotecas preferidas do programa. Sua tentativa quase faz isso, mas não exatamente. Se LD_LIBRARY_PATHainda não estiver no ambiente, a atribuição LD_LIBRARY_PATH=$CWD/LIB:$LD_LIBRARY_PATHdefinirá apenas uma variável de shell, não uma variável de ambiente, para que o programa não veja nada. Além disso, $CWDgeralmente se expande para uma string vazia, provavelmente você quis dizer $PWDou melhor $(dirname "$0")(ou seja, o diretório que contém o script). Cuidado também com o fato de você ter usado libe LIBinconsistentemente em sua pergunta. Tentar

#!/bin/sh
export LD_LIBRARY_PATH="$(dirname "$0")/lib:$LD_LIBRARY_PATH"
exec "$(dirname "$0")/some_binary" "$@"

ou melhor, para evitar ter uma entrada vazia no final LD_LIBRARY_PATHse não tiver sido definida antes (isso pode ser ruim porque uma entrada vazia representa o diretório atual, embora no final do caminho só seja prejudicial se uma biblioteca estiver ' não encontrei onde deveria estar):

#!/bin/sh
export LD_LIBRARY_PATH="$(dirname "$0")/lib:$LD_LIBRARY_PATH"
case "$LD_LIBRARY_PATH" in *:) LD_LIBRARY_PATH=${LD_LIBRARY_PATH%:};; esac
exec "$(dirname "$0")/some_binary" "$@"

informação relacionada