Files

3.7 KiB
Raw Permalink Blame History

二进制变体/补丁对比方法论坑与边界

匹配算法组(误判来源)

  • 指令哈希受编译差异影响:同源码不同优化等级/编译器版本,指令级哈希就变——按指令哈希判「不同」不等于「逻辑不同」,权重低于调用图与常量
  • 调用图受内联/拆分影响:编译器内联后函数边界漂移,调用图对比会拆错对应关系——匹配失败先怀疑内联,扩大匹配粒度或按常量锚定
  • 相似度分数不承载语义:高分可能只是共享代码/模板实例化;低分也可能是被刻意改写的同源逻辑——分数只作排序依据,语义靠人工复核
  • 跨架构匹配率必然低:指令集不同导致指令级维度全部失效——只比逻辑层(调用图/常量/字符串),并标注跨架构局限
  • 模板/泛型实例化干扰:C++ 模板实例化的多个函数高度相似——按模板参数区分实例,避免把实例化当家族标志

符号与地址组

  • strip 后无符号锚点:函数名全无时按入口特征/调用模式/常量匹配——错误率高,需阈值校准与人工抽查
  • 地址漂移别比裸地址:PIE/ASLR/重定位/版本构建差异都会移动函数地址——按符号/函数序对齐;版本间比较先归一化节区布局
  • 符号名可能误导:strip 不彻底的残留符号、伪造符号(混淆工具改名)会把不同函数粘在一起——符号对齐结果仍要过一遍结构确认
  • 导入表是稳定锚点但非全量:导入函数对齐可靠,但内部函数不出现——导入对齐只作辅助维度,不能替代函数级匹配

工具差异组

  • BinDiff 与 Diaphora 算法不同,结果可能不一致:匹配策略(指令哈希 vs 图同构的权重)不同——冲突时人工复核,一致性高时证据更强
  • BinExport 版本与反编译器版本需匹配:BinExport 插件与 IDA/Ghidra 版本严格绑定,版本错配导出失败或结果异常——先核对版本再导出
  • rz-diff -B 消耗分析时间:-B 先自动分析两个二进制(反汇编+函数识别),大文件耗时长——先用 -t functions 限定范围,大批量用脚本分批
  • 大二进制内存压力:全函数图对比在超大二进制(内核/大型框架)上内存占用高——按节区(如 .text)分段对比,或增大工具内存
  • qbindiff/ghidriff 的结果格式差异:开源替代输出 CSV/BinDiff 格式不等——下游消费前统一格式(按 re-analyze/analysis-contract)

反例与边界组

  • 共享库虚高相似度:两个无关样本都链接同一 libc/框架,共享函数比例虚高——排除共享库符号(re-imports 依赖对照)再算相似度
  • 「没 diff 出来」≠「没修」:修复可能内联进相邻函数、跨函数重组、或只改常量——扩大对比面(含内联展开)并核对版本历史
  • changed 多 ≠ 漏洞多:补丁常夹带重构/平台适配——按变更语义过滤(新增校验/边界处理优先),重构类排除
  • 变体「相似」≠「同源」:同源代码跨编译器、跨平台重编译后相似度下降;刻意改写(加花指令/常量混淆)也降——溯源结论需多证据(时间线/独有函数/行为侧)闭合
  • 单工具结论不跨工具复现:只用一个工具出的匹配,换工具可能完全不同——重要结论至少两个工具或人工复核

使用注意

  • 样本来源不可信时在沙箱内处理(re-sandbox);对比是静态操作,动态确认走对应技能
  • 结论按 decision-tree 分级标注,并注明工具版本、阈值与排除规则