¿Cómo podría usar Bash para encontrar 2 bytes en un archivo binario, aumentar sus valores y reemplazarlos?


8

Estoy tratando de encontrar dos bytes dentro del archivo binario, luego aumentar el valor de esos dos bytes y reemplazarlos dentro del archivo. Esos dos bytes están en las posiciones 0x82-0x83. Por ahora, he extraído con éxito esos dos bytes usando esto:

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

Estos bytes tienen un valor: 1B 1F. Estoy atrapado con:

  1. ¿Cómo convertir bytes a entero? Debería ser 6943decimal.
  2. Cómo agregar / hacer eco de datos binarios al archivo
  3. Cómo escribir bytes aumentados dentro del archivo en las posiciones 0x82-0x83. Podría usar head -c 130 original.bin >> new_file.bin && magic_command_writing_bytes_to_file >> new_file.bin && tail -c +133 original.bin, pero debe haber una mejor manera.

Podría hacer eso en PHP, debería ser más fácil, pero estoy interesado en cómo hacer esto en bash.

Respuestas:


5

Prueba con este archivo:

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

Entonces, en este caso, el 1B 1Festá en posición 12.

  • Convierte a entero (probablemente haya una manera más fácil)

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

    $ printf '%04X' 6943 | xxd -r -ps | hexdump -C
    00000000  1b 1f                                             |..|
    $ printf '%04X' 4242 | xxd -r -ps | hexdump -C
    00000000  10 92                                             |..|
    
  • Y poniéndolo de nuevo en el archivo:

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

Sí, es exactamente lo que estaba buscando. Gracias.
piotrekkr

@frostschutz: Hay un error, falta \x, en la línea dos de su código de ejemplo. Debería ser echo -n $'\x1b\x1f' >> test.txt.
erik

1
Convierte a entero (probablemente haya una manera más fácil) ¡Oh sí, la hay! :) erik eligió el mejor comando, así que solo adaptaré su línea a la tuya: printf "%d" 0x1B1Fhará el trabajo bien para obtener tu 6943resultado; a partir de eso, puede usar una línea significativamente más inteligente como en su printf "%d" $(xxd -u -ps -l 2 -s 12 test.txt)lugar y ya no la necesitará bc.
syntaxerror

2

Oh, lo siento. Esta respuesta es obsoleta, porque pensé que tenía valores hexadecimales escritos como ascii en su archivo.


Puede convertir los números hexadecimales al sistema decimal a través de printf "%d" 0x1B1F.

Si ha guardado los bytes en una variable BYTES=1B1F, obtendrá el resultado con printf "%d" 0x$BYTES.

Entonces, si quieres aumentar el número, haz

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

Luego conviértalo de nuevo

printf '%X' $(($(printf "%d" 0x$BYTES) +1))
1B20
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.