How to use bash script to read binary file content?
I want to read a character and then a fixed length of string (the string is not null terminated in the file, and its length is given by the preceding character). How can I do this in a bash script? How to define the string variable so that I can do some post-processing on it?
5 Answers 5
If you want to stick with shell utilities, you can use head to extract a number of bytes, and od to convert a byte into a number.
export LC_ALL=C # make sure we aren't in a multibyte locale n=$(head -c 1 | od -An -t u1) string=$(head -c $n)
However, this does not work for binary data. There are two problems:
- Command substitution $(…) strips final newlines in the command output. There’s a fairly easy workaround: make sure the output ends in a character other than a newline, then strip that one character.
string=$(head -c $n; echo .); string=$
If you have binary data, you’ll want to switch to a language like Perl or Python.
If you want to be able to deal with binary file in shell, the best option (only?) is to work with hexdump tool.
hexdump -v -e '/1 "%u\n"' binary.file | while read c; do echo $c done
head -cX binary.file | hexdump -v -e '/1 "%u\n"' | while read c; do echo $c done
Read length (and work with 0 as length) and then «string» as byte decimal value:
len=$(head -c1 binary.file | hexdump -v -e '/1 "%u\n"') if [ $len -gt 0 ]; then tail -c+2 binary.file | head -c$len | hexdump -v -e '/1 "%u\n"' | while read c; do echo $c done fi
Rather than just present a bunch of commands, can you explain what they do and how they work? What do the options mean? What output can the user expect from your commands? Please do not respond in comments; edit your answer to make it clearer and more complete.
Well, I can copy manpages here, but I don’t see the point. There is only basic commands used here, the only trick is the usage of hexdump.
read -N stops at null bytes, so this is not a suitable way to work with binary data. In general, shells other than zsh can’t cope with nulls.
UPDATE (with hindsight). This question/answer (my answer) makes me think of the dog which keeps chasing the car.. One day, finally, he catches up to the car.. Okay, he caught it, but he really can’t do much with it. This anser ‘catches’ the strings, but then you can’t do much with them, if they have embedded null-bytes. (so a big +1 to Gilles answer.. another language may be in order here.)
dd reads any and all data. It certainly won’t baulk at zero as a «length». but if you have \x00 anywhere in your data, you will need to be creative how you handle it; dd has no propblems with it, but your shell script will have problems (but it depends on what you want to do with the data). The following basically outputs each «data string», to a file with a line divider between each strin.
btw: You say «character», and I assume you mean «byte».
but the word «character» has become ambiguous in these days of UNICODE, where only the 7-bit ASCII character-set uses a single byte per character. And even within the Unicode system, byte counts vary depending on the method of encoding characters, eg. UTF-8, UTF-16, etc.
Here is a simple script to highlight the difference between a Text «character» and bytes.
STRING="௵" echo "CHAR count is: $" echo "BYTE count is: $(echo -n $STRING|wc -c)" # CHAR count is: 1 # BYTE count is: 3 # UTF-8 ecnoded (on my system)
If your length character is 1-byte long and indicates a byte-length, then this script should do the trick, even if the data contains Unicode characters. dd only sees bytes regardless of any locale setting.
This script uses dd to read the binary file and outputs the strings seperated by a «=== =================================»; echo $div ((skip=0)) # read bytes at this offset while ( true ) ; do # Get the «length» byte ((count=1)) # count of bytes to read dd if=binfile bs=1 skip=$skip count=$count of=datalen 2>/dev/null (( $( strlen=$((0x$(/dev/null ddgetct=$( echo -e «\n$div» >>dataline # add a newline for TEST PURPOSES ONLY. cat dataline # ((skip=skip+count)) # read bytes from and including this offset done # echo
This script builds test data which includes a 3-byte prefix per line.
The prefix is a single UTF-8 encoded Unicode character.
# build test data # =============== prefix="௵" # prefix all non-zero length strings will this obvious 3-byte marker. prelen=$(echo -n $prefix|wc -c) printf \\0 > binfile # force 1st string to be zero-length (to check zero-length logic) ( lmax=3 # line max . the last on is set to 255-length (to check max-length logic) for ((i=1;i<=$lmax;i++)) ; do # add prefixed random length lines suflen=$(numrandom /0..$((255-prelen))/) # random length string (min of 3 bytes) ((i==lmax)) && ((suflen=255-prelen)) # make last line full length (255) strlen=$((prelen+suflen)) printf \\$((($strlen/64)*100+$strlen%64/8*10+$strlen%8))"$prefix" for ((j=0;j>binfile #
Лучшие HEX – редакторы для Linux
В этой статье мы рассмотрим топ лучших шестнадцатеричных редакторов для Linux. Но прежде чем мы начнем, давайте посмотрим на то, что на самом деле является hex-редактором.
Про Linux за 5 минут
Что такое Hex-редактор
Hex-редактор, или проще говоря, шестнадцатеричный редактор позволяет вам просматривать и редактировать двоичные файлы. Разница между обычным текстовым редактором и шестнадцатеричным редактором заключается в том, что обычный редактор представляет логическое содержимое файла, тогда как шестнадцатеричный редактор представляет физическое содержимое файла.
Кто использует Hex-редакторы
Шестнадцатеричные редакторы используются для редактирования отдельных байтов данных и в основном используются программистами или системными администраторами. Некоторые из наиболее распространенных случаев — это отладка или обратная инженерия (reverse engineering) двоичных протоколов связи. Конечно, есть много других вещей, которые вы можете использовать в шестнадцатеричных редакторах — например, просмотр файлов с неизвестным форматом файла, выполнение шестнадцатеричного сравнения, просмотр дампа памяти программы и другое. Большинство из упомянутых шестнадцатеричных редакторов доступны для установки из репозитория по умолчанию с помощью диспетчера пакетов вашего дистрибутива, например:
# yum install package [На CentOS] # dnf install package [На Fedora] # apt install package [На Debian/Ubuntu] # zypper install package [На OpenSuse] # pacman -Ss package [На Arch Linux]
Если пакет недоступен, перейдите на веб-сайт каждого инструмента, где вы сможете получить отдельный пакет для процедур загрузки и установки, а также подробную информацию о зависимостях.
Xxd Hex Editor
Большинство (если не все) дистрибутивов Linux поставляются с редактором, который позволяет выполнять шестнадцатеричные и двоичные манипуляции. Одним из таких инструментов является инструмент командной строки — xxd, наиболее часто используемый для создания шестнадцатеричного дампа данного файла или стандартного ввода. Он также может конвертировать шестнадцатеричный дамп обратно в исходную двоичную форму.
Hexedit Hex Editor
Hexedit — это еще один шестнадцатеричный редактор командной строки, который уже может быть предварительно установлен в вашей ОС. Hexedit показывает и шестнадцатеричное и ASCII представление файла одновременно.
Hexyl Hex Editor
Другой полезный инструмент для проверки двоичного файла — это hexyl, простой просмотрщик шестнадцатеричных данных для терминала Linux, который использует цветной вывод для определения различных категорий байтов. Его вид разделен на три колонки:
- Смещенный столбец, указывающий количество байтов в файле.
- Шестнадцатеричный столбец, который содержит шестнадцатеричное представление файла.
- Текстовое представление файла.
Установка этого шестнадцатеричного вьюера различна для разных операционных систем, поэтому рекомендуется проверить файл read-me в проекте, чтобы увидеть точные инструкции по установке для вашей ОС. Ссылка на GitHub.
Ghex — GNOME Hex Editor
Ghex — это графический шестнадцатеричный редактор, который позволяет пользователям редактировать двоичный файл как в шестнадцатеричном, так и в ASCII формате. Он имеет многоуровневый механизм отмены и повтора, который некоторые могут найти полезным. Еще одна полезная функция — функции поиска и замены, а также преобразование двоичных, восьмеричных, десятичных и шестнадцатеричных значений.
Bless Hex Editor
Одним из наиболее продвинутых шестнадцатеричных редакторов в этой статье является Bless, похожий на Ghex, он имеет графический интерфейс, который позволяет редактировать большие файлы данных с многоуровневым механизмом отмены/повторения. Он также имеет настраиваемые представления данных, функцию поиска-замены и многопоточные операции поиска и сохранения. Несколько файлов могут быть открыты одновременно с помощью вкладок. Функциональность также может быть расширена с помощью плагинов. Ссылка на GitHub.
Okteta Editor
Okteta — еще один простой редактор для просмотра файлов необработанных данных. Некоторые из основных особенностей октета включают в себя:
- Различные представления символов — традиционные в столбцах или в строках со значением верха символа.
- Редактирование аналогично текстовому редактору.
- Различные профили для просмотра данных.
- Несколько открытых файлов.
- Удаленные файлы по FTP или HTTP.
wxHexEditor
wxHexEditor — еще один из шестнадцатеричных редакторов Linux, обладающий некоторыми расширенными функциями.
whHexEditor предназначен в основном для больших файлов. Он работает быстрее с большими файлами, потому что он не пытается скопировать весь файл в вашу оперативную память. Он имеет низкое потребление памяти и может просматривать несколько файлов одновременно.
Hexcurse — Conx Hex Editor
Hexcurse — это шестнадцатеричный редактор на основе ncurses. Он может открывать, редактировать и сохранять файлы в дружественном терминальном интерфейсе, который позволяет перейти к определенной строке или выполнить поиск. Вы можете легко переключаться между шестнадцатеричными или десятичными адресами, или переключаться между шестнадцатеричными и ASCII-окнами.
Hexer Binary Editor
Hexer — еще один бинарный редактор командной строки. Его отличительная особенность заключается в том, что это Vi-подобный редактор стилей для бинарных файлов. Некоторые из наиболее заметных особенностей — много буферов, многоуровневая отмена, редактирование командной строки с завершением и двоичное регулярное выражение.
Emacs
Emacs является альтернативой текстовому редактору Vim и предоставляет функции редактирования в шестнадцатеричном формате. Простота и удобное переключение между режимами являются важнейшими особенностями Emacs
Заключение
Это был краткий обзор некоторых наиболее часто используемых шестнадцатеричных редакторов в Linux. Какие шестнадцатеричные редакторы вы используете и почему вы предпочитаете именно этот редактор? Что делает его лучше других?