Ghidra BSim 实战教程:评估函数匹配质量并在反编译 Diff 视图中应用信息

Ghidra BSim 实战教程:评估函数匹配质量并在反编译 Diff 视图中应用信息 Ghidra BSim 实战教程评估函数匹配质量并在反编译 Diff 视图中应用信息【免费下载链接】ghidraGhidra is a software reverse engineering (SRE) framework项目地址: https://gitcode.com/GitHub_Trending/gh/ghidra本文基于 Ghidra 官方 BSim 教程的“Evaluating Matches”一节BSimTutorial_Evaluating_Matches.md系统讲解 BSim 查询结果的人工评估与“信息应用”工作流如何解读反编译并排 diff 视图中的各种高亮颜色与同步滚动行为如何通过Apply From Other Function菜单把匹配函数的名称、签名、完整数据类型安全地迁移到查询方函数以及如何利用Compare Matching Callees对调用者与被调用者成对比较。读完本篇读者将能够独立完成“BSim 匹配 → diff 验证 → 应用信息 → 递归下钻被调用者”这一逆向工程闭环并理解其中每一步在源码中的对应实现。1. 前置条件教程系列走到这一步时手头有什么在展开本篇之前先明确 BSim 教程系列见 BSim 教程总目录在前几节已经搭建好的三要素本篇的所有操作都建立在这三者之上一个剥离符号的可执行文件postgres无原始函数名一个 Ghidra 项目其中包含若干用于构建该可执行文件的带调试信息的目标文件1一个 BSim 数据库本教程中名为example内含上述目标文件的 BSim 向量签名。本篇的目标就是用 BSim 辅助逆向postgres这个剥离版本同时顺带演示反编译 diff 视图decompiler diff view的各项能力。这些视图能力的实现位于 CodeCompare 特性模块DecompilerCodeComparisonView.java 负责并排双反编译窗口的组织BSim 侧则通过 BSimSearchResultsProvider.java 的结果表提供Compare Functions等动作入口。2. 练习一发起全量查询并定位高置信度匹配2.1 操作步骤将剥离版postgres导入并分析到教程项目中沿用默认自动分析选项在 Listing 窗口按Ctrl-A选中全部函数——这是查询整个程序所有函数的最省事方式无选择时只查当前地址所在函数有选择时查所有入口点落在选择范围内的函数对 BSim 数据库example发起 BSim 查询BSim - Search Functions...或点击 Code Browser 工具栏的 BSim 图标注意后续几节练习都会复用本次查询结果。如果不关闭 BSim Search Results 窗口之后无需重复查询在结果表中按置信度confidence排序找到匹配函数为grouping_planner的那一行——postgres中对应的函数应该是默认名FUN_xxxxx对该匹配执行Compare Functions动作在并排反编译视图中检查注意匹配方函数因带有调试信息其数据类型信息明显更完整思考题为什么两个函数中double形参的位置相对其他参数不一致2.2 为什么double参数的位置会不同原文答案浮点值与整数/指针值使用两组互不相干的寄存器传递。两种排序都没有错因为它们各自都与该函数的指令一致。带调试信息的版本中调试信息记录了函数特定的签名含参数顺序Ghidra 会将其应用上去而不带调试信息的版本中反编译器是靠启发式推断函数签名的。这段答案触及了一个 BSim 用户常见的困惑即使两个函数逻辑完全一致反编译呈现的参数布局也可能不同——一个来自调试信息的“真值”另一个来自反编译启发式的“猜测”。在 diff 视图中看到参数顺序差异时不必怀疑匹配本身的有效性。关于相似性similarity与置信度confidence两个评分指标的定义与阈值取舍可参见 Basic BSim Queries 一节置信度衡量匹配的“含金量”共享稀有特征对置信度贡献更大因此按置信度排序能快速把真正有信息量的匹配排到前面。3. 反编译 Diff 视图聚焦令牌与四种高亮颜色当两个函数存在相当数量的差异时decompiler diff 面板会“五彩缤纷”。而且在两侧窗口随意点击时令牌token会不断获得或失去各种颜色的高亮。原文档对此给出了一套术语与颜色约定值得完整保留。术语聚焦令牌focused token——在任一反编译面板中点击某个令牌该令牌即成为聚焦令牌。颜色含义触发条件青色Cyan高亮两个函数之间的差异打开比较窗口后自动标注无需点击粉色Pink高亮聚焦令牌及其匹配令牌聚焦令牌在另一侧存在匹配时淡紫色Lavender高亮无匹配的聚焦令牌聚焦令牌在另一侧找不到对应令牌时橙色Orange高亮不可参与匹配的聚焦令牌该令牌天生不会被指派匹配令牌补充规则某些令牌例如空白令牌、用于变量声明的令牌永远不会被指派匹配令牌因此聚焦到它们时呈现橙色属于正常现象不代表匹配失败。3.1 源码佐证高亮颜色是可配置的选项而非硬编码从源码结构看这些颜色并非写死的常量而是 DecompilerCodeComparisonOptions.java 中注册的主题颜色绑定theme color bindings每个都有默认值和用户可覆盖的键名Focused Token Match Highlight粉色聚焦令牌的匹配Focused Token Unmatched Highlight淡紫色聚焦令牌无匹配聚焦令牌不可匹配的高亮橙色color.bg.codecompare.highlight.diff青色差异高亮。选项类在构造时通过options.getColor(KEY, DEFAULT_..._COLOR)读取配置也就是说用户在 Ghidra 的颜色选项中可以调整这些默认高亮色。具体的着色逻辑由 DiffClangHighlightController.java 执行它实现 CTokenListener在令牌状态focused / matched / unmatched / ineligible变化时驱动 C 显示层重新着色。4. 练习二锁定与解锁同步滚动4.1 默认行为同步滚动与行对齐diff 窗口默认开启同步滚动滚动一侧窗口时另一侧窗口随之滚动。其工作原理是“用左侧函数的一行去匹配右侧函数的一行”两个函数就以这些行作为对齐基准相互对齐初始对齐使用两个函数的签名行。在任一侧函数中点击时对齐行会随之变化若聚焦令牌有匹配滚动会围绕包含这对匹配令牌的行重新居中若聚焦令牌无匹配函数会以最接近聚焦令牌、且有匹配的令牌为基准重新对齐。工具栏上的锁形lock与开锁形unlock图标可以切换同步滚动的开/关练习就是分别体验这两种模式。4.2 源码佐证滚动协调器该行为的实现位于 DualDecompilerScrollCoordinator.java它监听两侧 C 显示组件的滚动与令牌聚焦事件在两侧之间传播滚动量并维护对齐关系DecompilerCodeComparisonView.java 中持有左右两个CDisplay并在令牌选中变化时调用各自的DiffClangHighlightController完成第 3 节所述的着色联动。5. 练习三把匹配信息“应用”到被查询函数5.1 三个 Apply 动作的差异如果对某个匹配满意你通常想把匹配函数右侧的信息应用到被查询函数左侧上例如函数名或函数签名。但“能安全应用多少信息”有微妙之处因此在左侧面板右键打开的 Apply From Other Function 菜单下提供了三个层次递进的动作Function Name把右侧函数的名称与命名空间应用到左侧函数。风险最低只迁移命名Function Signature应用名称、命名空间以及**“骨架”skeleton数据类型**。注意结构体与联合体的具体定义不会被迁移取而代之的是创建空的占位结构体从而避免把未验证的结构定义带入程序Function Signature and Data Types应用名称与签名并携带完整的数据类型定义。这可能会向程序导入大量数据类型考虑结构体引用其他结构体的连锁效应。警告原文强调应用“签名 完整数据类型”前必须绝对确信两侧数据类型定义完全一致。哪怕只是数据类型定义的微小改动即使 BSim 相似度达到 1.0也可能把错误的数据类型带进程序。此外对跨架构匹配应用完整数据类型同样是有问题的。5.2 练习操作由于本教程中grouping_planner的匹配来源明确同一代码库、带调试信息的目标文件可以直接应用Function Signature and Data Types到左侧函数左侧函数的签名信息会立即刷新。5.3 源码佐证Apply 动作的两种实现路径BSim 结果表与 diff 视图中的 Apply 动作背后是成对的任务类。从源码结构看NameAndNamespaceBSimApplyTask.java 对应“仅应用名称/命名空间”SignatureBSimApplyTask.java 对应“应用签名”路径二者均继承自 AbstractBSimApplyTask.java由应用后弹出的结果面板BSimApplyResultsDisplayDialog.java汇总展示。在 decompiler diff 视图中同名动作则来自 CodeCompare 模块的一组以“Matched Tokens”命名的动作类例如 ApplyCalleeSignatureWithDatatypesFromMatchedTokensAction.java对匹配的被调用者应用含数据类型的签名这些动作统一挂在 AbstractMatchedTokensAction.java 定义的菜单父项MENU_PARENT Apply From Other Function之下与教程描述的右键菜单完全对应。另外BSim Search Results 窗口的Function Matches表函数级结果表的行上也有同名的批量 Apply 动作可以对多行结果一次性应用该表的Status列会记录哪些行的匹配已经被应用过。6. 练习四成对比较被调用者Compare Matching Callees6.1 令牌匹配算法的边界令牌匹配算法把程序 A 中的一处函数调用与程序 B 中的一处调用配对时依据的是CALL指令的流入与流出数据流它完全不处理被调用者callee的函数体。这意味着调用点对上了不代表两边调用的是“同一个函数”需要显式下钻验证。6.2 操作步骤在反编译 diff 窗口的左侧面板点击一下按Ctrl-F进入查找对应源码中的 DecompilerDiffViewFindAction.java输入FUN_作为搜索词筛选出满足条件的匹配调用令牌左侧窗口的被调用者是默认名FUN_开头而右侧窗口的被调用者是非默认名且不是外部函数对其中一个匹配的调用令牌右键执行 Compare Matching Callees 动作——这会为新打开一个比较窗口比较两侧的被调用函数。该动作由 CompareFuncsFromMatchedTokensAction.java 实现菜单文本即 Compare Matching Callees继承自 AbstractMatchedCalleeTokensAction.java后者负责从一对匹配令牌中提取左右两侧的 FunctionCallSite在被调用者的比较窗口中把右侧函数的签名和完整数据类型应用到左侧函数回到调用者的 diff 视图验证更新已反映出来左侧调用点的名称/类型随之变化——这正是 BSim 工作流的精髓从调用点顺藤摸瓜逐层命名、定型被调用者。7. 练习五对同一函数评估多个候选匹配反编译 diff 窗口每个面板顶部都有一个下拉菜单用于控制该面板显示哪个函数。当你需要评估“同一个查询函数 vs 多个候选匹配”时这个下拉菜单非常有用。操作步骤在 BSim Search Results 窗口中右键点击某列表头选择Add/Remove Columns启用Matches列每行的匹配明细会以子行展开在postgres中找到两个各恰好有两个匹配的函数在 matches 表中选中对应的四行执行Compare Functions动作在打开的比较窗口中实验各面板顶部的下拉菜单切换左右两侧分别显示哪个候选函数横向对比多个候选匹配的质量。8. 小结与延伸阅读本篇教程节完成了 BSim 工作流中最关键的“人机协同”环节BSim 负责召回候选匹配反编译 diff 视图负责让差异可见青色差异、粉色/淡紫/橙色聚焦状态、可切换的同步滚动Apply 动作负责把已验证的信息安全地沉淀到被分析程序名称 → 骨架签名 → 完整数据类型风险逐级递增Compare Matching Callees 则支持沿调用链递归下钻。接下来教程将讨论Executable Results可执行文件级结果表如何从函数级匹配上升到可执行文件级匹配见 From Matching Functions to Matching Executables。与之相邻的章节还有 Overview Queries、BSim Filters 与 Scripting and Visualization。实现代码索引供深入阅读反编译比较视图与选项Ghidra/Features/CodeCompare/src/main/java/ghidra/features/codecompare/decompileDecompilerCodeComparisonView.java、DecompilerCodeComparisonOptions.java、DualDecompilerScrollCoordinator.java、CompareFuncsFromMatchedTokensAction.java等BSim 结果应用任务Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/gui/search/results/applySignatureBSimApplyTask.java、NameAndNamespaceBSimApplyTask.java特性级帮助文档Ghidra/Features/BSim/src/main/help/help/topics/BSimSearchPlugin/BSimSearch.htmlBSim 查询界面、Ghidra/Features/Base/src/main/help/help/topics/FunctionComparison/FunctionComparison.htm函数比较功能总述。原文档脚注使用 BSim 并不强制要求目标文件带有调试信息前一节的练习中已演示过无调试信息的情形但带调试信息会方便很多。需要注意应用调试信息可能会改变 BSim 签名这会对“带调试信息函数”与“不带调试信息函数”之间的匹配质量产生负面影响。↩【免费下载链接】ghidraGhidra is a software reverse engineering (SRE) framework项目地址: https://gitcode.com/GitHub_Trending/gh/ghidra创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考