Tour
What it does, in detail.
Everything on this page is in the build you can download today. Nothing here is aspirational, and nothing here is coming later.
Input
Loaders and architectures
Klarion opens PE32+, ELF32 and ELF64, Mach-O, Intel HEX, Motorola S-record and raw images with a base address you supply. A loader claims a file by inspecting it rather than by its extension, and a file no loader claims is reported as unrecognised rather than guessed at.
Disassembly covers twelve architectures: x86-64, x86 and x86-16 including real mode for firmware and boot code; AArch64 and AArch32 in both ARM and Thumb state; RISC-V in 32- and 64-bit; and MIPS32 and MIPS64 in both byte orders, because big-endian MIPS is what most router and firmware images actually are. Every one of them assembles as well as disassembles, so a replacement instruction can be written in the mnemonic you would have typed rather than as bytes.
Symbol names are demangled from MSVC, Itanium, Rust and Swift schemes, and Objective-C selectors are recovered from the runtime metadata. A name Klarion cannot demangle is left exactly as it was found rather than half-decoded.
- Containers
- PE32 · PE32+ · ELF32 · ELF64 · Mach-O
- Flat formats
- Intel HEX · S-record · raw
- Architectures
- x86-64 · x86 · x86-16 · AArch64 · ARM · Thumb · RISC-V 32/64 · MIPS32/64 BE+LE
- Demangling
- MSVC · Itanium · Rust · Swift · Objective-C
Ground truth
Debug symbols, managed code and signing
Point Klarion at a binary whose symbols you have and it reads them: PDB for anything built with MSVC, DWARF 2 through 5 for anything built with GCC or Clang. Functions get their real names and their real boundaries, parameters and locals get theirs, and source line numbers come across, so a listing can say which line of which file it came from. A PDB is matched on both its identifier and its age, so a stale one left over from an earlier link is refused rather than quietly applied to addresses it no longer describes.
A .NET assembly is recognised as one. Its types, methods, fields and strings are recovered from the CLR metadata and its method names reach the listing — and, just as importantly, its bytecode is marked as bytecode. A disassembler pointed at CIL will say so rather than presenting a confident x86 reading of something that was never x86.
Where a file carries an Authenticode signature, the image is hashed the way the signature says it was and compared against what was signed, so a binary altered after signing is identified as altered. Klarion reports whether the contents still match and states plainly that it has not evaluated the certificate chain: a tampered file and an untrusted publisher are different questions, and only the first is answerable from the file alone.
Output
The decompiler
Functions are lifted to an SSA intermediate representation, put through data-flow analysis, structured back into loops and conditionals, and printed as C. Each line carries the address of the instruction it came from, so pseudocode and disassembly are never two separate stories about the same function.
Seven of the twelve architectures decompile: x86, x86-64, AArch64, AArch32 in both ARM and Thumb state, and RISC-V in 32- and 64-bit. x86-16 and MIPS disassemble but do not yet produce pseudocode, and Klarion says so at the point you ask rather than returning something that looks like an answer.
Where a type has not been recovered, the output says undefined8 rather than guessing at int. A decompiler that quietly invents a type is worse than one that admits it does not know, because the invention is indistinguishable from a recovered fact once it is on the screen.

