SuperAPI AI Directory

binary-diff

Security & auditing

View repository

Updated 10-16 08:49

About this skill

Cross-version symbol migration (Binary Diff)

When to Use

  • A program updated and old annotations/symbols must be migrated to the new build.
  • Recovering changed functions between two versions of a stripped binary.

Scope of application

Use this skill when the task falls into the following scenarios:

  1. Kernel/driver missing PDB — You have symbols for an old version of ntoskrnl.exe, the new version's PDB has been taken down by Microsoft, and you need to use the old symbols to infer the addresses of non-exported functions in the new version
  2. Symbol migration after a program update — You have reverse engineered a program before, the program has been updated, and you don't want to reverse it all over again; use the old results to migrate in bulk
  3. Protection mechanism update — The old version has complete reverse engineering results, and the new version requires quickly locating the new offset of the same function
  4. Any binary comparison scenario with "old version has symbols + new version has no symbols"

Division of labor with other skills

Scenario What to use
Reverse engineering a binary from scratch ida-reverse/ or radare2/
Have old version results, migrate to the new version This skill
Comparing two completely different binaries BinDiff / Diaphora (traditional tools)

Core advantages

Compared with traditional solutions:

Solution Cost for 200 functions Time Accuracy
Manually opening two IDA windows to compare Free but life-draining Several hours High
BinDiff automatic matching Free Fast Medium (fails when structural changes are large)
Fully delegated to an Agent (CC/Codex) 50-100 yuan Slow High
This skill (LLM batch comparison) ~1 yuan ~10 seconds/function High

Core principles

旧版函数(有符号)          新版同一函数(无符号)
    ↓                              ↓
导出反汇编 + 伪代码          导出反汇编 + 伪代码
    ↓                              ↓
    └──────── LLM 结构化比对 ────────┘
                    ↓
         输出 YAML(符号映射表)
                    ↓
         程序化解析 → 批量应用到新版 IDB

Key points:

  • The prompt is a fixed template, filled in programmatically
  • Input and output formats are fixed, parsed programmatically
  • The LLM is only responsible for the step of "looking at two pieces of code and finding the correspondence"
  • Time cost and token cost are extremely low

Prompt template

Standard comparison Prompt

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

{procedure_for_reference}

This is the function you need to reverse-engineering:

Disassembly to reverse-engineering

{disasm_code}

Procedure code to reverse-engineering

