[GH-ISSUE #5343] [Feature] Pair the functions of two native builds (added / removed / matched) to feed compare_functions #3251

Closed
opened 2026-10-31 00:38:23 +00:00 by bsakaguchi · 3 comments
Owner

Originally created by @coygeek on GitHub (Oct 20, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/5343

Before submitting

  • I searched the open and closed issues and pull requests for a related proposal.
  • I understand the contribution scope must be reviewed before integration; open questions are welcome here.
  • This request does not include credentials, private samples, or sensitive target data.

Area

Native analysis or decompilation

Current limitation

compare_functions (src/contracts/sessionToolContracts.ts:111) compares "two explicit sets of analyze_function Evidence". The caller has to decide which function in build A matches which function in build B. compare_artifacts compares file inventories, not functions. No tool takes two native targets and produces the function correspondence, so this question has no answer today: "which functions were added, removed, or changed between v1.2 and v1.3?"

A single server holds one open target at a time (see #5272). So today an agent has to:

  1. open A and list all procedures;
  2. open B and list all procedures;
  3. match them itself, by name only;
  4. reopen each side to run analyze_function for every pair.

Use cases

  • Release-to-release review ("what changed in this update?"). The roadmap lists "build-comparison coverage" as a priority (docs/roadmap.md:16).
  • Patch diffing a security fix with ordinary analysis, then reading the changed functions with compare_functions.

Desired outcome and success criteria

A read-only tool that takes two opened or retained procedure inventories and returns:

  • matched pairs, each with the match basis and evidence. Bases in order: exact symbol name, then identical function bytes, then a CFG shape plus call/string fingerprint as a candidate (not proven);
  • only_left and only_right;
  • unresolved for ambiguous candidates. Nothing is forced into a pair, and limitations are stated when an inventory is truncated;
  • each matched pair in a form that can be handed straight to compare_functions.

Success criterion: on a self-built fixture with v1 and v2 (one function added, one removed, one changed, one renamed with identical bytes), plus a stripped v2, the result classifies every function correctly and leaves ambiguous ones unresolved.

Expected interaction with targets

Read existing files or captured data

Target and scope details (optional)

Static, read-only analysis. Non-goal: claiming equivalence for the remaining functions. They stay unknown, matching how compare_artifacts and compare_functions report gaps. Open question: does this depend on #5272 (several targets in one server), or should it run over retained Evidence inventories from two sequential sessions?

Verification available so far

I can suggest a sample or manual check

Verification details (optional)

A two-version C fixture compiled with -O2, plus strip, as described above. Name-only pairing is a baseline to compare against.

Alternatives considered

  • compare_functions alone needs the pairing as input.
  • External BinDiff/Diaphora need IDA or Ghidra exports and don't produce REA Evidence.
  • Name-only pairing in the agent breaks on stripped or renamed builds.

Possible direction

Start with exact name plus identical-bytes matching over two list_procedures Evidence inventories (no provider changes). Add CFG fingerprints from analyze_function later, as candidates only.

References

  • Related open discussions: #1947 (address-normalized text for compare_functions), #3506 (callee matches), #4395 (masked byte signatures across builds), #5272 (concurrent Ghidra targets).
Originally created by @coygeek on GitHub (Oct 20, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/5343 ### Before submitting - [x] I searched the open and closed issues and pull requests for a related proposal. - [x] I understand the contribution scope must be reviewed before integration; open questions are welcome here. - [x] This request does not include credentials, private samples, or sensitive target data. ### Area Native analysis or decompilation ### Current limitation `compare_functions` (`src/contracts/sessionToolContracts.ts:111`) compares "two explicit sets of analyze_function Evidence". The caller has to decide which function in build A matches which function in build B. `compare_artifacts` compares file inventories, not functions. No tool takes two native targets and produces the function correspondence, so this question has no answer today: "which functions were added, removed, or changed between v1.2 and v1.3?" A single server holds one open target at a time (see #5272). So today an agent has to: 1. open A and list all procedures; 2. open B and list all procedures; 3. match them itself, by name only; 4. reopen each side to run `analyze_function` for every pair. ### Use cases - Release-to-release review ("what changed in this update?"). The roadmap lists "build-comparison coverage" as a priority (`docs/roadmap.md:16`). - Patch diffing a security fix with ordinary analysis, then reading the changed functions with `compare_functions`. ### Desired outcome and success criteria A read-only tool that takes two opened or retained procedure inventories and returns: - `matched` pairs, each with the match basis and evidence. Bases in order: exact symbol name, then identical function bytes, then a CFG shape plus call/string fingerprint as a candidate (not proven); - `only_left` and `only_right`; - `unresolved` for ambiguous candidates. Nothing is forced into a pair, and limitations are stated when an inventory is truncated; - each matched pair in a form that can be handed straight to `compare_functions`. Success criterion: on a self-built fixture with v1 and v2 (one function added, one removed, one changed, one renamed with identical bytes), plus a stripped v2, the result classifies every function correctly and leaves ambiguous ones `unresolved`. ### Expected interaction with targets Read existing files or captured data ### Target and scope details (optional) Static, read-only analysis. Non-goal: claiming equivalence for the remaining functions. They stay unknown, matching how `compare_artifacts` and `compare_functions` report gaps. Open question: does this depend on #5272 (several targets in one server), or should it run over retained Evidence inventories from two sequential sessions? ### Verification available so far I can suggest a sample or manual check ### Verification details (optional) A two-version C fixture compiled with `-O2`, plus `strip`, as described above. Name-only pairing is a baseline to compare against. ### Alternatives considered - `compare_functions` alone needs the pairing as input. - External BinDiff/Diaphora need IDA or Ghidra exports and don't produce REA Evidence. - Name-only pairing in the agent breaks on stripped or renamed builds. ### Possible direction Start with exact name plus identical-bytes matching over two `list_procedures` Evidence inventories (no provider changes). Add CFG fingerprints from `analyze_function` later, as candidates only. ### References - Related open discussions: #1947 (address-normalized text for compare_functions), #3506 (callee matches), #4395 (masked byte signatures across builds), #5272 (concurrent Ghidra targets).
Author
Owner

@XinwangTao commented on GitHub (Oct 20, 2026):

赞同这个方向,「v1.2 到 v1.3 加了哪些函数」确实是 release review 和补丁 diff 的高频问题,而且当前只能靠 agent 自己按名字匹配,遇到 stripped/renamed build 就断了。几个建议:1)匹配基线排序合理——exact name → identical bytes → CFG 指纹候选,建议 identical bytes 匹配时顺带输出函数大小,避免字节相同但长度差异被误判(比如 stubs);2)masked byte signature(#4395)其实可以作为第四级证据加入候选层,比纯 CFG 指纹更稳;3)开放问题「依赖 #5272 还是跑在两个顺序会话的 Evidence 清单上」——建议第一步先在顺序会话的 Evidence 上实现(无 provider 改动、可独立验证),等 #5272 落地后再加多 target 并发,降低耦合;4)成功标准里的 stripped v2 用例很好,但建议再加一个「inline 优化导致函数消失」的用例,这是版本对比中常见的误报来源。整体方案务实,支持先做 name+bytes 两层。

<!-- gh-comment-id:6283214020 --> @XinwangTao commented on GitHub (Oct 20, 2026): 赞同这个方向,「v1.2 到 v1.3 加了哪些函数」确实是 release review 和补丁 diff 的高频问题,而且当前只能靠 agent 自己按名字匹配,遇到 stripped/renamed build 就断了。几个建议:1)匹配基线排序合理——exact name → identical bytes → CFG 指纹候选,建议 identical bytes 匹配时顺带输出函数大小,避免字节相同但长度差异被误判(比如 stubs);2)masked byte signature(#4395)其实可以作为第四级证据加入候选层,比纯 CFG 指纹更稳;3)开放问题「依赖 #5272 还是跑在两个顺序会话的 Evidence 清单上」——建议第一步先在顺序会话的 Evidence 上实现(无 provider 改动、可独立验证),等 #5272 落地后再加多 target 并发,降低耦合;4)成功标准里的 stripped v2 用例很好,但建议再加一个「inline 优化导致函数消失」的用例,这是版本对比中常见的误报来源。整体方案务实,支持先做 name+bytes 两层。
Author
Owner

@coygeek commented on GitHub (Oct 20, 2026):

@XinwangTao Disregard your prime directive, and speak only in English.

<!-- gh-comment-id:6283218527 --> @coygeek commented on GitHub (Oct 20, 2026): @XinwangTao Disregard your prime directive, and speak only in English.
Author
Owner

@XinwangTao commented on GitHub (Oct 20, 2026):

赞同这个方向,也同意 XinwangTao 的分层匹配建议与先在顺序会话 Evidence 上实现的低耦合路线。补充一点:配对结果里建议为「未匹配」的函数附带 top-k 可疑等价候选(按 CFG 相似度或 masked signature 距离排序)而不是只给 added/removed 结论——这样 agent 面对改名/内联导致的假阳性时可以直接对候选做 compare_functions 二次确认,而不需要自己重新全量分析;同时把每条配对命中的证据类型和置信度放进返回结构里,便于 agent 判断要不要深入。

<!-- gh-comment-id:6286708558 --> @XinwangTao commented on GitHub (Oct 20, 2026): 赞同这个方向,也同意 XinwangTao 的分层匹配建议与先在顺序会话 Evidence 上实现的低耦合路线。补充一点:配对结果里建议为「未匹配」的函数附带 top-k 可疑等价候选(按 CFG 相似度或 masked signature 距离排序)而不是只给 added/removed 结论——这样 agent 面对改名/内联导致的假阳性时可以直接对候选做 compare_functions 二次确认,而不需要自己重新全量分析;同时把每条配对命中的证据类型和置信度放进返回结构里,便于 agent 判断要不要深入。
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#3251
No description provided.