# How to Perform Cross-Version Binary Symbol Migration with the binary-diff Module

> Automate cross-version binary symbol migration using the binary-diff module. Send IDA Pro exports to an LLM and apply YAML mappings to your new IDB with IDAPython.

- Repository: [ZhaoXu/reverse-skill](https://github.com/zhaoxuya520/reverse-skill)
- Tags: how-to-guide
- Published: 2026-08-17

---

**The binary-diff skill in zhaoxuya520/reverse-skill automates cross-version binary symbol migration by sending IDA Pro exports from a symbol-rich old binary and a stripped new binary to an LLM, then applying the returned YAML mappings to the new IDB with IDAPython.**

Cross-version binary symbol migration recovers meaningful names in stripped binaries by referencing known symbols from older builds. The `binary-diff` module in the [zhaoxuya520/reverse-skill](https://github.com/zhaoxuya520/reverse-skill) repository implements a lightweight, LLM-assisted pipeline designed for this exact task. It combines deterministic prompt templates, structured YAML output, and IDA Pro automation to migrate symbols one function at a time.

## Architecture of the binary-diff Migration Pipeline

The binary-diff pipeline consists of three tightly-coupled layers that move symbols from an old binary to a newer binary.

### Data Preparation Layer

The first step exports disassembly and pseudo-code from both binaries using IDA Pro. The old binary must contain known symbols, while the new binary is typically stripped. These exported blocks are fed into a fixed prompt template. The required inputs are described in [`skills/binary-diff/SKILL.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/binary-diff/SKILL.md) at lines 48-55.

### LLM Comparison Layer

A single LLM call compares the old and new function exports. By default, the skill uses **DeepSeek V3**; larger functions are automatically routed to bigger models. The LLM returns a **YAML** mapping of discovered symbol relationships. The exact prompt definition lives in [`skills/binary-diff/SKILL.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/binary-diff/SKILL.md) at lines 68-99.

### Result Application Layer

The returned YAML is parsed with **PyYAML** and applied programmatically to the new IDB using IDAPython helpers such as `idapro_rename` or `idapro_set_comments`. The mapping of YAML keys to specific actions is documented in [`skills/binary-diff/SKILL.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/binary-diff/SKILL.md) at lines 14-22.

## Cross-Version Symbol Migration Workflow

The overall workflow, from start to finish, is illustrated in [`skills/binary-diff/SKILL.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/binary-diff/SKILL.md) at lines 56-84. Follow these steps:

1. Load both binaries into IDA Pro (the old binary with symbols and the new binary without).
2. Export a single anchor function's disassembly and pseudo-code from each binary.
3. Fill the prompt template and invoke the LLM.
4. Parse the returned YAML and programmatically rename symbols in the new IDB.
5. Iterate: promoted functions become new anchors until the desired coverage is reached.

## Model Selection and Cost Optimization

As documented in [`skills/binary-diff/SKILL.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/binary-diff/SKILL.md) at lines 58-66, the skill routes functions based on size to manage cost and context limits:

- **Small functions** (< 200 lines) default to **DeepSeek V3**, costing approximately 1¢ per 200 functions.
- **Large functions** are automatically routed to **GPT-4o**, **Claude Sonnet**, or **Claude Opus**.

This one-function-per-LLM-call design keeps token usage low and avoids context overflow.

## Complete Python Example for binary-diff Automation

Below is a minimal, end-to-end Python snippet that drives the binary-diff workflow for a single function. It assumes four exported files exist: [`old_disasm.txt`](https://github.com/zhaoxuya520/reverse-skill/blob/main/old_disasm.txt), [`old_pcode.txt`](https://github.com/zhaoxuya520/reverse-skill/blob/main/old_pcode.txt), [`new_disasm.txt`](https://github.com/zhaoxuya520/reverse-skill/blob/main/new_disasm.txt), and [`new_pcode.txt`](https://github.com/zhaoxuya520/reverse-skill/blob/main/new_pcode.txt).

```python
import json, yaml, requests

# -------------------------------------------------

# 1️⃣  Load exported data (normally produced by IDA)

# -------------------------------------------------

def load_file(path: str) -> str:
    with open(path, "r", encoding="utf-8") as f:
        return f.read()

old_disasm = load_file("old_disasm.txt")
old_pcode = load_file("old_pcode.txt")
new_disasm = load_file("new_disasm.txt")
new_pcode = load_file("new_pcode.txt")

# -------------------------------------------------

# 2️⃣  Build the prompt (see SKILL.md for the exact template)

# -------------------------------------------------

prompt_template = """I have disassembly outputs and procedure code of the same function.

This is the function for reference:

**Disassembly for Reference**

```c
{disasm_for_reference}

```

**Procedure code for Reference**

```c
{procedure_for_reference}

```

This is the function you need to reverse-engineering:

**Disassembly to reverse-engineering**

```c
{disasm_code}

```

**Procedure code to reverse-engineering**

```c
{procedure}

```

What you need to do is to collect all references to "{symbol_name_list}" in the function you need to reverse-engineering and output those references as YAML.
"""

symbol_list = "PsSetCreateProcessNotifyRoutine, PspSetCreateProcessNotifyRoutine"  # example

filled_prompt = prompt_template.format(
    disasm_for_reference=old_disasm,
    procedure_for_reference=old_pcode,
    disasm_code=new_disasm,
    procedure=new_pcode,
    symbol_name_list=symbol_list,
)

# -------------------------------------------------

# 3️⃣  Call the LLM (DeepSeek V3 shown; replace URL/key as needed)

# -------------------------------------------------

api_url = "https://api.deepseek.com/v1/chat/completions"
headers = {"Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json"}

payload = {
    "model": "deepseek-coder",
    "messages": [{"role": "user", "content": filled_prompt}],
    "temperature": 0.0,
}
response = requests.post(api_url, headers=headers, json=payload)
response.raise_for_status()
yaml_text = response.json()["choices"][0]["message"]["content"]

# -------------------------------------------------

# 4️⃣  Parse the YAML output

# -------------------------------------------------

mapping = yaml.safe_load(yaml_text)

# -------------------------------------------------

# 5️⃣  Apply results to the new IDB (IDAPython example)

# -------------------------------------------------

import idaapi, idc

def rename_call(addr: int, name: str):
    idc.set_name(addr, name, idc.SN_CHECK)

for entry in mapping.get("found_call", []):
    rename_call(int(entry["insn_va"], 16), entry["func_name"])

for entry in mapping.get("found_vcall", []):
    comment = f"vcall: {entry['func_name']} @ +{entry['vfunc_offset']}"
    idc.set_cmt(int(entry["insn_va"], 16), comment, 0)

```

This script follows the exact steps described in [`skills/binary-diff/SKILL.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/binary-diff/SKILL.md) at lines 70-98 and uses the same YAML schema defined at lines 4-12.

## Key Files in the reverse-skill Repository

Understanding where binary-diff lives in the larger project helps with integration and navigation:

- **[`skills/binary-diff/SKILL.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/binary-diff/SKILL.md)** — Full skill definition, prompt template, workflow, and YAML schema.
- **[`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json)** — Registers the binary-diff skill with the router (`"skill": "binary-diff/SKILL.md"`).
- **[`skills/INDEX.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/INDEX.md)** — Human-readable index that points to the binary-diff skill page (line 13).
- **[`docs/ARCHITECTURE.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/docs/ARCHITECTURE.md)** — Shows the overall system architecture where binary-diff appears as a sub-module of the BinDiff node (line 51).
- **[`skills/reverse-engineering/tools-advanced.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/reverse-engineering/tools-advanced.md)** — Lists binary-diff among other advanced reverse-engineering tools (line 14).

## Summary

- The **binary-diff** module provides an LLM-assisted pipeline for cross-version binary symbol migration within the zhaoxuya520/reverse-skill framework.
- The workflow is split into three layers: **data preparation**, **LLM comparison**, and **result application**.
- Each function is processed individually to control token usage, with small functions defaulting to **DeepSeek V3** and large functions routing to premium models.
- The LLM returns a structured **YAML** mapping that is parsed and applied via **IDAPython** to rename symbols and set comments in the new binary.
- Iteration using promoted anchor functions extends coverage across the new binary's entire surface area.

## Frequently Asked Questions

### What inputs are required to start a binary-diff migration?

You need two sets of IDA Pro exports: disassembly and pseudo-code from a known old binary that contains symbols, and the same exports from the new stripped binary. The specific input requirements are detailed in [`skills/binary-diff/SKILL.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/binary-diff/SKILL.md) at lines 48-55.

### Why does binary-diff use one LLM call per function?

Processing one function per call keeps token usage low, prevents context-window overflow, and yields deterministic, easy-to-parse YAML output for each individual comparison. This architecture is a core design decision documented in the skill's workflow.

### Which LLM models are supported for binary-diff?

The skill defaults to **DeepSeek V3** for small functions under 200 lines. For larger functions, it automatically routes to **GPT-4o**, **Claude Sonnet**, or **Claude Opus**. You can see the exact model-selection logic in [`skills/binary-diff/SKILL.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/binary-diff/SKILL.md) at lines 58-66.

### How are the YAML results applied to the new binary?

The YAML is parsed with **PyYAML** and applied programmatically to the new IDB using IDAPython helpers. The skill references actions such as `idapro_rename` and `idapro_set_comments`, while practical scripts typically use standard APIs like `idc.set_name` and `idc.set_cmt` to rename call targets and add virtual-call comments.