Hexdump reverse command
Asked Answered
K

8

24

The hexdump command converts any file to hex values.

But what if I have hex values and I want to reverse the process, is this possible?

Kiangsu answered 1/5, 2017 at 18:14 Comment(0)
U
28

There is a similar tool called xxd. If you run xxd with just a file name it dumps the data in a fairly standard hex dump format:

# xxd bdata
0000000: 0001 0203 0405
......

Now if you pipe the output back to xxd with the -r option and redirect that to a new file, you can convert the hex dump back to binary:

# xxd bdata | xxd -r >bdata2
# cmp bdata bdata2
# xxd bdata2
0000000: 0001 0203 0405
Uchida answered 1/5, 2017 at 18:24 Comment(2)
Conveniently, xxd -r also accepts hexdump output as input.Explosion
What do I do if I have a file which isn't formatted with things like colons, spaces, and newlines, and is just a stream matching [0-9A-F]* until the end of the file?Reunionist
S
7

Restore file, given only the output of hexdump file

If you only have the output of hexdump file and want to restore the original file, first note that hexdump's default output depends on the endianness of the system you ran hexdump on!

If you have access to the system that created the dump, you can determinate its endianness using below command:

[[ "$(printf '\01\03' | hexdump)" == *0103* ]] && echo big || echo little

Reversing little-endian hexdump

This is the most common case. All x86/x64 systems are little-endian. If you don't know the endianness of the system that ran hexdump file, try this.

sed 's/ \(..\)\(..\)/ \2\1/g;$d' dump | xxd -r

The sed part converts hexdump's format into xxd's format, at least so far that xxd -r works.

Reversing big-endian hexdump

sed '$d' dump | xxd -r

Known Bugs (see comment section)

  • A trailing null byte is added if the original file was of odd length (e.g. 1, 3, 5, 7, ..., byte long).
  • Repeating sections of the original file are not restored correctly if they were hexdumped using a *.

You can check your dump for above problematic cases by running below command:

grep -qE '^\*|^[0-9a-f]*[13579bdf] *$' dump && echo bug || echo ok

Better alternative to create hexdumps in the first place

Besides the non-posix (and therefore not so portable) xxd there is od (octal dump) which should be available on all unix-like systems as it is specified by posix:

od -tx1 -An -v

Will print a hexadecimal dump, grouping digits as single bytes (-tx1), with no Address prefixes (-An, similar to xxd -p) and without abbreviating repeated sections as * (-v). You can reverse such a dump using xxd -r -p.

Salpa answered 16/10, 2018 at 11:5 Comment(7)
This wasn't necessary for me (MacOS Mojave)Explosion
Does not work if the last line ends with 0A, because it's replaced by 0A00.Swish
@Swish Thank you for this observation! You are right: This command produces a trailing null byte which wasn't in the original file if the length in bytes was an odd number. I also found another bug. hexdump may hide repeated parts using a *. This command also cannot restore these parts correctly. Example: yes | head -n100 | hexdump | sed -E 's/ /: /;s/ (..)(..)/ \2\1/g' | xxd -r prints only 8 y instead of 100. Fixing these things would require more than this one-liner. Maybe I add another script in the future.Salpa
You can avoid the * bug if you run hexdump with the -v option.Geordie
Or you can specify the hexdump format so you can just use xxd -p -r mydump: hexdump -ve '1/1 "%.2x"' mybinaryfile > mydumpWickliffe
@Wickliffe For me, the whole point of the question was to reverse a hexdump for which you do not have the binary file. In that case, dumping in another format is not possible. Either way, I'll have to update this answer, as some people claimed xdd -r to work on the default output of hexdump all by itself.Salpa
Keep in mind that people with the obvious use case will stumble upon this question and its answers too: those who have the binary file, but no other way to transfer it than telnet or serial access to a console where it is located - so no need to update it. Also, Google already has it indexed for searches about reversing hexdump :-0Wickliffe
C
6

I've written a short AWK script which reverses hexdump -C output back to the original data. Use like this:

reverse-hexdump.sh hex.txt > data

Handles '*' repeat markers and generating original data even if binary. hexdump -C and reverse-hexdump.sh make a data round-trip pair. It is available here:

Carchemish answered 29/7, 2020 at 23:7 Comment(2)
@Zibri Yes my script does handle * repeat markers hexdump -C produces without the -v option. The example in the README shows it working. There are 5 unit test cases confirming this. If you really have a case where this doesn't work please raise an issue in the github repo.Carchemish
My bad.. good work.. I noticed 5 minute after and I forgot to remove the comment.Szabadka
D
3

