CLI: запись байта по адресу (hexedit / изменение двоичного файла из командной строки) - PullRequest
37 голосов
/ 24 января 2011

Есть ли простой способ изменить двоичный файл из командной строки? Допустим, я знаю, что мой двоичный файл содержит 1234abcd, и я хочу изменить его на 12FFabcd или FFFFabcd или, может быть, даже FF34FFabc0 (вы поняли): -)

Как мне добиться этого без использования каких-либо специальных инструментов, таких как http://stahlworks.com/dev/swiss-file-knife.html или аналогичных.

Было бы здорово сделать это только из командной строки, используя только стандартные инструменты linux.

Или, может быть, даже лучше вместо поиска шестнадцатеричной строки, которую я хочу заменить, непосредственно записывая FF со смещением 0x10000, 12 со смещением 0x100001 и т. Д.

Есть идеи?

Заранее спасибо!

П.С .: Я должен добавить следующее:

Он должен быть сценарием и запускаться непосредственно из командной строки. Я ищу что-то вроде «двоичный файл, который включен в дистрибутив - пишите AB - смещение 100000 - файл thebinary.bin». Я совершенно уверен, что это возможно с «dd», но я не смог обернуть голову вокруг страницы руководства.

Ответы [ 8 ]

70 голосов
/ 07 апреля 2011
printf '\x31\xc0\xc3' | dd of=test_blob bs=1 seek=100 count=3 conv=notrunc 

аргументы дд:

  • из | файл для исправления
  • шс | 1 байт за раз, пожалуйста
  • искать | перейти в позицию 100 (десятичное число)
  • conv = notrunc | не обрезать вывод после редактирования (что по умолчанию выполняет dd)

Один Джош ищет другого;)

7 голосов
/ 30 декабря 2015

Решения на основе printf+dd, похоже, не работают для записи нулей. Вот общее решение в python3 (включено во все современные дистрибутивы), которое должно работать для всех байтовых значений ...

#!/usr/bin/env python3
#file: set-byte

import sys

fileName = sys.argv[1]
offset = int(sys.argv[2], 0)
byte = int(sys.argv[3], 0)

with open(fileName, "r+b") as fh:
    fh.seek(offset)
    fh.write(bytes([byte]))

Использование ...

set-byte eeprom_bad.bin 0x7D00 0
set-byte eeprom_bad.bin 1000 0xff

Примечание. Этот код может обрабатывать входные числа как в шестнадцатеричном (с префиксом 0x), так и в десятичном (без префикса).

6 голосов
/ 21 марта 2013

Вот функция Bash replaceByte, которая принимает следующие параметры:

  • имя файла,
  • смещение байта в файле для перезаписи и
  • новое значение байта (числа).
#!/bin/bash

# param 1: file
# param 2: offset
# param 3: value
function replaceByte() {
    printf "$(printf '\\x%02X' $3)" | dd of="$1" bs=1 seek=$2 count=1 conv=notrunc &> /dev/null
}

# Usage:
# replaceByte 'thefile' $offset 95
2 голосов
/ 10 февраля 2018

Запись одного и того же байта в двух разных позициях в одном и том же файле с одним вкладышем.

printf '\x00'| tee >(dd of=filename bs=1 count=1 seek=692 conv=notrunc status=none) \
    >(dd of=filename bs=1 count=1 seek=624 conv=notrunc status=none)

status = none очень полезно, когда вы не хотите получать статистику из дд.

2 голосов
/ 24 января 2011
Инструмент

xxd, который поставляется с vim (и, следовательно, вполне вероятно, будет доступен), позволяет выполнить шестнадцатеричный дамп двоичного файла и создать новый двоичный файл из модифицированного шестнадцатеричного дампа.

1 голос
/ 03 августа 2013

Некоторые альтернативы:

1 голос
/ 24 января 2011

Если вам не нужен сценарий, вы можете попробовать утилиту "hexedit". Он доступен во многих дистрибутивах Linux (если он не установлен по умолчанию, его обычно можно найти в репозитории пакетов дистрибутива).

Если в вашем дистрибутиве его нет, вы можете собрать и установить его из источника .

0 голосов
/ 04 июня 2019

Относительно ответа Джоша: Если вы хотите сделать это для определенного адреса

hexdump -C {file location}

с некоторым шестнадцатеричным значением, вы, возможно, попытались добавить 0x, но это не получится:

dd: warning: ‘0x’ is a zero multiplier; use ‘00x’ if that is intended

Этого можно добиться, заключив его в $ (()), который терминал переведет как значение типа int:

mybinary={file location}
printf '\x31\xc0\xc3' | dd of=$mybinary bs=1 seek=$((0x100)) count=3 conv=notrunc 
...