Papers
Topics
Authors
Recent
Search
2000 character limit reached

NeuCall: Indirect Call Resolution

Updated 7 July 2026
  • NeuCall is an approach that combines cross-reference augmented control-flow graphs with a relational graph convolutional network to resolve indirect call targets in stripped binaries.
  • It leverages compiler-level type analysis to generate high-quality, one-to-many indirect-call training pairs, addressing noisy supervision in prior methods.
  • By integrating control flow, data/code cross-references, and Laplacian positional encoding, NeuCall achieves a state-of-the-art F1 score of 95.2% on x86_64 binaries.

NeuCall is an approach for resolving indirect call targets in stripped binaries by combining cross-reference augmented control-flow graphs with a relational graph convolutional network. It is designed for static binary code analysis in settings where source code is unavailable and where unresolved indirect calls would otherwise leave the inter-procedural control-flow graph incomplete. The method addresses two obstacles identified in prior ML-based work: low-quality callsite-callee training pairs and inadequate binary code representation. Its central contributions are the use of compiler-level type analysis to generate high-quality one-to-many indirect-call supervision and a heterogeneous graph representation that preserves both control flow and data/code cross-references, yielding an F1 score of 95.2% on real-world x86_64 binaries from GitHub and the Arch User Repository (Zhang et al., 24 Jul 2025).

1. Indirect-call resolution as a static binary analysis problem

Indirect calls in stripped binaries arise when the target address of a call instruction, such as call rax, is computed at runtime rather than encoded directly in the instruction. Static analysis tools construct inter-procedural CFGs by connecting basic blocks across function calls; when an indirect callsite’s destination register or memory operand cannot be resolved statically, the CFG remains incomplete, obscuring true data-flow and control-flow relationships (Zhang et al., 24 Jul 2025).

The underlying difficulty is not merely implementation complexity. The problem is described as undecidable in general: resolving all possible values held in a register or memory location at an indirect callsite is Turing-complete because it reduces to solving arbitrary program paths. This motivates approximations, but the paper positions existing approximations as exhibiting a characteristic precision-scalability tradeoff (Zhang et al., 24 Jul 2025).

Prior static approaches are grouped into three broad categories. Value-set analysis over-approximates pointer ranges and may generate thousands of spurious targets, producing poor precision. Symbolic execution can enumerate actual targets but suffers path explosion, producing poor scalability. Type-based matching, including TypeArmor and TypeSqueezer, relies on argument-count and prototype heuristics, but these heuristics can under- or over-estimate types, producing low recall or low precision. Dynamic approaches such as hardware tracing, fuzzing, and concolic execution can record actual targets, yet coverage remains incomplete because rare paths may be missed, and instrumentation overhead is high (Zhang et al., 24 Jul 2025).

NeuCall is framed as a response to limitations that persist even in recent ML-based systems such as Callee and AttnCall. Two deficiencies are emphasized. First, the training pairs used by earlier models may be incomplete or noisy. Second, binaries are often represented as linear token sequences, which discard control- and data-cross-reference semantics. The paper further notes that tokenizing addresses as special tokens such as [addr] or using limited loose dictionaries destroys cross-reference information. This suggests that the representational bottleneck is not only about local instruction semantics but also about preserving address-mediated program structure (Zhang et al., 24 Jul 2025).

2. Cross-reference augmented CFG representation

NeuCall represents each binary as a heterogeneous graph that preserves both control flow and cross-references into and out of the code and data sections. The starting point is a base CFG obtained by disassembling the .text section to identify basic blocks and direct control-flow edges, including fall-through, conditional and unconditional jumps, and direct calls. Callsites are modeled as special control-flow edges r_call connecting a caller block to the callee’s entry block (Zhang et al., 24 Jul 2025).

The representation is then augmented through symbolization and cross-reference extraction. The system uses angr’s symbolization to resolve immediate numeric addresses to labels in code and data sections. For each code-to-data reference, such as mov rax, [0x401234], it adds an edge r_c2d from the referencing basic block v_c to a newly created data node v_d. For data-to-code references, such as function pointers stored in .data, it adds edges r_d2c from data node v_d to a basic-block node v_c. For code-to-code references outside the normal CFG, such as jump tables, it adds special edges r_cc between code nodes. Data-to-data edges r_dd are also included when one data item references another, although such edges are described as rare (Zhang et al., 24 Jul 2025).

The formal graph is defined by

V=VcVd,V = V_c \cup V_d,

where VcV_c is the set of basic blocks and VdV_d is the set of data-section objects. The relation set is

R={rt,rcall,rc2d,rd2c,rcc,rdd},R = \{r_t, r_{call}, r_{c2d}, r_{d2c}, r_{cc}, r_{dd}\},

where r_t denotes default CFG edges for fall-through and direct jumps. Edges satisfy

EV×R×V,E \subseteq V \times R \times V,

and an element (vi,r,vj)E(v_i, r, v_j) \in E denotes a type-rr edge from viv_i to vjv_j. The augmented CFG is denoted

G=(V,E,R)G = (V, E, R)

or, equivalently,

VcV_c0

