Why isn't decompilation a solved problem in the AI era?
There are thousands of pairs of source-executable pairs that could be used for training, and the compiler is a parameter that AI can easily identify and account for as a heavily weighted factor.
So why isn't there (or maybe there is and I don't know about it) an AI based decompiler that can take almost any machine code, and transform it into highly readable source code (complete with meaningful guesses for variable names and comments)? It seems like it should be even easier when the executable could be run and inspected at runtime by the AI model.
What is the state of the art with AI decompilation, and are there tools I can play with today?
Comments
Because the primary value of source code compared to the binary is not the actual translation of expressing the binary as text.
The lost value can never be restored, aka comments, names (these could be lost if debug symbols are not included) etc.
Its not terribly difficult to manually decompile, but it is slow. However the question of WHY this magic number or WHY is it doing that are lost because the comments and context are lost.
Good source code has more of these WHY ANSWERS.
You could go further -- much of the 'why' context might be captured outside of the source code completely, say scattered across design documents / commit messages / issue trackers / test suites / powerpoint decks.
Mathematically speaking, because compilation is a surjective function. Context, organizational, as well as personal knowledge - that information simply is lost in the process of compilation.
It can be restored to some extent by making educated guesses, but it'll never be exactly as readable as the original, which in some cases probably isn't that bad, because the original source code might not have been particularly readable to begin with.
I'm currently doing this with PlayStation games. Primarily using deepseek flash v4 and qwen 3.8 27b. But with escalations to fable and sol at times.
On optimistic days, I'd say, "it is solved". But it's a little more nuanced.
For example, My pipeline takes machine code into "readable" c that matches the underlying binary function by function, and then has an agent annotate each function with what it thinks it should do.
What that produces is decent, but it needs more refinement as more of the project evolves and context emerges.
The problem is that there's an almost infinite source space between what can be statically decompiled and matching c code with the appropriate idioms. If the model can't reason about the flavor of c code it should produce, or doesn't have adequate tooling to unwind a particular function it will just grind away and eventually give up. Sometimes a single function can take a lot of time. The main loop of the game that's being decompiled right now took over a day and multiple sessions and eventually needed to be escalated to fable.
I'm still working on tools and the harness to guide the llm better. I'm optimistic that this can be made more efficient, but still playing with it.
It is.