Comment pourrais-je utiliser Bash pour trouver 2 octets dans un fichier binaire, augmenter leurs valeurs et remplacer?

8

J'essaie de trouver deux octets à l'intérieur du fichier binaire, puis d'augmenter la valeur de ces deux octets et de les remplacer à l'intérieur du fichier. Ces deux octets sont sur les positions 0x82-0x83. Pour l'instant, j'ai réussi à extraire ces deux octets en utilisant ceci:

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

Ces octets ont une valeur: 1B 1F. Je suis coincé avec:

  1. Comment convertir des octets en entier? Il doit être 6943décimal.
  2. Comment ajouter / faire écho des données binaires dans un fichier
  3. Comment écrire des octets accrus à l'intérieur du fichier sur les positions 0x82-0x83. Je pourrais utiliser head -c 130 original.bin >> new_file.bin && magic_command_writing_bytes_to_file >> new_file.bin && tail -c +133 original.bin, mais il doit y avoir une meilleure façon.

Je pourrais faire ça en PHP, ça devrait être plus facile, mais je suis intéressé par comment faire ça en bash.

piotrekkr
la source

Réponses:

5

Test avec ce fichier:

$ 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:

Donc, dans ce cas, le 1B 1Fest en position 12.

  • Convertir en entier (il existe probablement un moyen plus simple)

    $ echo 'ibase=16; '`xxd -u -ps -l 2 -s 12 test.txt`  | bc
    6943
    
  • Et l'inverse:

    $ printf '%04X' 6943 | xxd -r -ps | hexdump -C
    00000000  1b 1f                                             |..|
    $ printf '%04X' 4242 | xxd -r -ps | hexdump -C
    00000000  10 92                                             |..|
    
  • Et le remettre dans le fichier:

    $ 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
    
  • Résultat:

    $ 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
la source
Oui, c'est exactement ce que je cherchais. Merci.
piotrekkr
@frostschutz: Il y a un bogue - un manquant \x- à la ligne deux de votre exemple de code. Ça devrait l'être echo -n $'\x1b\x1f' >> test.txt.
erik
1
Convertir en entier (il existe probablement un moyen plus simple) Oh oui, il y en a! :) erik a choisi la meilleure commande, donc je vais juste adapter sa ligne à la vôtre: printf "%d" 0x1B1Ffera le travail très bien pour obtenir votre 6943résultat; à partir de cela, vous pouvez utiliser une ligne beaucoup plus intelligente comme à la printf "%d" $(xxd -u -ps -l 2 -s 12 test.txt)place et vous n'en aurez plus besoin bc.
erreur de syntaxe
2

Oh pardon. Cette réponse est obsolète, car je pensais que vous avez des valeurs hexadécimales écrites en ascii dans votre fichier.


Vous pouvez convertir les nombres hexadécimaux en système décimal via printf "%d" 0x1B1F.

Si vous avez enregistré les octets dans une variable, BYTES=1B1Fvous obtenez le résultat avec printf "%d" 0x$BYTES.

Donc, si vous voulez augmenter le nombre,

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

Puis reconvertissez-le

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