As someone who sucks at bash, I could not understand the examples already posted. Here is what would have helped me when I was originally searching:

Take your text file "AYE.TXT" and convert it into a hex dump called "BEE.TXT"

xxd -p "AYE.TXT" > "BEE.TXT"

Take your hex dump file ("BEE.TXT") and covert it back to ascii file "CEE.TXT"

xxd -r -p "BEE.TXT" > "CEE.TXT"

Now that you have some simple working code, feel free to check out "xxd -help" on the command line for an explanation of what all those flags do. (That part is the easy part, the hard part is the specifics of the bash syntax)

Deify answered 8/5, 2021 at 14:41 Comment(1)
From man xxd: Use the combination -r -p to read plain hexadecimal dumps without line number information and without a particular column layout. Thank you @Deify that was the quick working answer!Jarboe
W
1

If you don't have xxd, use hexdump, od, perl or python:

The following all give the same output:

# If you only have hexdump
hexdump -ve '1/1 "%.2x"' mybinaryfile > mydump

# This gives exactly the same output as:
xxd -p mybinaryfile > mydump

# Or, much slower:
od -v -t x1 -An < mybinaryfile | tr -d "\n " > mydump 

# Or, the fastest:
perl -pe 'BEGIN{$/=\1e6} $_=unpack "H*"' < mybinaryfile > mydump

# Or, if you somehow have Python, and not Perl:
python -c "print(open('mybinaryfile','rb').read().hex())" > mydump

Then you can copy and paste, or pipe the output, and convert back with:

xxd -r -p mydump mybinaryfileagain

# Or
xxd -r -p < mydump > mybinaryfileagain

The hexdump command is available almost everywhere, and is usually part of the default busybox - if it's not linked, you can try running busybox hexdump or busybox xxd.

If xxd is not available to reverse the data, then you can try awk

The old days: Zmodem

In the old days we used to use X/Y/Zmodem which is available in the package lrzsz which can tolerate lossy comms - but it's a bidirectional protocol so the binaries need to be running at the same time and there needs to be bidirectional comms:

# Demo on local machine, using FIFOs
mkfifo /tmp/fifo-in
mkfifo /tmp/fifo-out
sz -b mybinaryfile > /tmp/fifo-out < /tmp/fifo-in
mkdir out; cd out
rz -b < /tmp/fifo-out > /tmp/fifo-in

Luckily, screen supports receiving Zmodem, so if you're in a screen session:

screen
telnet somehost

Then type Ctrl+A and : and then zmodem catch and Enter. Then inside the screen on the remote host, issue:

# sz -b mybinaryfile

Press Enter when you see the string starting with "!!!".

When you see "Transfer Complete", you may want to run reset if you want to continue the terminal session normally.

Wickliffe answered 3/11, 2021 at 9:17 Comment(0)
M
0

There is a tonne of more elegant ways to get this done, but I've quickly hacked something together that Works for Me (tm) when regenerating a binary file from a hex dump generated by hexdump -C some_file.bin:

sed 's/\(.\{8\}\)  \(..\) \(..\) \(..\) \(..\) \(..\) \(..\) \(..\) \(..\)/\1: \2\3 \4\5 \6\7 \8\9/g' some_file.hexdump | sed 's/\(.*\)  \(..\) \(..\) \(..\) \(..\) \(..\) \(..\) \(..\) \(..\)  |/\1 \2\3 \4\5 \6\7 \8\9  /g' | sed 's/.$//g' | xxd -r > some_file.restored

Basically, uses 2 sed processeses, each handling it's part of each line. Ugly, but someone might find it useful.

Mccartney answered 9/12, 2020 at 12:36 Comment(0)
S
0

This program reverses hexdump -C output back to the original data.

Usage:

make
make test
./unhexdump -i inputfile -o outputfile

see https://github.com/zhouzq-thu/unhexdump!

Skimmer answered 16/6, 2022 at 0:50 Comment(0)
S
0

i found more simple solution:

bin2hex

echo -n "abc" | hexdump -ve '1/1 "%02x"'

hex2bin

echo -n "616263" | grep -Eo ".{2}" | sed 's/\(.*\)/\\x\1/' | tr -d '\n' | xargs -0 echo -ne

Susian answered 7/1, 2023 at 4:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.