Como eu poderia usar o Bash para encontrar 2 bytes em um arquivo binário, aumentar seus valores e substituir?

8

Estou tentando encontrar dois bytes dentro do arquivo binário, aumente o valor desses dois bytes e os substitua dentro do arquivo. Esses dois bytes estão nas posições 0x82-0x83. Por enquanto, extraí com êxito esses dois bytes usando este:

#!/usr/bin/env bash
BYTES=$(tail -c +131 "$1" | head -c 2)

Esses bytes têm valor: 1B 1F. Estou preso com:

  1. Como converter bytes em número inteiro? Deve ser 6943decimal.
  2. Como acrescentar / ecoar dados binários no arquivo
  3. Como escrever bytes aumentados dentro do arquivo nas posições 0x82-0x83. Eu poderia usar head -c 130 original.bin >> new_file.bin && magic_command_writing_bytes_to_file >> new_file.bin && tail -c +133 original.bin, mas deve haver uma maneira melhor.

Eu poderia fazer isso no PHP, deveria ser mais fácil, mas estou interessado em fazer isso no bash.

piotrekkr
fonte

Respostas:

5

Testando com este arquivo:

$ echo hello world > test.txt
$ echo -n $'\x1b\x1f' >> test.txt
$ echo whatever >> test.txt
$ hexdump -C test.txt 
00000000  68 65 6c 6c 6f 20 77 6f  72 6c 64 0a 1b 1f 77 68  |hello world...wh|
00000010  61 74 65 76 65 72 0a                              |atever.|
$ grep -a -b --only-matching $'\x1b\x1f' test.txt 
12:

Então, neste caso, o 1B 1Festá na posição 12.

  • Converter em número inteiro (provavelmente existe uma maneira mais fácil)

    $ echo 'ibase=16; '`xxd -u -ps -l 2 -s 12 test.txt`  | bc
    6943
    
  • E o contrário:

    $ printf '%04X' 6943 | xxd -r -ps | hexdump -C
    00000000  1b 1f                                             |..|
    $ printf '%04X' 4242 | xxd -r -ps | hexdump -C
    00000000  10 92                                             |..|
    
  • E colocando de volta no arquivo:

    $ printf '%04X' 4242 | xxd -r -ps | dd of=test.txt bs=1 count=2 seek=12 conv=notrunc
    2+0 records in
    2+0 records out
    2 bytes (2 B) copied, 5.0241e-05 s, 39.8 kB/s
    
  • Resultado:

    $ hexdump -C test.txt
    00000000  68 65 6c 6c 6f 20 77 6f  72 6c 64 0a 10 92 77 68  |hello world...wh|
    00000010  61 74 65 76 65 72 0a                              |atever.|
    
frostschutz
fonte
Sim, é exatamente o que eu estava procurando. Obrigado.
Piotrekkr 30/08/2013
@frostschutz: Há um erro - ausente \x- na linha dois do seu código de exemplo. Deveria ser echo -n $'\x1b\x1f' >> test.txt.
quer
1
Converter em número inteiro (provavelmente existe uma maneira mais fácil) Ah, sim! :) erik escolheu o melhor comando, então vou adaptar a linha dele à sua: printf "%d" 0x1B1Ffará o trabalho muito bem para obter o 6943resultado; partindo disso, você pode usar uma linha significativamente mais inteligente printf "%d" $(xxd -u -ps -l 2 -s 12 test.txt)e não precisará bcmais.
Syntaxerror
2

Oh, desculpe. Esta resposta é obsoleta, porque pensei que você tivesse valores hexadecimais escritos como ascii em seu arquivo.


Você pode converter os números hexadecimais em sistema decimal via printf "%d" 0x1B1F.

Se você salvou os bytes em uma variável BYTES=1B1F, obtém o resultado com printf "%d" 0x$BYTES.

Então, se você quiser aumentar o número,

$ echo $(($(printf "%d" 0x$BYTES) +1))
6944

Depois converta

printf '%X' $(($(printf "%d" 0x$BYTES) +1))
1B20
erik
fonte