Подтвердить что ты не робот

Записать байт по адресу (hexedit/изменить двоичный файл из командной строки)

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

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

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

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

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

Есть идеи?

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

4b9b3361

Ответ 1

printf '\x31\xc0\xc3' | dd of=test_blob bs=1 seek=100 count=3 conv=notrunc 

аргументы dd:

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

Один Джош смотрит на другого;)

Ответ 2

Решения на основе 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) и dec (без префикса).

Ответ 3

Здесь 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

Ответ 4

Инструмент

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

Ответ 5

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

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 очень полезно, когда вам не нужна статистика из dd.

Ответ 6

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

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

Ответ 7

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

Ответ 8

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

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