back

Introducing hevi: a hex viewer

zig   July 04, 2024

Almost a year ago, I started writing hevi. Today, hevi 1.0.0 was released. Following the release, I decided I would write a blog post about it. I'll address the following:

Why another tool

xxd, hexdump, hexyl... There's a lot of tools like hevi out there. However, I feel like none of them is good enough. Most of them either are really old pieces of software or don't offer many essential features.

For instance, xxd (bundled with vim) and hexdump are really old and primitive tools. Sure, they get the job done most of the times, but they're not pleasant to use by any means (obscure flags, long manpages...). hexyl on the other hand is a modern hex viewer... that offers little to no features.

I won't talk about GUI tools, as I think those are in a completely different context.

Bringing a new tool to the ecosystem is often viewed as a bad idea. But when all the other alternatives don't cut it, creating a new one does make sense.

What makes a tool good?

We've just decided that we need a new hex viewer. What do we do now? Start writing a tool that will be as bad as the ones that are already out there? No. We think frist.

Semantic flags

For a CLI program, the main way the user will interact with it is, well, the CLI. If a program has obscure flags that the user has to remember, it can be very harmful to the entire experiece. hevi does not have single-character flags. The only exceptions are -h and -v, which are well-known and widespread (but even those have semantic alternatives, --help and --version).

Sure, we could add shorthards for certain flags (e.g. -c for --color), but that would only encourage bad habits. By not having those, we push users towards a more semantic usage.

If your program needs to have single-character flags in order to provide a concise and short CLI usage, maybe you've got another problem...

Defaults

I like the ASCII interpretation of the bytes. But some people don't. Do all those people have to type --no-ascii every single time they want to use the tool? Of course not. We want to create a versatile tool, that can suit the needs of as much users as possible. Having a way to override the defaults is the way to go.

hevi archives this by allowing the user to create a config file. In it, the user can decide if they want to have ASCII or not by default. They can still use --ascii and --no-ascii, but it will default to what the user likes, not to what the developer wants.

Having config files doesn't seem like a big deal, but many programs do it in a very bad way, having little to no connection to the flags.

Diagnostics

If the user has an invalid config or passes an invalid flag, we need to report it properly. We shouldn't say "error: invalid config" and exit. Having good diagnostics, specially for the config file, is an essential piece that makes for a good tool.

Features the user wants

Ideally, the tool should support every single feature the user wants, but not many unwanted ones. We don't want the user to feel like the tool is bloated.

For example, if you're dumping the contents of an ELF file, you're probably interested in its structure. hevi can parse ELF files and give the user a syntax-highlighted dump. It is an optional feature, and does not affect the executable size significantly.

Modularity

A tool as generic as a hex viewer should be modular, and maybe even export some kind of module or library. hevi does this in an elegant way, exporting a zig module that makes it extremely easy to integrate with your zig application.

Here comes hevi

hevi meets all the criteria we described.

Now, what is hevi?

hevi is a modern, modular and minimalistic hex viewer.

That's exactly what it is. Just look at it, and its simple usage:

image of example usage

One of the most remarkable features are the parsers. I've mentioned them briefly before, but here's an example. Just picture this. You're inspecting a Windows executable. Let's use xxd first. You write xxd foo.exe | less. You get this:

xxd pe dump

What a mess! Oh, wait, let's add the -R always flag (which obviously stands for colorize).

xxd pe dump color

Still, not great. Now let's use hevi instead of xxd:

hevi pe parser

You can easily see the headers, the sections it contains... You can even pretend like the executable doesn't contain a DOS stub for back-compatibility by just ignoring the brown blob!

Nice.


Well, that's pretty much everything I wanted to say. If you want to check it out, you can do so on github.