Como escapar dados binários para inclusão no script bash

1

Eu quero criar um script bash que leia uma "carga útil" de dados binários de um arquivo externo e cuspa outro script básico com esses dados escapados e encapsulados dentro de uma variável de string. Exemplo:

  • mydata.bin - Os dados de origem: um arquivo de dados binários a ser encapsulado
  • myencoder.sh - O principal perpetrador: um script bash que converte os dados binários em um script com uma variável de string
  • mypayload.sh - O resultado final: um script bash gerado por myencoder.sh que contém os dados codificados como uma variável de string.

Para usar isso eu rodaria myscript.sh mydata.bin mypayload.sh e myscript.sh converteria / escape / wrap / qualquer que fosse o arquivo mydata.bin para mypayload.sh

Depois de executar este comando, o arquivo mypayload.sh seria algo como isto:

# Generated by myencoder.sh with data from mydata.bin
encoded_data="[...]ugly escaped string representation of the binary data found in mydata.bin[...]"

O problema que estou enfrentando é a maneira de resolver como os dados seriam codificados adequadamente. Eu li que printf "% q" poderia ser usado para escapar seqüências de caracteres, mas como invocá-lo em dados obtidos a partir de um arquivo binário externo me escapou completamente.

Então, por favor, qualquer facada neste e quaisquer dicas são bem vindas!

PS: Eu não quero introduzir nenhuma dependência fora do bash, se possível. Dependendo dos recursos do bash 4.x, tudo bem.

PPS: A codificação deve favorecer o tamanho pequeno e o desempenho de codificação / decodificação.

    
por Lennart Rolland 16.10.2015 / 14:08

3 respostas

1

É muito difícil lidar com zero bytes do bash. Você pode produzir um byte zero por

printf %c

mas você não pode armazená-lo em uma variável.

É muito mais fácil usar ferramentas externas:

xxd < mydata.bin > encoded
xxd -r < encoded > binary
    
por 16.10.2015 / 14:40
1

Esta não é uma solução completa para o seu problema; como outros mencionaram, lidar com NULLs em seu arquivo de entrada é difícil no bash, e tenho certeza que o potencial de arquivos de entrada unicode pode causar ainda mais dores de cabeça.

Mas eu dedico um pouco de tempo para pensar em como você pode usar printf %q no bash para fazer algo semelhante à sua sugestão e criou este rápido truque:

echo -n 'myvar="'
while read -r; do
  if [ ! -z "$REPLY" ]; then
    printf %q "$REPLY"
  fi
  echo -n '\n'
done
echo '"'

Tenho certeza de que poderia quebrar de muitas maneiras, mas talvez isso satisfaça alguma parte de sua curiosidade.

    
por 16.10.2015 / 15:56
0

Esta resposta não responde a pergunta diretamente, porque aparentemente conter 0 bytes nas variáveis bash não é possível e, aparentemente, não há como escapar delas em strings que podem ser mantidas com segurança dentro de variáveis bash sem depender de ferramentas externas como xxd ou uuencode que não estão disponíveis por padrão nas plataformas onde meu script será executado.

No entanto, esta foi a solução que acabei procurando porque resolveu meu problema mais próximo, ou seja, criar um script que contém dados binários arbitrários como uma carga útil que pode ser manipulada pelo próprio script que a contém.

Eu usei este artigo como minha fonte. Basicamente, a abordagem usa uma string separadora entre o script e os dados binários e nunca permite que o intérprete bash atinja a parte binária no final.

    
por 01.11.2015 / 01:45