Source-linked AI summary
DIRE: A Neural Approach to Decompiled Identifier Naming
Jeremy Lacomis, Pengcheng Yin, Edward J. Schwartz, Miltiadis Allamanis, Claire Le Goues, Graham Neubig, Bogdan Vasilescu
TL;DR
Decompilers recover much program structure but generally lose meaningful variable names, limiting code comprehension. DIRE combines lexical and structural information with an automated corpus-generation process, and predicts original developer names up to 74.3% of the time on 164,632 unique x86-64 binaries. Its applicability is bounded because it was not evaluated on optimized or intentionally obfuscated binaries and did not work well with Ghidra’s variable-naming behavior.
Problem
Decompilers usually lose semantically meaningful variable names even though such names improve code understandability.
Method
DIRE is a probabilistic neural approach that uses lexical and structural decompiler information, trained on automatically generated aligned examples from compiled and decompiled C code.
Results
DIRE predicts variable names identical to those in the original source code up to 74.3% of the time on a corpus of 164,632 unique x86-64 binaries.
Takeaways & Limitations
DIRE provides a demonstrated approach for recovering developer-like variable names from decompiled code using both lexical and structural information.
Takeaways & Limitations
The evaluation excludes optimized and intentionally obfuscated binaries, and the approach did not work well with the Ghidra decompiler’s variable-naming behavior.
Abstract
from arXiv · showhide
The decompiler is one of the most common tools for examining binaries without corresponding source code. It transforms binaries into high-level code, reversing the compilation process. Decompilers can reconstruct much of the information that is lost during the compilation process (e.g., structure and type information). Unfortunately, they do not reconstruct semantically meaningful variable names, which are known to increase code understandability. We propose the Decompiled Identifier Renaming Engine (DIRE), a novel probabilistic technique for variable name recovery that uses both lexical and structural information recovered by the decompiler. We also present a technique for generating corpora suitable for training and evaluating models of decompiled code renaming, which we use to create a corpus of 164,632 unique x86-64 binaries generated from C projects mined from GitHub. Our results show that on this corpus DIRE can predict variable names identical to the names in the original source code up to 74.3% of the time.
I. INTRODUCTION
DIRE addresses the loss of meaningful variable names in decompiled code by combining lexical and structural information with automatically generated training data. It predicts developer-chosen names and outperforms prior approaches on a large corpus of decompiled C programs.
- I. INTRODUCTION: DIRE recovers meaningful variable names from decompiled code using lexical context and structural information from the decompiler’s abstract syntax tree.The approach is motivated by the importance of variable names for code comprehension and the limitations of prior lexical or binary-semantic methods.
- I. INTRODUCTION: The corpus-generation method mines open-source C code, compiles binaries with debugging information, then aligns named and stripped decompiler outputs.This process produces training examples pairing decompiler-assigned names with developer-assigned names.
- I. INTRODUCTION: DIRE predicts names identical to those chosen by developers up to 74.3% of the time on its GitHub-derived corpus.The dataset contains 3,195,962 decompiled x86-64 functions and parse trees annotated with gold-standard variable names.
- I. INTRODUCTION: DIRE outperforms previous approaches by exploiting abstractions recovered by decompilers instead of relying only on binary semantics or sequential lexical output.The introduction identifies the decompiler’s AST as an additional source of structural context for prediction.
A. Decompilation
Decompilers reverse compilation by reconstructing high-level structure from binaries, but information loss makes the original source ambiguous. Statistical naming models therefore use repetitive code patterns and neural sequence and graph representations to predict identifiers.
- A. Decompilation: Decompilers reconstruct an abstract syntax tree by disassembling binaries, lifting code to an intermediate representation, and recovering variables, types, functions, and control flow.A final code generator converts the reconstructed AST into decompiled output.
- A. Decompilation: Information loss during compilation allows distinct source programs to produce identical assembly, so decompilers use heuristics and debugging information to choose readable structures.Debugging information can identify offsets, types, names, and user-defined structures, while heuristics may prefer constructs such as while loops over gotos.
- A. Decompilation: Statistical code models exploit the repetitiveness of source code to predict variable names from contextual features.Prior naming systems include n-grams, conditional random fields, and deep learning models.
- A. Decompilation: Earlier decompiled-code approaches recovered 12.7% of original names lexically, while a binary-based method recovered 63.5% among variables successfully mapped in its first stage.The binary-based method first predicts whether registers or memory locations correspond to source-level variables, then predicts their names and types.
- A. Decompilation: DIRE combines recurrent neural networks for sequences with gated-graph neural networks for structural representations.Its encoder LSTMs represent input sequences, while decoder LSTMs generate predicted names for identifiers.
2) Gated-Graph Neural Networks:
DIRE uses a gated-graph neural network to encode AST structure through typed message passing, repeatedly updating node states so they capture local context and graph-wide information.
- 2) Gated-Graph Neural Networks:: GGNNs represent code as directed graphs whose vertices carry hidden states and whose typed edges define neighboring nodes for message passing.Each node state is updated concurrently at successive time steps.
- 2) Gated-Graph Neural Networks:: Typed neighbor messages are transformed with edge-specific matrices, aggregated by element-wise mean pooling, and summarized into a single node input.The pooled message vector is then used in the node-state update.
- 2) Gated-Graph Neural Networks:: The approach overview is presented as a figure showing how DIRE processes decompiled-program information.The supplied figure caption identifies the visual only as a high-level overview.
- 2) Gated-Graph Neural Networks:: A GRU update repeatedly integrates pooled messages with each node’s prior state, allowing representations to incorporate information from the node’s graph context.The recurrent process applies neural message passing for T steps.
III. THE DIRE ARCHITECTURE
DIRE is a decompiler plugin and encoder-decoder neural architecture that predicts informative variable names from both tokenized code and AST structure. Its lexical and structural signals are combined to outperform lexical-only techniques.
- III. THE DIRE ARCHITECTURE: DIRE processes decompiler output by replacing variable nodes with placeholders, encoding the resulting AST and tokenized code, and rewriting the output with predicted names.The plugin is designed to operate on top of Hex-Rays while remaining adaptable to other decompilers.
- III. THE DIRE ARCHITECTURE: The encoder-decoder architecture creates distributed representations for identifiers and code elements, which the decoder uses to predict names from identifier-use contexts.The encoder covers both the decompiled token sequence and internal AST.
- III. THE DIRE ARCHITECTURE: Using lexical and structural information together allows DIRE to outperform techniques that rely on lexical information alone.This is stated as the key architectural takeaway and reported comparison.
- III. THE DIRE ARCHITECTURE: Each encoder produces code-element and identifier representations, while identifier sub-token representations can be mean-pooled into fixed-length vectors.The lexical and structural representations are later merged into unified encodings.
- III. THE DIRE ARCHITECTURE: The lexical encoder sequentially represents sub-tokenized code, using bidirectional LSTMs to capture context before and after each token.SentencePiece breaks complex tokens such as mystrcopy into sub-pieces, reducing vocabulary size.
2) Structural Code Encoder:
DIRE’s structural encoder applies a GGNN to an AST, initializing nodes with syntactic, data-type, and name information and augmenting the graph with edges that expose naming and usage relationships.
- 2) Structural Code Encoder:: The structural encoder uses a GGNN over the decompiler’s AST to learn from structural information that lexical encoding alone cannot capture.The encoder requires initial node states and choices about which AST edges to include.
- 2) Structural Code Encoder:: Initial AST node states combine embeddings for syntactic type, data type, and node name, with zero vectors used when type or name information is unavailable.Data-type embeddings are computed from sub-tokenized type representations.
- 2) Structural Code Encoder:: The graph augments parent-child AST edges with function-name-to-identifier, successor-terminal, supernode, and reverse edges.These edge types encode naming dependencies, neighboring-code dependencies, identifier-wide information flow, and bidirectionality.
- 2) Structural Code Encoder:: After eight GGNN propagation steps, each AST node uses its final state as its element representation, while each identifier uses the final state of its supernode.Because supernodes connect to all mentions, identifier representations capture usage across occurrences.
- 2) Structural Code Encoder:: The architecture overview omits data-flow links in the AST for clarity.The caption identifies the visual as an overview of DIRE’s neural architecture.
3) Combining Outputs of Lexical and Structural Encoders:
DIRE merges lexical and structural encoder outputs, then uses an attention-based LSTM decoder to generate sub-tokenized identifier names or preserve decompiler-assigned names when appropriate.
- 3) Combining Outputs of Lexical and Structural Encoders:: Lexical and structural representations are combined for code elements and identifiers before decoding.Code-element encodings unite token and AST-node representations, while identifier representations are merged through a linear transformation.
- 3) Combining Outputs of Lexical and Structural Encoders:: The decoder predicts each identifier name as a sequence of sub-tokens, continuing across identifiers and allowing a special identity token when no ground-truth name is available.For example, destAddr is generated as dest, Addr, and an end token.
- 3) Combining Outputs of Lexical and Structural Encoders:: Name-generation probability is factorized into local conditional probabilities over successive sub-token decisions.The sequence is conditioned on the input code and previously generated sub-tokens.
- 3) Combining Outputs of Lexical and Structural Encoders:: At each decoding step, an LSTM uses the previous name embedding and current identifier representation, while attention aggregates relevant AST-node and code-token context.The attended context is combined with the decoder state before predicting the next sub-token.
D. Training the Neural Network
DIRE training uses automatically generated examples that pair tokenized decompiled code and AST structure with developer and decompiler names. Variable alignment relies on instruction-offset signatures, which remain stable despite structural changes caused by debugging information.
- Corpus construction: Each corpus entry contains tokenized code, an AST, and a lookup table linking variable IDs to decompiler- and developer-assigned names.Variables in the code and AST are replaced with unique IDs so the representations share a consistent identity space.
- Training-data alignment: Decompiler outputs may introduce temporary variables without developer-assigned names, and debugging information can change how many such variables are generated.For example, a direct return expression may become an assignment to an additional temporary variable.
- Training-data alignment: Instruction-offset signatures align variables across decompilations even when debugging information changes the AST and code structure.Each variable is identified by the full set of instruction offsets accessing it, enabling accurate alignment without heuristic post-processing.
- Training-data alignment: Prior heuristic alignment correctly matched only 72.8% of variable names, limiting the accuracy of models trained on those annotations.DIRE instead integrates alignment with the decompiler and uses unchanged offsets and variable operations to improve correspondence.
- Corpus construction: The corpus is generated by decompiling binaries with debugging information, collecting developer names, stripping symbols, and aligning variables across the two outputs.The workflow then annotates the stripped decompilation and generates training code from the updated AST.
V. EVALUATION
The evaluation measures exact recovery of developer-assigned names and character error rate on a large, binary-separated corpus. It also tests data provenance, component contributions, and practical evaluation boundaries.
- Evaluation questions: The evaluation asks how effective DIRE is, how its components contribute, how data provenance and quantity affect it, and whether it outperforms prior approaches.These questions define the evaluation’s effectiveness, ablation, data-scaling, and comparison dimensions.
- Data and protocol: DIRE is trained on 3,195,962 decompiled functions from 164,632 GitHub-mined x86-64 binaries, with filtered functions split 80:10:10 per binary.The final filtered set contains 1,259,935 functions, averaging 77 AST nodes; per-binary splitting limits identifier overlap between training and testing.
- Metrics: Evaluation counts an exact match when a predicted variable name equals the original developer-assigned name and also uses character error rate for near matches.Exact match cannot recognize multiple equally acceptable spellings such as file_name, fname, and filename.
- Evaluation boundaries: Predictions for variables lacking developer-assigned names are excluded because assigning an informative name may be helpful, while assigning a misleading name may reduce readability.This prevents the evaluation from counting all renamings of generated temporaries as correct.
A. RQ1: Overall Effectiveness
DIRE recovers developer-assigned names effectively overall, performs best when function bodies appeared in training, and still generalizes to unseen functions with semantically relevant suggestions.
- Overall effectiveness: 74.3% of original variable names are recovered exactly by DIRE on the full test set.This result is reported for the overall evaluation and is presented as evidence that DIRE assigns contextually meaningful names.
- Qualitative examples: Figure 6 shows two of three DIRE suggestions exactly matching developer-selected names, while buf is a plausible alternative to ret.The example illustrates that an inexact prediction can still describe a pointer returned by mmap.
- Generalization: 85.5% accuracy on Body in Train functions contrasts with 35.3% on Body not in Train functions, showing strong performance on seen code and nonzero generalization to unseen functions.The partitions separate functions whose entire body appeared in training from those absent from training.
- Generalization: On unseen functions, DIRE often suggests semantically similar names, performing best on simple identifiers such as len and value.Complex compositional names are harder to predict exactly, while suggestions such as node and child can remain semantically relevant.
B. RQ2: Component Contributions
DIRE’s combined lexical and structural models outperform either component alone and can merge complementary predictions. Performance remains competitive with reduced training data, though lower sampling rates increase character error.
- Component contributions: 72.9% lexical accuracy and 64.6% structural accuracy improve to 74.3% when the two encoders are combined in DIRE.The component comparison shows that both simpler models perform well, but their combination yields the strongest overall result.
- Component contributions: DIRE combines complementary lexical and structural predictions to recover names that neither submodel predicts correctly alone.In the example, combining file and fname produces filename, while information from another variable helps recover mode.
- Training-data quantity: At a 1% sampling rate, DIRE still selects names correctly more than 40% of the time on Body in Train functions.The result suggests that smaller training sets can suffice when the target application contains code seen during training.
- Training-data quantity: At 40% of the training data, DIRE reaches 68.2% overall accuracy versus 74.2% with the full set, while CER is 33.6% versus 28.2%.Higher sampling rates substantially reduce CER, bringing incorrect names closer to developers’ choices.
- Training-data quantity: DIRE is data-efficient at 40% of the training data and outperforms the lexical and structural models in most subsampling cases.At sampling rates of 10% or less, the component models have similar performance, potentially reducing training time when only one is used.
D. RQ4: Comparison to Prior Work
DIRE outperforms DEBIN and prior lexical naming approaches, while preserving decompiler-recovered structure and types when predictions are incorrect.
- 74.3% of original variable names were recovered exactly by DIRE, compared with 12.7% for the earlier purely lexical model.
- DIRE leverages decompiler-identified variables and offsets, whereas DEBIN predicts variable locations before assigning names.DEBIN’s two-stage process can suffer compound error when a memory location is not identified as a variable.
- Unlike DEBIN’s incorrect debugging information, DIRE maintains pseudocode structure and typing even when its name predictions are incorrect.The example reports that DEBIN’s information can remove arguments and return information and alter inferred types.
- DIRE recovered 32.2% of identifiers at 1% training data and 38.4% at 3%, versus DEBIN’s 2.4% and 3.9%.DIRE outperformed DEBIN at both reported sampling sizes.
- DIRE was more accurate and scalable than the compared state-of-the-art approaches, and trained faster than DEBIN under the reported hardware conditions.DIRE was GPU-accelerated, whereas the distributed DEBIN implementation was CPU-limited.
VI. THREATS TO VALIDITY
The evaluation is bounded by the collected corpus, compilation settings, and decompiler compatibility, although the authors do not believe DIRE applies only to the tested code.
- The collected C repositories may not represent the binaries typically targeted by reverse-engineering efforts.
- DIRE was not evaluated on optimized or intentionally obfuscated binaries, where performance may be lower.The authors characterize these binaries as a general challenge for decompilers.
- The corpus-generation approach did not work well with Ghidra because its name propagation can conflict with developers’ intended local names.The authors leave Ghidra integration to future work and identify a need for a new compatible corpus-generation approach.