This construction is intended to preserve semantic information that standard CFG-only or token-sequence representations omit (Zhang et al., 24 Jul 2025).

A notable implication of this design is that addresses are not treated merely as lexical items. They become graph structure, enabling the model to exploit relationships among callsites, code blocks, jump tables, and data-resident function pointers. The ablation results reported later in the paper are consistent with the view that these cross-references contribute materially to prediction quality.

3. Compiler-level supervision and training-pair generation

NeuCall avoids noisy dynamic traces by extracting ground-truth indirect-callsite-to-callee pairs at compile time using TyPro, an LLVM-CFI plugin that propagates type information forward. TyPro performs inter-procedural type propagation on function pointers and associates each indirect callsite with a refined set of callees whose argument and return types match the propagated types (Zhang et al., 24 Jul 2025).

The training-pair generation workflow relies on source-level instrumentation and controlled linkage. Unique labels are inserted at each indirect callsite and function entry, after which the program is compiled and linked with a custom linker script that resolves labels to final binary addresses. The result is a one-to-many mapping from indirect callsite address to callee addresses. The paper characterizes this mapping as having high precision, with few false positives, and high recall, with few false negatives, because it leverages full IR-level type information rather than approximate heuristics (Zhang et al., 24 Jul 2025).

The dataset assembled through this process comprises 2680 stripped binaries drawn from GitHub and the Arch User Repository, compiled at optimization levels O0–O3 for the x86_64 architecture. From these binaries, the authors extract 350K functions, 36K indirect calls, and validate 704K indirect-callsite–callee pairs (Zhang et al., 24 Jul 2025).

The significance of this supervision pipeline is methodological. Earlier ML systems are criticized for low-quality training pairs; NeuCall instead constructs labels using compiler-level provenance before stripping and deployment. A plausible implication is that the reported performance gains depend not only on the graph encoder but also on the quality of the supervisory signal. The paper’s framing presents both components as necessary: clean labels for learning and a representation expressive enough to exploit them.

4. Relational graph neural architecture

NeuCall embeds the augmented CFG VcV_c1 with a relational graph convolutional network. Each node VcV_c2 is assigned an initial feature VcV_c3 assembled from several components. For basic-block nodes, instruction embeddings are obtained with PalmTree, described as BERT-based, which converts each basic block’s instructions into a fixed-length vector, with truncation at 70 instructions. Two scalar features—the normalized block address and the normalized function address—are appended to that instruction embedding. For data nodes, the initial feature is the normalized address of the data item. In addition, the model computes Laplacian positional encoding by taking the top-VcV_c4 eigenvectors of the graph Laplacian, treating VcV_c5 as undirected, and appending these vectors to VcV_c6 so that each node carries positional information within the graph (Zhang et al., 24 Jul 2025).

The layer-wise relational message-passing update for layer VcV_c7 is

VcV_c8

where VcV_c9 is the set of edge-relation types, VdV_d0 is the set of neighbors of VdV_d1 connected via relation VdV_d2, VdV_d3 is the normalization constant, VdV_d4 are relation-specific weight matrices, VdV_d5 is a self-loop weight, and VdV_d6 is ReLU or another nonlinear activation. Hyperparameter tuning found VdV_d7 R-GCN layers to be optimal, after which each node has final embedding VdV_d8 (Zhang et al., 24 Jul 2025).

The design directly reflects the graph schema. Relation-specific parameters allow the model to distinguish, for example, ordinary control-flow edges from code-to-data references or jump-table-like code-to-code links. This suggests that NeuCall treats cross-reference semantics not as incidental context but as typed evidence relevant to call-target inference.

5. Pair scoring, loss, and inference procedure

Training is formulated as link prediction between indirect callsites and candidate function-entry nodes. For each binary, the set of indirect-callsite blocks is denoted

VdV_d9

and the set of function-entry blocks is

R={rt,rcall,rc2d,rd2c,rcc,rdd},R = \{r_t, r_{call}, r_{c2d}, r_{d2c}, r_{cc}, r_{dd}\},0

Positive pairs R={rt,rcall,rc2d,rd2c,rcc,rdd},R = \{r_t, r_{call}, r_{c2d}, r_{d2c}, r_{cc}, r_{dd}\},1 are constructed for each true target R={rt,rcall,rc2d,rd2c,rcc,rdd},R = \{r_t, r_{call}, r_{c2d}, r_{d2c}, r_{cc}, r_{dd}\},2 obtained from TyPro, while an equal number of negative pairs R={rt,rcall,rc2d,rd2c,rcc,rdd},R = \{r_t, r_{call}, r_{c2d}, r_{d2c}, r_{cc}, r_{dd}\},3 are sampled from R={rt,rcall,rc2d,rd2c,rcc,rdd},R = \{r_t, r_{call}, r_{c2d}, r_{d2c}, r_{cc}, r_{dd}\},4 to balance the classes (Zhang et al., 24 Jul 2025).

