Ghidra BSim 入门:基于特征向量与 LSH 索引的函数行为相似度搜索
BSim 是 Ghidra 内置的"行为相似度"(Behavioral Similarity)数据库技术,用于在大规模二进制集合中检索"相似但不完全相同"的函数。本文基于 Ghidra 教程 BSimTutorial_Intro.md 展开,结合 BSim 功能模块 的源码与数据模板,讲清 BSim 的工作原理、三个核心组件(BSim 客户端、BSim 数据库、Ghidra 项目)的分工,以及 PostgreSQL、Elasticsearch、H2 三种数据库后端的选择依据,帮助读者在开始实操建库与查询之前建立完整的技术认知框架。
BSim 解决什么问题
逆向分析过程中,研究者经常会遇到这样一类问题(以下即原文档列举的典型场景):
- 这个可执行文件静态链接了哪些库?
- 它与我之前分析过的另一个可执行文件共享代码吗?
- 某个可执行文件的版本 1 和版本 2 之间有什么差异?
- 在一个大规模二进制集合中,它与哪些其他可执行文件共享代码?
- 这个函数是否来自某个开源库?
BSim 正是为这类问题设计的:它提供了一种在二进制集合中搜索相似但不必完全一致的函数的方法。与基于哈希或指令编码的"精确匹配"思路不同,BSim 面向的是函数级别的"模糊匹配",因此可以跨越编译器差异、目标架构差异和源码的小幅改动。
BSim 是如何工作的:特征向量与余弦相似度
特征向量的生成
BSim 的核心思想是为二进制中的每个函数生成一个特征向量(feature vector):
- 向量由 Ghidra 的分解器(decompiler) 生成;
- 每个特征(feature)代表该函数数据流和/或控制流中的一小块内容;
- 分解器会对特征表示进行归一化,使得"不同但功能等价"的代码往往产生相同的特征;
- 常量的具体取值、寄存器名称、数据类型等属性被刻意排除在特征之外,以保证归一化效果。
官方帮助文档 BSimOverview.html 进一步说明:用于索引函数的主要特征集提取自函数数据流的简洁描述,而非机器指令的显式编码。这个数据流描述是基于 Ghidra 中间表示语言 p-code 的图结构(抽象语法树),由分解器生成,归一化后可以削弱以下因素的影响:等价的机器指令差异、存储位置(寄存器/栈/内存)差异、指令顺序差异、多种编译器变换,甚至某些刻意的混淆手段。
余弦相似度与容差
BSim 向量之间的比较使用余弦相似度(cosine similarity)。由编译器差异、目标架构差异或源码小改动引起的 foo 与 bar 两个向量之间的不一致,通常表现为向量接近但不相同,从而可以按相似度阈值筛选候选结果。帮助文档同时指出,查询时未知函数的特征集不需要与命中记录的特征完全一致,只需满足可配置的百分比即可命中——这相当于在分解器提供的"功能等价"容差之上,又叠加了一层对"功能性差异"的容差。
LSH 索引与数据库模板
BSim 向量可存储在专用数据库中。为容纳大量向量,BSim 数据库维护一个基于局部敏感哈希(locality-sensitive hashing, LSH)的索引,它大幅减少了所需的向量比较次数,从而支持快速检索。
创建数据库时需要一个数据库模板(database template),它决定了索引的具体参数。当前 Ghidra 内置两个模板量级:
- medium:面向最多约 1000 万个唯一向量的数据库;
- large:面向最多约 1 亿个唯一向量的数据库。
这一说法可以直接在仓库的数据文件里得到印证。medium_32.xml 定义了 32 位可执行文件的 medium 模板:
<dbconfig>
<info>
<name>Medium 32-bit</name>
<description>A medium sized (~10 million functions) database tuned for 32-bit executables</description>
...
</info>
<k>17</k>
<L>146</L>
<weightsfile>lshweights_32.xml</weightsfile>
</dbconfig>
而 large_32.xml 对应的 large 模板(约 1 亿函数)中 <k> 与 <L> 两个 LSH 参数分别增大为 19 和 232,引用的特征权重文件同为 lshweights_32.xml。从源码结构看,模板按位数与特征集划分,data 目录 下还提供 medium_64、large_32、medium_cpool、medium_nosize 等多个变体,覆盖 64 位目标、常量池特征集等不同场景。
"BSim" 名字的由来
可以把每个特征理解为函数行为的一小片,类似于一段源码片段。BSim 向量接近的函数通常拥有大量共同特征,即具有相似的行为。因此 "BSim" 取自 Behavioral Similarity(行为相似度)。
三个核心组件:客户端、数据库与 Ghidra 项目
使用 BSim 涉及以下组件,三者分工明确:
- BSim 客户端(BSim Client):即启用了 BSim 插件的 Ghidra 实例。逆向分析在这一端进行。
- BSim 数据库(BSim Database):存储 BSim 签名(signature),同时保存每个函数及其宿主可执行文件的元数据。特别是,它保存关联 Ghidra 程序的
ghidra://URL,但不存储反汇编或反编译后的函数体。 - Ghidra 项目(Ghidra Project):存储用于填充 BSim 数据库的已分析程序。当 BSim 查询产生匹配结果时,客户端可通过
ghidra://URL 从 Ghidra 项目中取回对应程序,进行并排(side-by-side)比对。需要注意:一个 BSim 数据库可以引用多个 Ghidra 项目。
查询 foo 与某个 BSim 数据库比对后,通常会得到若干潜在匹配;每个候选匹配都可以与 foo 在并排视图中对比,函数名等信息可从匹配项快速复制回 foo。我们常把 BSim 向量称为函数的 BSim 签名(BSim signature),上下文明确时简称签名。
三种数据库后端及其适用场景
BSim 支持三种数据库后端,各有明确的适用边界:
-
PostgreSQL
- Ghidra 发行版包含 PostgreSQL 的源码、面向 BSim 的 PostgreSQL 插件以及构建脚本;
- 从共享 Ghidra 项目(shared Ghidra projects)填充数据,即需要一个 Ghidra 服务器;
- 服务器端不支持 Windows(客户端不受此限制)。
-
Elasticsearch
- BSimElasticPlugin 扩展包含 BSim 的 Elasticsearch 插件;
- 该插件必须安装到已有的 Elasticsearch 数据库中;
- 从共享 Ghidra 项目填充数据。
-
H2
- 最简单的 BSim 使用方式:
- 由用户本机的文件支撑,无需安装数据库服务器;
- 可以快速创建并填充;
- 支持所有平台;
- 不支持大规模二进制集合或多用户场景;
- 可从本地(非共享)或共享 Ghidra 项目填充。
- 最简单的 BSim 使用方式:
源码与文档结构:如何进一步验证与深入
结合当前仓库,BSim 的实现与文档入口如下,方便读者按图索骥:
- 查询后端的实现分别位于 postgresql、elastic、file(基于文件/本地数据库的访问)等包中,另有 facade、ingest、protocol 等包负责统一访问、数据摄入与协议层;
- GUI 部分(查询对话框、结果窗体、过滤器)位于 gui 包;
- 官方帮助文档除 BSimOverview.html 外,还有 DatabaseConfiguration.html、IngestProcess.html、FeatureWeight.html 和 CommandLineReference.html 等页面,分别对应数据库配置、可执行文件摄入、特征与权重、命令行参考;
- BSim 完整教程索引见 GhidraDocs/GhidraClass/BSim/README.md,本篇一文的后续章节包括 启动 Ghidra 并启用 BSim、从 GUI 创建并填充 BSim 数据库、基本查询、命令行用法、评估匹配结果、过滤条件 与脚本及可视化。
小结
BSim 的技术链条可以概括为:分解器归一化特征向量 → 余弦相似度比较 → LSH 索引加速检索 → 按 ghidra:// URL 回源 Ghidra 项目做并排比对。理解这条链路后,再进入后续的建库(选择 medium/large 模板与合适的后端)、数据摄入和查询实操,就能清楚地知道每一步在整条链路中的位置:H2 适合个人快速试用,PostgreSQL 适合需要 Ghidra 服务器协作的团队生产环境,Elasticsearch 则适合已有 ES 集群的场景。下一步建议直接阅读 BSimTutorial_Enabling.md,按教程完成插件启用并创建第一个 BSim 数据库。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00