bash não pode armazenar hexvalue 0x00 na variável

11

Estou tentando fazer alguns truques com dd. Eu pensei que seria possível armazenar alguns valores hexadecimais em uma variável chamada "cabeçalho" para canalizar em dd.

Meu primeiro passo sem uma variável foi:

$ echo -ne "\x36\xc9\xda\x00\xb4" |dd of=hex
$ hd hex

00000000  36 c9 da 00 b4                                    |6....|
00000005

Depois disso eu tentei isso:

$ header=$(echo -ne "\x36\xc9\xda\x00\xb4") 
$ echo -n $header | hd

00000000  36 c9 da b4                                       |6...|
00000004

Como você pode ver, perdi meu valor \x00 na variável $header . Alguém tem uma explicação para esse comportamento? Isso está me deixando louco.

    
por Frank 24.02.2017 / 18:25

2 respostas

16

Você não pode armazenar um byte nulo em uma string porque o Bash usa strings no estilo C, que reservam o byte nulo para os terminadores. Então você precisa reescrever seu script para simplesmente canalizar a seqüência que contém o byte nulo sem que o Bash precise armazená-lo no meio. Por exemplo, você pode fazer isso:

printf "\x36\xc9\xda\x00\xb4" | hd

Observe, a propósito, que você não precisa de echo ; você pode usar o printf do Bash para isso, muitas outras tarefas simples.

Ou, em vez de encadear, você pode usar um arquivo temporário:

printf "\x36\xc9\xda\x00\xb4" > /tmp/mysequence
hd /tmp/mysequence

Claro, isso tem o problema de que o arquivo /tmp/mysequence já exista. E agora você precisa continuar criando arquivos temporários e salvando seus caminhos em strings.

Ou você pode evitar isso usando a substituição de processos:

hd <(printf "\x36\xc9\xda\x00\xb4")

O operador <(command) cria um canal nomeado no sistema de arquivos, que receberá a saída de command . hd receberá, como seu primeiro argumento, o caminho para aquele pipe - que será aberto e lido quase como qualquer arquivo. Você pode ler mais sobre isso aqui: link .

    
por 24.02.2017 / 19:31
8

Você pode usar zsh , que é o único shell que pode armazenar o caractere NUL em suas variáveis. Esse caractere também está no valor padrão de $IFS em zsh .

nul=$'
nul=$'\x0'
'

Ou:

nul=$'\u0000'

Ou

nul=$(printf '
echo $'
nul=$'
nul=$'\x0'
'
' # works /bin/echo $'
nul=$'\u0000'
' # doesn't
')

Ou

nul=$(printf '
echo $'%pre%' # works
/bin/echo $'%pre%' # doesn't
')

No entanto, note que você não pode passar uma variável como um argumento ou variável de ambiente para um comando executado como os argumentos e variáveis de ambiente são seqüências delimitadas por NUL passadas para o execve() chamada do sistema (uma limitação da API do sistema, não do shell). Em zsh , você pode, no entanto, passar bytes NUL como argumentos para funções ou comandos incorporados.

%pre%     
por 24.02.2017 / 19:38