For each pair R={rt,rcall,rc2d,rd2c,rcc,rdd},R = \{r_t, r_{call}, r_{c2d}, r_{d2c}, r_{cc}, r_{dd}\},5, a two-layer MLP takes the concatenation R={rt,rcall,rc2d,rd2c,rcc,rdd},R = \{r_t, r_{call}, r_{c2d}, r_{d2c}, r_{cc}, r_{dd}\},6 and outputs

R={rt,rcall,rc2d,rd2c,rcc,rdd},R = \{r_t, r_{call}, r_{c2d}, r_{d2c}, r_{cc}, r_{dd}\},7

interpreted as the probability that R={rt,rcall,rc2d,rd2c,rcc,rdd},R = \{r_t, r_{call}, r_{c2d}, r_{d2c}, r_{cc}, r_{dd}\},8 is a callee of R={rt,rcall,rc2d,rd2c,rcc,rdd},R = \{r_t, r_{call}, r_{c2d}, r_{d2c}, r_{cc}, r_{dd}\},9. The loss is binary cross-entropy over positive and negative pairs:

EV×R×V,E \subseteq V \times R \times V,0

The R-GCN and MLP are trained end-to-end with Adam, learning rate EV×R×V,E \subseteq V \times R \times V,1, dropout EV×R×V,E \subseteq V \times R \times V,2, and balanced sampling (Zhang et al., 24 Jul 2025).

Inference proceeds by constructing the new binary’s augmented graph EV×R×V,E \subseteq V \times R \times V,3, computing node embeddings for all nodes, and then scoring all address-taken function entries EV×R×V,E \subseteq V \times R \times V,4 for a given indirect callsite EV×R×V,E \subseteq V \times R \times V,5. Targets can be predicted either by ranking candidates according to EV×R×V,E \subseteq V \times R \times V,6 or by thresholding at EV×R×V,E \subseteq V \times R \times V,7 (Zhang et al., 24 Jul 2025).

A common misconception in indirect-call resolution is that once a good graph encoder is available, candidate generation and training supervision are secondary. NeuCall’s formulation does not support that view. The method combines a graph encoder, a callsite-callee pair classifier, and a compiler-derived labeling pipeline; the reported system is the composition of all three.

6. Empirical results, ablations, and downstream significance

Evaluation is performed on the 2680 stripped x86_64 binaries described above, with train/validation/test partitioning at project granularity so that no project appears in more than one split. The split ratio is 80%/10%/10%. The reported metrics are Precision, Recall, F1, and AUROC (Zhang et al., 24 Jul 2025).

NeuCall achieves F1 = 95.2%, Precision = 97.1%, Recall = 93.3%, and AUROC = 98.3%. The state-of-the-art baseline is Callee, re-implemented and fine-tuned on the same data, which achieves F1 = 89.9%. The paper therefore presents NeuCall as outperforming prior ML-based indirect-call resolution on this benchmark (Zhang et al., 24 Jul 2025).

The ablation studies isolate the role of graph augmentation and positional encoding. Using reverse edges only yields F1 = 91.5%. Using data nodes with c2d+d2d edges yields F1 = 85.1%. Using code-cross-reference edges only yields F1 = 85.2%. Using all cross-reference features but no positional encoding yields F1 = 93.7%. Adding Laplacian positional encoding restores performance to F1 = 95.2%, and the paper notes that this improves precision at slight recall cost (Zhang et al., 24 Jul 2025). These results suggest that neither code references nor data references alone suffice; the best performance arises from the full cross-reference augmentation together with positional structure.

The method is also reported to be robust across optimization levels, with F1 remaining at least 93.6% across O0–O3. In a case study on binary-only CFI using the Average Indirect Call Targets metric, NeuCall’s predicted target sets are described as on average 80% closer to LLVM-CFI’s precision than Callee’s sets, thereby reducing over-approximation (Zhang et al., 24 Jul 2025).

The downstream applications enumerated in the paper follow from producing more complete inter-procedural CFGs. With high-precision indirect-call resolution, static analyses such as taint analysis, vulnerability scanning, and program slicing can become more sound because fewer edges are missing and more precise because fewer spurious edges are introduced. Correct call targets also support binary rewriting and recompilation tasks, including safe instrumentation, inline caching, and re-optimization of stripped binaries. In control-flow integrity, refined target sets enable stronger binary-only CFI policies with lower overhead and higher security. In malware analysis and reverse engineering, more accurate call graphs can accelerate deobfuscation, function matching, and vulnerability discovery (Zhang et al., 24 Jul 2025).

Taken together, the reported evidence supports a specific interpretation of NeuCall’s contribution. It does not treat indirect-call resolution as a purely sequence-modeling problem or as a purely type-matching problem. Instead, it combines compiler-level type-propagated labels with a graph representation that explicitly encodes control flow and cross-references, and trains a relation-aware GNN to perform call-target prediction. Within the scope of the reported dataset and evaluation protocol, this combination is what yields the stated improvement over prior ML-based approaches (Zhang et al., 24 Jul 2025).

Definition Search Book Streamline Icon: https://streamlinehq.com
References (1)

Topic to Video (Beta)

No one has generated a video about this topic yet.

Whiteboard

No one has generated a whiteboard explanation for this topic yet.

Follow Topic

Get notified by email when new papers are published related to NeuCall.