re-variant
Compares malware code versions to find patches, similarities, and origins.
Installation
Paste this into Claude Code, Cursor, or any agent that can run commands.
What this skill does
What it does:
- Compares two versions of binary files to find what changed between them
- Matches functions and code blocks from one file to another using special tools
- Identifies new, deleted, or modified functions when comparing versions
- Helps find security patches by showing what code was fixed
- Traces how malware families are related by comparing their code
When to use it:
- You have two versions of the same program and want to see what changed
- You found a security patch and need to understand what bug it fixed
- You want to know if two malware samples are from the same family
- You need to check if a security fix was applied to all versions of a program
- You are studying how code gets reused across different versions
SKILL.mdShow the author's original SKILL.md (not in English)
--- name: re-variant type: atomic description: > 二进制变体/补丁对比:函数匹配、N-day 补丁 diff、变体溯源与相似度分析。 触发词:二进制对比、补丁对比、N-day、变体分析、BinDiff、函数匹配、样本相似。 --- # 二进制变体/补丁对比 ## 何时使用 / 何时不用 - 用:补丁前后对比(漏洞定位)、家族变体关联、样本溯源、N-day 分析 - 用:同源代码复用识别(共享函数/库代码判断) - 用:修复覆盖审计——多分支版本逐一对比修复样本,核对哪些版本修了、哪些没修 - 用:漏洞研究——修复前后结构与行为差异的完整还原(补丁 → 缺陷模式) - 不用:单样本深度分析(走 [[re-binary-core]] 通用路径) - 不用:无对比基线(只有单个样本、无第二版本可对比)——先走单样本路径 - 不用:行为层面比较(动态行为差异走 [[re-behavior]];本技能只比静态代码结构) - 不用:需要语义级还原的对比(先 [[re-cpp-abi]] 还原 ABI/符号语义,再回到本技能做差异定位) ## 工具准备 ### BinDiff / Diaphora(函数匹配插件) - BinDiff(Google/Zynamics 系,Windows 商业工具,官方安装包):IDA 插件为主;BinDiff 6 起官方支持 Ghidra(需 BinExport 插件导出);BinExport 亦支持 Binary Ninja——导出格式可桥接多反编译器 - Diaphora: 多平台开源(`git clone https://github.com/joxeankoret/diaphora`),IDA 插件为主(Ghidra 侧支持持续推进中) - 无 IDA 环境替代:qbindiff(Quarkslab,读 BinExport/quokka 导出)、ghidriff(headless Ghidra 对比) - 典型流程: 反编译器内 BinExport 导出 → 工具载入两样本 → 匹配 → 结果(相似度/变更集)导出为报告;BinExport 插件与反编译器版本需匹配(见 [[gotchas]]) - 验证: 插件在反编译器内可加载,能导出/导入匹配结果 ### radiff2 / rz-diff(rizin 命令行对比) - Linux: `apt install rizin` / `pacman -S rizin`;macOS: `brew install rizin`;Windows: 官方安装包 - 验证: `rz-diff --version`;radiff2 随 radare2 包(`apt install radare2` 类) - 用途: 无 GUI 的快速函数级对比与批量脚本化(见步骤 1 命令);radiff2 做字节/指令级快查(`radiff2 -s` 字节、`-C` 指令)——小文件快查用,函数级对比用 rz-diff ### readelf(符号对齐辅助) - 安装与验证见 [[re-cpp-abi]] 工具准备 - 用途: `readelf -s`(符号表/动态符号)与 `readelf -d`(动态节)做导入导出对齐与配对核对 ### 配对辅助(对比前置) - 哈希/基线: `sha256sum`;架构/编译器判定: [[re-imports]] 导入表与工具链指纹——配对前先确认可比性(同架构/同工具链,见坑 1、3) - 验证: `sha256sum --version` - 壳检查: [[re-packer-id]] 识别加壳;加壳样本先脱壳([[re-unpack-simple]])再对比——壳代码会污染匹配(见 [[gotchas]] 反例组) ## 操作步骤 按顺序执行,每步产物存档(路径 + sha256,见 [[re-triage]]);最终差异清单按 [[analysis-contract]] 数据契约传递。 1. **配对准备(先确认可比性再对比)**: - 记录基线:两样本的 sha256、架构(x86_64/ARM 等)、位数、编译器指纹(版本字符串/导入库集合,[[re-imports]]) - 可比性判定:同架构 + 同工具链 → 函数级全量匹配;跨架构/异编译器 → 降级为逻辑层对比(调用图/常量/字符串),标注局限 - 位数/字节序:32/64 位混合或大小端混合不直接比——统一到同位数同字节序再匹配 - 符号状态:strip/未 strip 决定匹配策略(未 strip 直接符号对齐,见步骤 2) 2. **函数匹配**: ```sh # 命令行快速对比(rizin 系):函数级匹配(-B 自动分析后按函数对比,含相似度列) rz-diff -B -t functions sample_v1 sample_v2 | head -30 ``` - 匹配维度:指令哈希(相同代码)、调用图(子图同构)、导入导出对齐、字符串/常量引用 - 数据引用维度:全局常量/字符串引用作函数身份指纹——重构/重排后比指令哈希稳定,跨版本匹配的可靠锚点 - 工具(BinDiff/Diaphora)输出:matched / changed / new / deleted 函数集 - 输出解读:matched 相同、changed 变化、new/deleted 功能增减——changed 进步骤 3,new/deleted 提示功能面差异,逐类给后续动作 - strip 后符号缺失:靠结构匹配(入口特征/调用模式/常量锚定)——匹配维度权重调整见坑 1 与 [[decision-tree]] - 地址差异处理:PIE/重定位后函数地址不同——按符号名/函数序对齐,不比裸地址(见坑 2) - 名称/注释迁移:工具支持把已命名函数的名称/注释迁移到匹配函数——已知样本先标注再对比,半自动还原新样本符号;迁移名称标注来源,仅作辅助锚点(见 [[gotchas]] 符号组) 3. **补丁 diff(N-day)**: - 修复前后对比 → `changed` 函数集 = 漏洞点候选 - 变更函数按语义分类:新增校验/边界处理(高优先级)> 行为变化 > 纯重构(低优先级)——按类别排序候选([[decision-tree]] 分级) - 变更函数深挖:新条件分支/新校验/新增调用([[re-ghidra]] / [[re-ida]] 反编译) - 反推漏洞:旧代码的缺陷模式(缺失校验/越界/释放后使用) - 修复模式识别:常见修复模式(长度检查/空指针检查/越界上限收紧)与缺陷模式对应归类——按模式快速筛候选函数 - 修复覆盖核对:多分支版本逐一对比修复样本,确认漏洞修复覆盖范围(哪些版本修了、哪些没修) - 产出:漏洞函数 + 缺陷模式推断(置信度标注,证据分级见 [[decision-tree]]) 4. **变体溯源**: - 家族内样本两两对比 → 相似度矩阵 → 聚类(共享函数比例阈值) - 演进链:按时间线/相似度排序样本(早期 vs 晚期变体) - 共享独有函数 = 家族标志(与 [[re-attribution]] 能力证据衔接) - 独有函数判定:先算家族内共享集合,再取外族样本缺失的函数为家族标志——避免把通用代码当标志 - 关联强度:共享独有函数数量 + 相似度分布综合判定,单项指标不做唯一依据 - 样本量控制:家族样本多时两两矩阵 O(n²)——先按特征(架构/大小/导入集)粗聚类,再在簇内细比 - 阈值校准:相似度分数先人工抽查校准再定聚类线(见坑 5),避免虚高关联 5. **输出差异清单与核查**: - 格式:变更函数表(函数名/地址/变更类型/相似度)+ 结论 - 按 [[analysis-contract]] 数据契约传递(下游消费) - 防误报核查:排除共享库代码([[re-imports]] 依赖清单对照)、异编译器复检(同源码不同编译差异)、跨工具交叉验证([[decision-tree]] 分级) - 报告可复现:差异清单附工具与版本、相似度阈值、排除规则;重要结论存匹配导出文件 + 反编译人工复核记录 ## 跨域联合 - [[re-binary-core]] 网关:本技能归属(选择树「补丁/N-day 对比」分支) - [[re-ghidra]] / [[re-ida]]:反编译底座(变更函数深挖) - [[re-attribution]]:变体关联的能力证据衔接 - [[re-imports]]:导入表/工具链指纹(配对可比性与共享库排除) - [[re-cpp-abi]]:符号语义还原(语义级对比前置) - [[re-packer-id]] / [[re-unpack-simple]]:加壳样本先脱壳再对比(壳代码污染匹配) - [[analysis-contract]]:差异清单按数据契约传递 ## 常见坑与陷阱 - **编译器差异干扰匹配**:现象——同源码不同编译器编译被判不相似;原因——优化/代码生成差异;对策——用调用图与常量引用加权,降低指令哈希权重 - **strip 后符号缺失**:现象——函数名全无;原因——符号剥离;对策——结构匹配(入口特征/调用模式)、导入表锚定 - **跨架构对比降级**:现象——x86 vs ARM 匹配率低;原因——指令集不同;对策——只比逻辑层(调用图/常量/字符串),标注跨架构局限 - **大量相似导致误关联**:现象——共享库代码导致虚高相似度;原因——公共依赖(libc/框架);对策——排除共享库符号,只比业务代码([[re-imports]] 依赖对照) - **补丁 diff 定位偏差**:现象——changed 函数多,漏洞点被淹没;原因——补丁含重构;对策——按变更语义过滤(新增校验/边界处理优先) - **裸地址对比失效**:现象——同一函数被报为不同;原因——PIE/重定位/版本差异导致地址漂移;对策——按符号/函数序对齐,不比裸地址 - **「没 diff 出来」≠「没修」**:现象——补丁对比无 changed 函数;原因——修复内联进相邻函数或跨函数重组;对策——扩大对比面(含内联展开后的指令哈希),结合版本历史核对 - **名称迁移污染**:现象——新样本函数名看似已知;原因——迁移自匹配来源而非真实符号;对策——迁移名称标注来源,仅作辅助锚点,关键函数过反编译确认 - **符号表被伪造**:现象——符号名齐全但结构对不上;原因——混淆/反分析工具改名(伪造符号);对策——符号对齐结果过结构确认(调用模式/常量),不信符号名本身 - **只比 .text 的盲区**:现象——函数匹配全相同但行为不同;原因——数据段差异(配置/常量表)被排除在对比范围外;对策——数据引用维度纳入匹配,常量表/配置结构单独比对 - 决策分支(可比性/匹配层级/候选排序)见 [[decision-tree]];匹配算法与工具边界见 [[gotchas]]
Ships with 2 supporting files:
- references/decision-tree.md
- references/gotchas.md
Mirrored from the author's public source. Install counts from the open skills registry.