[HN Gopher] Decompiling 2024: A Year of Resurgance in Decompilat...
       ___________________________________________________________________
        
       Decompiling 2024: A Year of Resurgance in Decompilation Research
        
       Author : matt_d
       Score  : 120 points
       Date   : 2025-01-30 01:48 UTC (21 hours ago)
        
 (HTM) web link (mahaloz.re)
 (TXT) w3m dump (mahaloz.re)
        
       | loloquwowndueo wrote:
       | "Resurgence" not "resurgance". I wanted to leave a comment in the
       | article itself but it wants me to sign in with GitHub, which:
       | yuk, so I'm commenting here instead.
        
         | mahaloz wrote:
         | Welp, that's a really sad typo... I've made a post-publication
         | edit to the article now, but my shame is immortalized in Git:
         | https://github.com/mahaloz/mahaloz.re/commit/90b760f53ef51b7...
        
           | sitkack wrote:
           | Proof you didn't use AI? :)
        
             | nayuki wrote:
             | Spell checkers existed before AI.
        
       | benob wrote:
       | > If you've ever talked to me in person, you'd know that I'm a
       | disbeliever of AI replacing decompilers any time soon
       | 
       | Decompilation, seen as a translation problem, is by any means a
       | job that suits AI methods. Give time to researchers to gather
       | enough mappings between source code and machine code, get used to
       | training large predictive models, and you shall see top notch
       | decompilers that beat all engineered methods.
        
         | kachapopopow wrote:
         | Typical obfuscation sure. vms, obfuscation and everything in
         | between is just noise to AI.
        
         | donatj wrote:
         | It's pattern matching, plain and simple, An area where AI
         | excels. AI driven decomp is absolutely on its way
        
           | dartos wrote:
           | Maybe in conjunction with a deterministic decompiler.
           | 
           | precision wrt translation, especially when the translation is
           | not 1-to-1, is not excellent with LLMs.
           | 
           | In fact, their lack of precision is what makes them so good
           | at translating natural languages!
        
           | ChrisKnott wrote:
           | It's also perfect for RL because it can compile it's output
           | and check it against the input. It's a translation exercise
           | where there's already a perfect machine translator in one
           | direction.
           | 
           | It probably just hasn't happened because decompilation is not
           | a particularly useful thing for the vast majority of people.
        
           | thesz wrote:
           | Let me parrot you, it's fun.
           | 
           | "It's pattern matching, plain and simple, an area where
           | pattern matching algorithms excel. Pattern matching driven
           | decomp absolutely leads"
           | 
           | Decompilation is a dependence graph problem, one can
           | formulate decompilation as a graph transformation/rewrite.
           | Neural networks are notoriously bad at graphs.
        
         | wzdd wrote:
         | > Decompilation, seen as a translation problem, is by any means
         | a job that suits AI methods.
         | 
         | Compilation is also a translation problem but I think many
         | people would be leery of an LLM-based rust or clang -- perhaps
         | simply because they're more familiar with the complexities
         | involved in compilation than they are with those involved in
         | decompilation.
         | 
         | (Not to say it won't eventually happen in some form.)
        
           | chrisco255 wrote:
           | LLMs are not deterministic, and I want deterministic builds
           | from compiled code to assembly. I also do not want the LLM to
           | arbitrarily change the functionality, I have no such
           | guarantees.
        
             | sitkack wrote:
             | Compilers aren't deterministic in the ways that people
             | would think matter.
             | 
             | We will have LLM based compilers in the near future.
             | Determinism is a property of the system, not the
             | components.
        
               | LowLevelMahn wrote:
               | "near" like never :)
        
               | sitkack wrote:
               | You want to put money on it?
               | 
               | You set the criteria.
        
           | IshKebab wrote:
           | I wouldn't be at all leery of LLM-based compilers (as long as
           | their output is verified to be correct and reasonable).
        
         | __alexander wrote:
         | > Give time to researchers to gather enough mappings between
         | source code and machine code, get used to training large
         | predictive models, and you shall see top notch decompilers that
         | beat all engineered methods.
         | 
         | Not anytime soon. There is more to a decompiler than assembly
         | being converted to x language. File parsers, disassemblers,
         | type reconstruction, etc are all functionality that have to run
         | before a "machine code" can be converted to the most basics of
         | decompiler output.
        
         | jcranmer wrote:
         | Yes and no.
         | 
         | My first priority for a decompiler is that the output is
         | (mostly) _correct_. (I say mostly because there 's lots of
         | little niggling behavior you probably want to ignore, like
         | representing a shift instruction as `a << b` over `a << (b &
         | 0x1f)`). When the decompiler's output is incorrect, I can't
         | trust it anymore, and I'm going to go straight back to the
         | disassembly because I need to work with the correct output. And
         | AI--especially LLMs--are notoriously bad at the "correct" part
         | of translation.
         | 
         | If you look at decompilation as a multistep problem, the main
         | steps are a) identify the function/data symbol boundaries, b)
         | lift the functions to IR, c) recover type information
         | (including calling convention for functions), d) recover high-
         | level control flow, and e) recover variable names.
         | 
         | For step b, correctness is so critical that I'm wary of even
         | trusting hand-generated tables for disassembly, since it's way
         | too easy for someone to copy something by hand. But on the
         | other hand, this is something that can be machine-generated
         | with something that is provably correct (see, e.g.,
         | https://cs.stanford.edu/people/eschkufz/docs/pldi_16.pdf).
         | Sure, there's also a further step for recognizing higher-level
         | patterns like manually-implemented-bswap, but that's basically
         | "implement a peephole optimizer," and the state of the art for
         | compilers these days is to use formally verifiable techniques
         | for doing that.
         | 
         | For a lot of the other problems, if you instead categorize them
         | as things where the AI being wrong doesn't make it incorrect,
         | AI can be a valuable tool. For example, control flow
         | structuring can be envisioned as identifying which branches are
         | gotos (including breaks/continues/early returns), since a CFG
         | that has no gotos is pretty trivial to structure. So if your
         | actual AI portion is a heuristic engine for working that out,
         | it's never going to generate _wrong_ code, just unnecessarily
         | complicated code.
        
           | sitkack wrote:
           | You are right on a lot of things, but LLMs are the best
           | bijective lens that humanity has ever discovered. They can
           | invert functions we didn't think were invertible.
           | 
           | If given a mostly correct transform from binary back to code,
           | how would we fix that?
           | 
           | Exactly!
           | 
           | Heuristics are dead.
        
             | thesz wrote:
             | > Heuristics are dead
             | 
             | I guess it is an example of an heuristic.
        
           | svilen_dobrev wrote:
           | > identifying which branches are gotos
           | 
           | mmh. Yesterday i tried some LLM-augmented "analysis", given a
           | 50 lines source of C, a function with few goto's in it..
           | somehow all "explanations" were ~correct except it completely
           | ignored the goto's. Using a deepseek-r1-...7b, ollama's
           | default, probably too weak ; but i don't believe other models
           | would be 100% correct either.
        
           | Vt71fcAqt7 wrote:
           | >And AI--especially LLMs--are notoriously bad at the
           | "correct" part of translation.
           | 
           | Can't you just compare the compiled binaries to see if they
           | are the same? Is the issue that you don't have the full
           | toolchain so there are different outputs from the two
           | compilers? Thinking about it though you could probably figure
           | out which compiler was used using those same differences
           | though..
        
             | CFLAddLoader wrote:
             | The expected outcome of using a LLM to decompile is a
             | binary that is so wildly different from the original that
             | they cannot even be compared.
             | 
             | If you only make mistakes very rarely and in places that
             | don't cause cascading analysis mistakes, you can recover.
             | But if you keep making mistakes all over the place and
             | vastly misjudge the structure of the program over and over,
             | the entire output is garbage.
        
               | Vt71fcAqt7 wrote:
               | That makes sense. So it can work for small functions but
               | not an entire codebase which is the goal. Does that sound
               | correct? If so, is it useful for small functions (like,
               | let's say I identify some sections of code I think are
               | important becuase they modify some memory location) or is
               | this not useful?
        
               | CFLAddLoader wrote:
               | There are lots of parts of analysis that really matter
               | for readability but aren't used as inputs to other
               | analysis phases and thus mistakes are okay.
               | 
               | Things like function and variable names. Letting an LLM
               | pick them would be perfectly fine, as long as you make
               | sure the names are valid and not duplicates before
               | outputting the final code.
               | 
               | Or if there are several ways to display some really weird
               | control flow structures, letting an LLM pick which to do
               | would be fine.
               | 
               | Same for deciding what code goes in which files and what
               | the filenames should be.
               | 
               | Letting the LLM comment the code as it comes out would
               | work too, as if the comments are misleading you can just
               | ignore or remove them.
        
         | mahaloz wrote:
         | I agree with many other sentiments here that if it can replace
         | decompilers, then surely it can replace compilers... which
         | feels unlikely soon. So far, I've seen four end-to-end binary-
         | to-code AI approaches, and none have had convincing results.
         | Even those that crawled all of GitHub continue to have issues
         | of making fake code, not understanding math, omitting portions
         | of code, and (a personal irritant for me) being unable to map
         | what address a line of decompilation came from.
         | 
         | However, I also acknowledge that AI can solve many pattern-
         | based problems well. I think a considerable value can be
         | extracted from AI by focusing in on micro decisions in the
         | decompiler process, like variable types, as recent work has.
        
           | jcranmer wrote:
           | I'd feel a lot more comfortable in the prospects of AI if
           | their big boosters weren't so gung-ho about it replacing
           | absolutely everything. Compilers (and by extension
           | decompilers) are one of the areas where we have the ability
           | to have formal proofs of correctness [1]--and the fact that
           | AI people seem to be willing to throw all of that away in
           | favor of their maybe-correct-but-does-it-really-matter-if-
           | it's-not tools is extremely distressing to me.
           | 
           | [1] And one of the big advances in compilers in the past
           | decade or so is the fact that compilers are actually using
           | these in practice!
        
         | thesz wrote:
         | > Give time to researchers to gather enough mappings between
         | source code and machine code, get used to training large
         | predictive models, and you shall see top notch decompilers that
         | beat all engineered methods.
         | 
         | Decompilation is about dependencies which makes it a graph
         | problem.
         | 
         | One such problem is boolean satisfiability and this particular
         | kind of problem is extremely important. It also very easy to
         | gather mappings between CNF and solutions. Actually,
         | randomization of standard benchmarks is now part of SAT
         | competitions, AFAIK.
         | 
         | Have you seen any advances there using large predictive models?
         | 
         | Proper decompilation is even harder, it is much like halting
         | problem than SAT. Imagine that there is a function that gets
         | inlined and, therefore specialized. One definitely wants source
         | for the original function and calls to it, not a listing of all
         | specializations.
         | 
         | This moves us to the space of "inverse guaranteed optimization"
         | and as such it requires approximation of the solution of
         | halting problem.
        
       | mips_avatar wrote:
       | Decompilers aren't just for security research they're a key part
       | of data compression of software updates. Delta compressors make
       | deltas between decompiled code. So an improvement in mapping of
       | decompiled files could have as much as a 20x improvement in
       | software update size.
        
         | mahaloz wrote:
         | I love this use case! Do you have any public links
         | acknowledging/mentioning/showing this use case? Including it in
         | the Applications portion of the Dec Wiki would be great.
        
       | rgovostes wrote:
       | This was an informative article and I hope the author continues
       | the series.
       | 
       | Regarding AI-assisted renaming of variables, the author calls
       | this "a strict improvement over traditional decompilation." But
       | looking at the example:                   struct IxpMsg {
       | struct Buffer {             char* data;              uint8_t*
       | buffer;             char* pos;               uint8_t* pos;
       | char* end;       =>      uint8_t* streamPos;             _ixpuint
       | size;           uint32_t bufferSize;             _ixpuint mode;
       | uint32_t type;         };                       }
       | Ground Truth                ReSym (AI)
       | 
       | I am reluctant to allow the decompiler to influence my judgment
       | about the meaning of variables. `streamPos` is not equivalent to
       | `end`. Consider the issue multiplied by 20 or 100 as many
       | incorrect assumptions, and it would severel cloud your
       | understanding of the decompiled code.
       | 
       | Combining this with reasoning models that can justify their
       | labels would be very helpful. UX improvements could also be made
       | to indicate confidence or progressively disclose these
       | assumptions.
        
       ___________________________________________________________________
       (page generated 2025-01-30 23:01 UTC)