BinView
A hex editor for VS Code that understands raw binaries and Intel HEX, with a
side panel that stacks a whole-file image map over a data inspector.
Features
Hex editor
- Address, hex octet and text columns, with column grouping and 4–64 bytes per row.
- Text column can render ASCII, Latin-1 or CP437 (the classic DOS glyph set).
- Edit directly in either column: type hex digits over the octets, or type
characters over the text. Both write through VS Code's normal dirty/save/undo
machinery (
Ctrl+Z, Ctrl+S, revert and hot-exit all work).
- Paste hex (
DE AD BE EF, 0xDE,0xAD) or text; copy the selection as hex, a C
array, base64 or text.
- Find with a widget modelled on the editor's own:
Ctrl+F, live match counting
(3 of 17), every match highlighted, Enter / Shift+Enter to step and wrap,
Escape or a click outside to close. A query is read both ways at once - dead finds the bytes
DE AD and the word "dead" - and text matching ignores case. Aa demands an
exact case match, 0x drops the text reading, and opening find with a short
selection seeds it as a byte search. Hover the match count to see the split
("2 as bytes, 1 as text").
- Go to an offset (
Ctrl+G), select with mouse or keyboard.
- Hand the selection to CyberChef in one click, from the chef-hat button at
the right of the toolbar (see below).
Editing is overwrite only — the file never changes length, which is what you
want for firmware images and fixed layouts.
Intel HEX
.hex / .ihex / .ihx / .mcs / .h86 files (and any file whose first bytes
look like Intel HEX records) are parsed into address-tagged regions:
- Real addresses in the address column, including extended linear/segment addressing.
- Unmapped space between regions is drawn as a
gap of N bytes separator rather
than silently concatenated.
- Checksums are verified on load; a bad record is reported instead of being guessed at.
- Saving rewrites the records, preserving the record length, line endings and start
address record of the original file, and never straddling a 64 KiB page boundary.
Hiding unwritten space
Firmware images are mostly erased flash. Toggle Hide fill rows in the
Config menu (or
BinView: Toggle Hiding of Fill Rows) and every run of two or more identical rows
collapses into a single ⋯ 1,234 rows of 0xFF hidden ⋯ marker.
Any repeated byte counts, and each run is labelled with its own value, so a file
padded with 0x00 in one place and erased to 0xFF in another collapses both
without being told which is which. A lone fill row is left visible - it takes a
run to be worth hiding - and binview.fillRunMinRows sets how long a run has to
be (default 2).
Click a marker to expand that one run. Jumping to an address or finding a match
inside hidden space turns the filter off so you can see where you landed. Rows are
re-evaluated when you toggle the filter, not while you type, so the row under your
cursor never disappears mid-edit.
Data inspector
The lower pane decodes the bytes at the cursor: int/uint 8–64, float32/float64 in
both endiannesses, binary, octal, character, the UTF-8 sequence, and the address.
The eight bit buttons toggle bits in place — clicking one is an edit.
File map
The upper pane of the side panel renders the whole file as an image and follows
the cursor. Click anywhere on it to jump the editor there. Modes:
| Mode |
What one pixel shows |
| Byte value |
Grayscale byte value — instantly separates code, text and padding |
| Entropy |
Shannon entropy of a window around the byte — compressed/encrypted regions glow |
| Byte class |
Null / printable ASCII / control / high byte |
| Value heat map |
Byte value through a colour ramp |
| Bigram plot |
256×256 dot plot of consecutive byte pairs — a fingerprint of the file's structure |
Hovering reads out the offset and the value under the pointer, phrased for the
mode: 0x0004C0 · 0x7F (127) for byte value, · entropy 0.853 for entropy,
· ascii for byte class, and 0x41 → 0x42 · 1,024 pairs for the bigram plot. The
? button explains what each mode shows.
Entropy is normalised to 0-1 (1 being the full 8 bits per byte), the way binary
analysis tools plot it. In entropy mode a Cut slider sets a threshold on that
scale: left at zero the map is the usual continuous ramp; move it and the map goes
two-tone - at or above the cut in yellow, below it in dark - which makes the
boundary of a compressed or encrypted region obvious. The hover readout keeps
reporting the real value either way.
Ctrl+scroll (or a pinch gesture) over the map changes how wide the image is
drawn, trading detail against coverage. Large files are folded so several bytes
share a pixel - the note under the image says how many - and the image is fitted
to the height the pane actually has. The current selection is boxed on the image.
Commands
| Command |
Default key |
BinView: Open with BinView Hex Editor |
— (also in the explorer context menu) |
BinView: Toggle File Map in Side Panel |
— (also File map in the editor's Config menu) |
BinView: Set File Map Mode... |
— |
BinView: Find in Binary |
Ctrl+F (handled in the editor itself) |
BinView: Go to Offset... |
Ctrl+G |
BinView: Toggle Data Inspector |
— |
BinView: Toggle Hiding of Fill Rows |
— |
BinView: Copy Selection As... |
— |
BinView: Open Selection in CyberChef |
— (also the chef-hat button in the editor toolbar) |
BinView: Copy CyberChef Link for Selection |
— |
BinView: Set Bytes Per Row... |
— |
Inside the grid: arrows/PageUp/PageDown/Home/End move, Shift extends the
selection, Tab switches between the hex and text columns, Ctrl+A selects all,
Delete zeroes the selection, Backspace steps back.
With a range selected, an unshifted arrow slides the whole selection instead
of collapsing it: left/right by the selection's own size, up/down by one row
(same columns, next row). So selecting a 4-byte field and holding Down walks
that field through a table of records, and holding Right walks it through
consecutive fields. The inspector always decodes from the first selected
byte, so extending a range never changes what it shows.
Settings
| Setting |
Default |
Meaning |
binview.bytesPerRow |
16 |
Bytes per row |
binview.uppercaseHex |
true |
Hex digit case |
binview.showInspector |
true |
Show the inspector pane |
binview.inspectorEndianness |
little |
Byte order used by the inspector |
binview.showFileMap |
true |
Show the file map pane |
binview.sidePanelSplit |
0.45 |
Share of the side panel height given to the map |
binview.asciiEncoding |
ascii |
ascii, latin1 or cp437 |
binview.columnGroupSize |
8 |
Wide gap every N hex columns |
binview.columnSubGroupSize |
4 |
Narrow gap every N hex columns |
binview.skipFillRows |
false |
Collapse runs of identical rows |
binview.fillRunMinRows |
2 |
Rows a run needs before it collapses |
binview.maxFileSize |
268435456 |
Refuse to open files larger than this |
binview.cyberChef.url |
gchq.github.io |
CyberChef instance to open |
binview.cyberChef.recipe |
From_Hex('Auto') |
Recipe prefilled with the input |
binview.cyberChef.maxBytes |
8192 |
Most bytes to put in a CyberChef link |
binview.fileMap.mode |
value |
Default file map mode |
binview.fileMap.width |
256 |
File map width in pixels (Ctrl+scroll on the map) |
binview.fileMap.entropyThreshold |
0 |
Entropy cut, 0-1; 0 keeps the ramp |
binview.fileMap.entropyWindow |
256 |
Entropy window in bytes |
binview.intelHex.bytesPerRecord |
0 |
Data bytes per record when saving (0 = keep the file's own) |
binview.intelHex.eol |
auto |
Line endings when saving Intel HEX |
Developing
npm install
npm run build # bundle into dist/
npm run watch # rebuild on change
npm test # format, render and webview (jsdom) tests
npm run package # produce a .vsix
Press F5 in VS Code to launch an Extension Development Host (or install the
packaged build with code --install-extension binview-0.1.0.vsix), then open
examples/sample.bin (firmware-shaped: header, code, padding, strings, erased
flash) or examples/sample.hex (two regions 256 KiB apart). Regenerate them with
node examples/make-samples.mjs.
Layout
| Path |
What lives there |
src/ihex.ts |
Intel HEX parser and serializer |
src/binDocument.ts |
Document model: regions, edits, undo, save, backup |
src/hexEditorProvider.ts |
Custom editor, webview messaging |
src/render.ts |
Image modes (value, entropy, class, heat, bigram) |
src/cyberchef.ts |
Builds CyberChef deep links |
src/editorHtml.ts |
Editor markup, shared with the tests |
media/editor.js |
The hex grid: layout, navigation, editing, find, inspector, side panel |
media/filemap.js |
The file map widget in the side panel |
media/icon.svg |
Source for the extension icon (icon.png is generated from it) |
Known limits
- Editing is overwrite only: no insert or delete.
- Intel HEX editing changes bytes inside existing records; it cannot add addresses
that the file does not already map.
- Matches for search do not span a gap between two Intel HEX regions.
License
MIT