Show HN: Binspector – A Binary Format Analysis Tool
binspector.github.io
binspector.github.io
I would really love such a tool, but a language to describe most of the file formats in the wild is probably going to be (close to) Turing complete and is unfortunately nothing you can hack together over a weekend.
What I have discovered, however, is that there are still a vast array of binary formats that can be well described with the format language as it stands. I have tried to devise workarounds to skip past the parts of formats that cannot be handled well. I hope to double-back on those limitations and extend the feature set of the language, but I hope what's in there is enough to get people started.
Of the issues you mentioned, Binspector's language can handle dynamic field endianness, dynamic field size, terminators and delimiters, absolute/relative/dynamic offsets, tag-discriminated unions, and lambda calculations. It doesn't do everything, but it does allow a lot.
I used this primarily for reverse-engineering proprietary formats both for personal entertainment, but also while doing work to determine when/if patents were being violated while working for a legal firm.
I had a variety of supported formats, including several microcontroller instruction sets, as I spent a lot of time disassembling ROMs. These had full support for labels etc.
This seems very similar.
edit: grammar
https://www.synalysis.net/formats.xml
Having wanted a binary grammar format for a while, and just purchased the Pro version of "Synalyze It!" as a starting point, it would be interesting to hear a short non-specialist's summary of the relative merits of your approach to expressing grammars compared with an XML based approach like "Synalyze It!" ...
Overall, "Synalyze It!" seems mostly fairly stable and certainly a useful tool well worth the purchase price for the Pro version. However, it is closed source, by a small developer, on a single platform: would much prefer to rely on something with source code available ...
But does he have a repository for "Synalyze It!"?
I cannot see one. It looks like he has open sourced some supporting frameworks ...
edit: grammar
https://www.synalysis.net/Grammars/png.grammar
v.
https://raw.githubusercontent.com/binspector/binspector/mast...
Anything I'd say at this point would be biased, but I would be interested in continuing the conversation.
I could see educational value (and more) in attempting a bi-directional translator between the two grammar formats.
Certainly, it would be worth looking at Binspector. Probably it would take me a couple of days to get up to speed though, and that is not time that I have immediately.
I am a fan of https://pypi.python.org/pypi/hachoir-parser
Interesting project. Is there support for importing/exporting from a C header? Or generating file import code given a bfft file?
Generating import code given a bfft is a thought I had considered. One of the features I would like to implement is to separate the parse tree generator from the analyzer and expose an analyzer API. Applications would be able to use the Binspector core as a library, then, and read file contents directly by providing their own bffts and hooking the API to populate their own internals.
edit: spelling.
Regarding the import code, even if you start with just emitting a C header, it would make it easier to use your tool to design file formats.
I've worked on parsing TrueType files, and they have some really "interesting" grammars. For example, they have lookup tables that define offsets at the beginning of the file. Also, a format flag at the beginning of a table might define the structure of the rest of the table.
It seems that once you decide you want to be able to parse all of this, you're grammar will turn into a Turing-complete language. Have you considered this? Where do you stop?
I have concerns about Turing-completeness, and am interested in maintaining the declarative nature of bffts. The grammar is has drifted from that goal, and I am not entirely sure how to bring it back.
I understand your concern for keeping the format declarative, but I'm not entirely sure you can handle TTF files that way, as you'll run into walls very quickly.
For example, to know the number of entries in the `loca` table, you have to parse the `numGlyphs` field from the `maxp` table. The `maxp` table doesn't have to come first...
Build script here:
https://github.com/ianmiell/shutit/blob/master/library/binsp...
Get this error:
./smoke_test.sh: line 8: ./bin/debug/binspector: No such file or directory
anyone know why?
I write rudimentary bash. If there's a problem in build.sh, debugging the script should be straightforward.
docker pull imiell/binspector
https://registry.hub.docker.com/u/imiell/binspector/
Bit of a hack required to get it compiled; there's probably a better solution:
https://github.com/ianmiell/shutit/blob/master/library/binsp...
I have given a lot of thought into the question of output. Throughout the parse tree there is an implicit DAG of dependencies - this value affecting that read operation over there, etc. The real trick in making a generic output routine from a bfft is reversing this DAG, so e.g., if I add a pixel down here the parse tree can re-stabilize automatically into something valid. This also opens the door to generic editing of binary formats. My understanding is that DAG reversal is an NP-complete problem, but I suspect with file formats we're dealing with a subset of the space and it might not be as difficult as I am imagining.
similar idea: generating a nicely formatted spec document from the grammar.