Como você escreve bytes específicos em um arquivo?

6

Dado um arquivo myfile com o seguinte conteúdo:

$ cat myfile
foos

Um hexdump do arquivo nos fornece o conteúdo:

$ hexdump myfile
6f66 736f 000a

Atualmente, posso criar o arquivo especificando o conteúdo em ascii assim:

$ echo foos > myfile

É possível criar o arquivo dando-lhe os bytes exatos em hexadecimal em vez de ascii?

$ # How can I make this work?
$ echo --fake-hex-option "6f66 736f 000a" > myfile
$ cat myfile
foos

Atualização: para fins de clareza, redigi a pergunta para perguntar como escrever um pequeno número de bytes em um arquivo. Na verdade, eu preciso de uma maneira de canalizar uma grande quantidade de números hexadecimais diretamente para um arquivo, em vez de apenas 3 bytes:

$ cat hexfile
6f66 736f 6f66 736f ...
$ some_utility hexfile > myfile
$ cat myfile
foosfoosfoosfoos...
    
por Cory Klein 15.11.2012 / 00:30

5 respostas

6

Este é o script hexundump da minha coleção pessoal:

#!/usr/bin/env perl
$^W = 1;
$c = undef;
while (<>) {
    tr/0-9A-Fa-f//cd;
    if (defined $c) { warn "Consuming $c"; $_ = $c . $_; $c = undef; }
    if (length($_) & 1) { s/(.)$//; $c = $1; }
    print pack "H*", $_;
}
if (!eof) { die "$!"; }
if (defined $c) { warn "Odd number of hexadecimal digits"; }
    
por 15.11.2012 / 00:45
6

Você pode usar echo -e :

echo -e "\x66\x6f\x6f"

Observe que hexdump -C é o que você deseja despejar o conteúdo do arquivo na ordem de bytes, em vez de ser interpretado como palavras de 4 bytes na ordem de bytes da rede.

    
por 15.11.2012 / 00:36
3

Simule um trem de bytes:

echo 41 42 43 44 | 

Altere os espaços para novas linhas para que o while / read possa analisá-los facilmente em um

tr ' ' '\n' | 

Analisar byte por byte

while read hex; do

Converta hex para ascii:

  printf \x$hex

até o final da entrada

done

Se os arquivos a serem analisados forem muito grandes, você provavelmente não desejará usar o bash porque está lento. PERL, por exemplo, seria uma escolha melhor.

    
por 15.11.2012 / 08:55
1

A * some_utility * que você está descobrindo é dd ( manual ). Você pode copiar qualquer byte válido de qualquer posição válida de um arquivo para outro arquivo, especifique as opções bs (tamanho do bloco), count e skip .

Exemplo

Copie os primeiros 1024 bytes de um arquivo para outro arquivo.

$ dd if=liveusb-creator-3.11.7-setup.exe of=test.ex_ bs=1 count=1024
1024+0 records in
1024+0 records out
1024 bytes (1.0 kB) copied, 0.03922 s, 26.1 kB/s
    
por 15.11.2012 / 09:49
1

Veja um exemplo de como você pode usar dc to P rint o valor (UCHAR_MAX+1) de um byte:

printf %dP 104 101 121 32 116 104 101 114 101 10 |dc

... que imprime ...

hey there

A base padrão i nput é 10 - decimal - mas você pode configurá-la com $val i onde $val é qualquer número entre 2 e 16 (note que se a entrada atual não for 10 você Terá que usar o valor da base atual para 10 para recuperá-lo - senão você sempre pode fazer Ai ) .

Aqui está um exemplo mais complicado:

LC_ALL=C man man 2>/dev/null | 
od -v -An -t x1 |
tr -s '[:space:]' P | {
    echo 16i0
    tr '[:lower:]' '[:upper:]'
} | dc | head

... que traduz a saída de man man em hexadecimal e novamente em in-stream e imprime:

MAN(1)              Manual pager utils              MAN(1)



NAME
       man - an interface to the on-line reference manuals

SYNOPSIS
       man [-C file] [-d] [-D] [--warnings[=warnings]] [-R
       encoding] [-L locale] [-m system[,...]]  [-M  path]

Assegure-se de que todos os seus [:hexdigit:] s alfabéticos sejam maiúsculos e coloquem em sanduíche um P entre cada par, em seguida canalize-o em dc .

    
por 12.03.2015 / 21:52