首页
/ Ghidra BSim 入门:基于特征向量与 LSH 索引的函数行为相似度搜索

Ghidra BSim 入门:基于特征向量与 LSH 索引的函数行为相似度搜索

2026-09-04 19:37:43作者:廉皓灿Ida

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)。由编译器差异、目标架构差异或源码小改动引起的 foobar 两个向量之间的不一致,通常表现为向量接近但不相同,从而可以按相似度阈值筛选候选结果。帮助文档同时指出,查询时未知函数的特征集不需要与命中记录的特征完全一致,只需满足可配置的百分比即可命中——这相当于在分解器提供的"功能等价"容差之上,又叠加了一层对"功能性差异"的容差。

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_64large_32medium_cpoolmedium_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 支持三种数据库后端,各有明确的适用边界:

  1. PostgreSQL

    • Ghidra 发行版包含 PostgreSQL 的源码、面向 BSim 的 PostgreSQL 插件以及构建脚本;
    • 从共享 Ghidra 项目(shared Ghidra projects)填充数据,即需要一个 Ghidra 服务器
    • 服务器端不支持 Windows(客户端不受此限制)。
  2. Elasticsearch

    • BSimElasticPlugin 扩展包含 BSim 的 Elasticsearch 插件;
    • 该插件必须安装到已有的 Elasticsearch 数据库中;
    • 从共享 Ghidra 项目填充数据。
  3. H2

    • 最简单的 BSim 使用方式:
      • 由用户本机的文件支撑,无需安装数据库服务器;
      • 可以快速创建并填充;
      • 支持所有平台;
    • 不支持大规模二进制集合或多用户场景;
    • 可从本地(非共享)或共享 Ghidra 项目填充。

源码与文档结构:如何进一步验证与深入

结合当前仓库,BSim 的实现与文档入口如下,方便读者按图索骥:

小结

BSim 的技术链条可以概括为:分解器归一化特征向量 → 余弦相似度比较 → LSH 索引加速检索 → 按 ghidra:// URL 回源 Ghidra 项目做并排比对。理解这条链路后,再进入后续的建库(选择 medium/large 模板与合适的后端)、数据摄入和查询实操,就能清楚地知道每一步在整条链路中的位置:H2 适合个人快速试用,PostgreSQL 适合需要 Ghidra 服务器协作的团队生产环境,Elasticsearch 则适合已有 ES 集群的场景。下一步建议直接阅读 BSimTutorial_Enabling.md,按教程完成插件启用并创建第一个 BSim 数据库。

登录后查看全文
热门项目推荐
相关项目推荐