C++
Class recovery from RTTI
Klarion reads MSVC and Itanium run-time type information directly out of the image: class names, base-class hierarchies including virtual and multiple inheritance and every vftable slot resolved to the function it points at. Because this is a scan of image bytes rather than an analysis pass, it works on a fully stripped binary and it works before anything else has run.
Recovered classes become real types in the type system, so a pointer that the decompiler proves is a Foo * renders member accesses by name.
Obfuscation
When the graph was made unreadable on purpose
Control-flow flattening replaces a function’s structure with a loop around a switch: every original block becomes a case, and each one ends by writing the number of the next into a state variable. The result is one node wide and thirty tall and tells you nothing. Klarion identifies it as flattened rather than leaving it looking like a disassembler that failed, which is the difference between an hour and a minute.
Ask it to, and the original control flow is rebuilt: the dispatcher removed, each block joined to the one its state variable selects, and the conditional moves recovered as the two-way branches they were before they were flattened. Blocks whose next state cannot be resolved keep their original edges and are listed by address — a rebuilt graph that hides what it could not work out is worse than no rebuild, because nothing downstream can tell a recovered edge from an invented one.
Separately, branches that always go the same way are reported with the comparison that proves it, so the claim can be checked rather than taken. That is a proof and not a heuristic: both sides of the comparison are constants the block itself established. Removing them, and the blocks only they reached, is again something you ask for rather than something that happens to you.
Both are decisions made when the binary is opened, in the same dialog that chooses the loader, because rewriting a graph is not something to switch on afterwards: turning it off again does not restore what it replaced.
Navigation
Graph, listing and panels
The same function, as a linear listing, a control-flow graph, hex or pseudocode, switched with one key each. The hex view carries a data inspector that reads the bytes under the cursor as every primitive type at once, including a timestamp and a pointer.
Thirteen panels sit beside them, each on its own shortcut: search, strings, imports, exports, symbols, segments, bookmarks, entropy, types, comments, the call tree, snapshots and scripts. Four more — the functions list, cross-references, properties and the output drawer — are dock widgets you can drag to another edge, tear off onto a second monitor or close entirely. The layout is remembered and can be saved as a named arrangement.

Library code
Signatures
A signature database is built straight from a static library: 6,726 signatures from one CRT archive, generated rather than curated by hand. The format is memory-mapped, so matching a large database costs no load time.
A match reports the library, version and compiler it came from, so you can judge it rather than take it. And it never overwrites a name a human set: analysis is not allowed to undo a decision a person made, anywhere in Klarion.
Automation
Command line, diffing, scripting, MCP
The same engine, without the window. Every command emits JSON for whatever reads it next, so Klarion drops into a build pipeline without a scraping layer.
Two builds can be matched against each other function by function, on several independent signals at once: identical bytes, a normalised instruction hash that ignores relocation and layout, symbol names, mnemonic sequences and control-flow shape, with matches then propagated along the call graph. Every pair carries a confidence and is classified as identical, moved or changed, and anything ambiguous is reported as nothing at all — a wrong match costs far more than a missing one.
The reason to do it is the one that pays: diff a build you have symbols for against one you do not, and carry the names across. Only names that mean something are ported, only above a confidence threshold higher than the one for merely listing a match, and never over a name you set yourself.
An embedded Lua interpreter gives a flat read-and-write API over the analysis model. There is no os and no io: a script cannot touch the filesystem, spawn a process or open a socket, and a runaway loop is interrupted on a wall-clock budget rather than hanging the window.
Klarion also ships as a module your own Python imports, binding the same operations under the same names, so a notebook or a CI job reaches the engine without moving into a console of ours. It loads with your privileges, the way every other library you import does; the sandbox above is the Lua engine, and only that.
The MCP server exposes twenty-two tools over JSON-RPC on stdio, so an agent can drive the engine the way you drive the window. Three of them write to the analysis and each says so before it is called; none of them touches the binary on disk.
MCP referenceScripting reference
Everything above this section is in the free edition. A Klarion Pro licence adds the command line, the MCP server, scripting, the Python module, binary diffing, signature generation and export.
Your work
Projects, undo and collaboration
A project is a single SQLite file holding every name, comment, type, bookmark and patch you have made, with full undo and named snapshots you can return to. Every edit records whether it came from you, from analysis, from a plugin or from an import, and analysis is never permitted to overwrite one of yours.
For a team, Klarion Team adds a server you host yourself: your machine, your data, no account with us in the path. It works like a git remote for analysis: everyone has a working copy, changes are facts rather than file diffs, and the history says who decided what.
Try it on something you actually care about.
The free edition has everything on this page except the automation.