{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.

Example:

found_vcall: # This is for indirect call to virtual function or virtual function pointer fetching.
  - insn_va: '0x180777700' # Always be the instruction with displacement offset
    insn_disasm: call [rax+68h] # Always be the instruction with displacement offset
    vfunc_offset: '0x68'
    func_name: ILoopMode_OnLoopActivate
  - insn_va: '0x180777778' # Always be the instruction with displacement offset
    insn_disasm: mov rax, [rax+80h] # Always be the instruction with displacement offset
    vfunc_offset: '0x80'
    func_name: INetworkMessages_GetNetworkGroupCount

found_call: # This is for direct call to non-virtual regular function.
  - insn_va: '0x180888800'
    insn_disasm: call sub_180999900
    func_name: CLoopMode_RegisterEventMapInternal
  - insn_va: '0x180888880'
    insn_disasm: call sub_180555500
    func_name: CLoopMode_SetSystemState

found_funcptr: # This is for non-virtual regular function pointer.
  - insn_va: '0x180666600' # Must load/reference the function pointer target address
    insn_disasm: lea rdx, sub_15BC910 # Must load/reference the function pointer target address
    funcptr_name: CLoopMode_OnClientPollNetworking

found_gv: # This is for reference to global variable.
  - insn_va: '0x180444400'
    insn_disasm: mov rcx, cs:qword_180666600 # Must load/reference the global variable
    gv_name: g_pNetworkMessages
  - insn_va: '0x180333300'
    insn_disasm: lea rax, unk_180222200 # Must load/reference the global variable
    gv_name: s_EventManager

found_struct_offset: # This is for reference to struct offset. NOTE THAT virtual function pointer should not be here! virtual function pointer should ALWAYS be in found_vcall !
  - insn_va: '0x1801BA12A' # Always be the instruction with displacement offset
    insn_disasm: mov rcx, [r14+58h] # Always be the instruction with displacement offset
    offset: '0x58'
    size: 8
    struct_name: CResourceService
    member_name: m_pEntitySystem

If nothing found, output an empty YAML. DO NOT output anything other than the desired YAML. DO NOT collect unrelated symbols.


### 变量说明

| 变量 | 来源 | 说明 |
|------|------|------|
| `{disasm_for_reference}` | 旧版 IDA 导出 | 有符号的反汇编 |
| `{procedure_for_reference}` | 旧版 IDA 导出 | 有符号的伪代码 |
| `{disasm_code}` | 新版 IDA 导出 | 无符号的反汇编 |
| `{procedure}` | 新版 IDA 导出 | 无符号的伪代码 |
| `{symbol_name_list}` | 从旧版提取 | 需要在新版中定位的符号列表 |

## 工作流

### 完整流程

```text
Step 1: 准备数据
  - 旧版二进制加载到 IDA(有 PDB/符号)
  - 新版二进制加载到 IDA(无符号)
  - 找到两个版本中相同的锚点函数(导出函数、字符串引用等)

Step 2: 批量导出
  - 从旧版导出:锚点函数的反汇编 + 伪代码(含符号名)
  - 从新版导出:同一锚点函数的反汇编 + 伪代码(无符号名)

Step 3: LLM 比对
  - 用 prompt 模板填充数据
  - 调用 LLM API(推荐:deepseek 量大便宜,超大函数切 gpt)
  - 解析返回的 YAML

Step 4: 应用结果
  - 将 YAML 中的符号映射批量应用到新版 IDB
  - 用 idapro_rename 或 IDAPython 脚本批量重命名

Step 5: 迭代
  - 第一轮迁移的函数成为新的锚点
  - 进入这些函数,继续对比内部调用
  - 重复直到覆盖所有目标函数

Anchor selection strategy

Anchor type Reliability Description
Exported functions Highest Names do not change, addresses may change
String references High String contents do not change, reference locations may change
Constants/magic numbers Medium Characteristic values do not change
Code patterns Medium Function structures are similar but addresses all change

Batch processing recommendations

  • Compare 1 function at a time (to avoid context explosion)
  • Use deepseek for medium functions (<200 lines)
  • Switch to gpt-4o or claude for very large functions (>500 lines)
  • Use concurrent calls to improve speed (10-20 concurrent)
  • Cache results to avoid repeated calls

Output format

The 5 symbol types in YAML output

Type Meaning Key fields
found_vcall Virtual function call (indirect call) vfunc_offset, func_name
found_call Direct function call insn_va, func_name
found_funcptr Function pointer reference insn_va, funcptr_name
found_gv Global variable reference insn_va, gv_name
found_struct_offset Struct offset reference offset, struct_name, member_name

Parsed application action

found_call → idapro_rename(addr=call_target, name=func_name)
found_vcall → idapro_set_comments(addr=insn_va, comment="vcall: {func_name} @ +{offset}")
found_funcptr → idapro_rename(addr=funcptr_target, name=funcptr_name)
found_gv → idapro_rename(addr=gv_addr, name=gv_name)
found_struct_offset → idapro_set_comments(addr=insn_va, comment="{struct_name}.{member_name}")

Typical scenario examples

Scenario 1: ntoskrnl.exe missing PDB

已有:ntoskrnl.exe 10.0.26100.2000 + 完整 PDB
目标:ntoskrnl.exe 10.0.26100.2605(PDB 被下架)
需求:定位 PspSetCreateProcessNotifyRoutine 的新地址

步骤:
1. 两个版本都加载到 IDA
2. 找到导出函数 PsSetCreateProcessNotifyRoutine(两个版本都有)
3. 旧版中它调用了 PspSetCreateProcessNotifyRoutine(有符号)
4. 新版中它调用了 sub_140822108(无符号)
5. LLM 一眼看出:sub_140822108 = PspSetCreateProcessNotifyRoutine
6. 批量应用

Scenario 2: Migrate after application update

已有:target.exe v1.0 的完整逆向结果(200+ 函数已命名)
目标:target.exe v1.1(所有符号丢失)
需求:批量迁移 200 个函数名

步骤:
1. 从旧版导出所有已命名函数的反汇编+伪代码
2. 在新版中通过导出函数/字符串找到对应锚点
3. 批量调用 LLM 比对
4. 解析 YAML,批量 rename
5. 迭代深入

LLM selection recommendations

Model Suitable scenarios Cost Speed
DeepSeek V3 Small to medium functions (<200 lines), batch processing Very low Fast
GPT-4o Very large functions, complex control flow Medium Fast
Claude Sonnet Medium to large functions, requires reasoning Medium Fast
Claude Opus Extremely complex functions, requires deep understanding High Slow

Recommended strategy: default to DeepSeek, automatically upgrade when context exceeds limits or results are inaccurate.

Notes

  • Do not throw the entire binary at the LLM — compare only one function at a time
  • Anchors must be reliable — if the anchor itself is wrong, everything that follows is wasted
  • Results require manual spot checks — LLMs are not 100% accurate; key symbols must be verified
  • Cache intermediate results — avoid repeated calls that waste tokens
  • Pay attention to context limits — very large functions (>1000 lines of disassembly) need to be split or a large-context model used

On-Demand Bootstrap

Tool dependencies

Tool Purpose Can be installed automatically
IDA Pro Export disassembly/pseudocode ✗ (commercial software)
Python Script execution, API calls ✓
PyYAML Parse the YAML returned by the LLM ✓(pip install pyyaml)
LLM API Execute comparison Requires API key

Description

The core of this skill does not depend on installing heavy tools; it mainly depends on:

  • IDA Pro already available (managed with the ida-reverse/ skill)
  • Python + requests/httpx (calling the API)
  • An LLM API endpoint

Routing context

Upstream entry: skills/SKILL.md(overall control),routing.md Trigger conditions: there are old-version symbols/reverse-engineering results that need to be migrated to the new version Downstream exit:

  • Need to open the binary first → ida-reverse/
  • Need to quickly scout and confirm version differences → radare2/

Peer related modules: ida-reverse/(both data export and symbol application go through IDA)

Task completion self-check (MUST pass before claiming completion)

  • Did I execute every step in the workflow (rather than just reading it)?
  • Am I based on tool-index and used real tool paths?
  • Did I produce reproducible evidence (commands/scripts/screenshots/reports)?
  • Did I complete and write back the Checklist items required by RULES?

Limitations

  • Diff quality degrades with heavy recompilation or obfuscation between versions.
  • Requires local diff tooling (e.g., BinDiff, Diaphora, radiff2).

Adapted from zhaoxuya520/reverse-skill (MIT).