Autogenerated documentation with DeepWiki
Minimalistic and lightweight shell-based hex editor. It’s designed to have a low memory footprint, making it usable on very low-end devices.
- Print file content in various formats.
- Write/overwrite data into the file.
- Undo writes until committed.
- Enumerate (ASCII) strings.
- Search strings or binary data.
- Calculate hashes, checksums, and CRCs.
- Execute template files using a custom language (bhe), see examples in the
templates/subdirectory. - Disassemble opcodes (using Capstone).
- Assemble opcodes (using Keystone).
Just run bhex <file> to start the shell.
Supported flags:
Usage: bhex [ options ] inputfile
-h --help Print help
-w --write Open the file in write mode
-b --backup Backup original file in "filename.bk"
-2 --no_warning Disable warnings
-n --no_history Do not save command history
-c "c1; c2; ..." Execute the commands given as argument and exit
-s --script Script mode (commands from raw stdin)
command history is saved in "$HOME/.bhex_history", it can be changed by setting the BHEX_HISTORY_FILE environment variable
The project can be compiled using cmake. Without Capstone and Keystone, it has no runtime dependencies (apart from libc), so it should be quite straightforward:
$ mkdir build
$ cd build
$ cmake ..
$ make
To enable the disassembler command, use "-DENABLE_CAPSTONE=on".
To enable the assembler command, use "-DENABLE_KEYSTONE=on".
To enable an ASAN build, use "-DASAN=on -DCMAKE_BUILD_TYPE=Debug".
To enable tests, use "-DENABLE_TESTS=on".
Every command has the following structure:
$ command_name/mod1/mod2/mod3/... arg1 arg2 ...
where the modifiers (e.g., mod1) are optional parameters of the command.
The documentation for each command can be accessed by typing "?" after the name of the command.
If you type "help" (or "h"), you get the list of commands:
[0x0000000] $ h
Available commands:
help [h]
info [i]
interactive [int]
entropy [e]
search [src]
hash [hh]
checksum [cs]
crc [cr]
strings [str]
template [t]
seek [s]
print [p]
diff [df]
export [ex]
import [im]
assemble [as]
disas [ds]
write [w]
delete [d]
undo [u]
commit [c]
[0x0000000] $ i?
info: prints information about the opened binary
[0x0000000] $ e?
entropy: display an entropy graph
e [<rows> <len>]
rows: number of points in the graph (if omitted or '-', auto mode)
len: number of bytes to include starting from the current offset (if omitted, use the whole file)
[0x0000000] $ e - 8
[ 00000000 - 000277c8 ] (5.980) ---------------------------------+
[ 000277c8 - 0004ef90 ] (6.398) -----------------------------------+
[ 0004ef90 - 00076758 ] (6.492) ------------------------------------+
[ 00076758 - 0009df20 ] (4.491) -------------------------+
[ 0009df20 - 000c56e8 ] (6.441) ------------------------------------+
[ 000c56e8 - 000eceb0 ] (6.477) ------------------------------------+
[ 000eceb0 - 00114678 ] (6.495) ------------------------------------+
[ 00114678 - 0013be40 ] (4.388) ------------------------+
Start an interactive session.
[0x0000000] $ src?
search: search a string or a sequence of bytes in the file
src[/{x, s}/sk/p] <what>
x: data is a hex string
s: data is a string (default)
sk: seek to first match
c: print context
what: either a string or an hex string
[0x0000000] $ str?
enumerate the strings in the file (i.e., sequences of printable ascii characters with 8 or 16 bits)
str[/n/{a,w}] [ <pattern> <num> ]
n: look for null-terminated strings
a: 8-bit only
w: 16-bit only
pattern: print only strings that contain the pattern as substring (use * for any character)
num: minimum length (default: 3)
[0x0000000] $ hh?
hash: calculate the hash of <size> bytes at current offset + <off>
hash /l <algorithm> [ <size> <off> ]
l: list the supported hashing algorithms
algorithm: hashing algorithm (or '*' to use all supported algorithms)
size: number of bytes to include in the hash (if omitted or zero, hash the whole file starting from current offset)
off: starting offset wrt to current offset (default 0)
[0x0000000] $ hh/l
md2
md4
md5
md6-128
md6-256
md6-384
md6-512
sm3
sha1
sha224
sha256
sha384
sha512
sha3-128
sha3-224
sha3-256
sha3-384
sha3-512
RipeMD-128
RipeMD-160
RipeMD-256
RipeMD-320
blake2s
blake2b
ghost
[0x0000000] $ t?
template: parse the file at current offset using a 'bhe' template file
t[/l/i/x] <name or file>
l: list available templates and structs
x: output in XML
i: interpret inline code
arg: its meaning depends on the mode. It could be
- the name of the pre-loaded template/struct/proc to use
- a path to a template file
- a filter (if in list mode)
- inline bhex code (if in interpret mode)
[0x0000000] $ t/l
Available templates:
squashfs
zip
tar
jpeg
elf
gzip
lzo
png
pe
rpm
...
[0x0000000] $ s?
seek: change current offset
s[/{+,-}] <off>
+: sum 'off' to current offset (wrap if greater than filesize)
-: subtract 'off' from current offset (wrap if lower than zero)
off: can be either a number or the character '-'.
In the latter case seek to the offset before the last seek.
NOTE: if called without arguments, print current offset
[0x0000000] $ crc?
import: calculate the CRC <name> at current offset + <off>
crc[/l] <name> [<size> <off>]
l: list the supported crc names
name: name of the CRC (or a partial name, or '*')
size: number of bytes to include in the crc (if omitted or zero, import the whole file starting from current offset)
offset: starting offset of the imported file (if omitted, import from current offset)
[0x0000000] $ cs?
checksum: calculate a checksum at current offset + <off>
checksum [/l] <name> [<size> <off>]
l: list the supported checksum names
name: name of the checksum (or a partial name, or '*')
size: number of bytes to include (if omitted or zero, use the whole file starting from current offset)
offset: starting offset (if omitted, use current offset)
[0x0000000] $ as?
assemble: assemble code and write it at current offset
as[/l/i/s] <arch> "<code>"
l: list supported architectures
i: insert instead of overwrite
s: seek to the end of the write
arch: the architecture to use
code: assembly code string (e.g., "inc eax; inc ecx; ret")
[0x0000000] $ ds?
disas: disassemble code at current offset
ds[/l/i] [<arch>] [<nbytes>]
l: list supported architectures
i: identify architecture; optional nbytes limits the scan to
that many bytes from the current offset (default: whole file)
arch: the architecture to use
nbytes: number of opcodes to disassemble (default: 8)
[0x0000000] $ p?
print: display the data at current offset in various formats
p[/{x,w,d,q,a,C}/{le,be}/r/W/{+,-}] <nelements>
x: hex output (default)
w: words
d: dwords
q: qwords
a: as ascii
C: as C buffer
le: little-endian (default)
be: big-endian
r: raw mode (no ascii, no header and no addresses)
W: wide mode (print 32 bytes per line)
+: seek forward after printing
-: seek backwards after printing
nelements: the number of elements to display
(default: enough to display 256 bytes, if '-' the whole file)
[0x0000000] $ df?
diff: prints the differences with another file
df[/p/w] <file>
p: print different bytes
w: wide print (rows are 16 bytes)
file: path to the file to compare
[0x0000000] $ ex?
export: write <size> bytes of the file starting from current offset to <ofile>
ex <ofile> [<size>]
ofile: output file
size: number of bytes to export (if omitted, all the remaining bytes)
[0x0000000] $ im?
import: import the content of <file> at current offset
im[/{ovw,i}] <file> [<size> <offset>]
i: insert in current file (default)
ovw: overwrite current file
file: input file
size: number of bytes to import (if omitted or zero, import the whole file)
offset: starting offset of the imported file (if omitted, import from offset 0)
[0x0000000] $ w?
write: write data at current offset
w[{s,x,b,w,d,q}/{le,be}/u/i] <data>
s: string input (default)
x: hex input
b: byte
w: word
d: dword
q: qword
le: little-endian (default)
be: big-endian
u: unsigned
i: insert
data: the data to write. The format depends on the type of
write. Here are some examples:
w/x "00 01 02 03"
w/s "a string"
w/q/be 0x1234
[0x0000000] $ d?
delete: delete bytes at current offset (all remaining bytes if the argument is omitted)
d [<nbytes>]
[0x0000000] $ u?
undo: undo the last write
u[/a]
a: undo all
[0x0000000] $ c?
commit: commit all writes to file
c[/l]
l: list uncommitted changes