如何用 Function ID 从库文件创建并填充 FidDb 函数识别数据库
2026/9/9 22:35:12 网站建设 项目流程

如何用 Function ID 从库文件创建并填充 FidDb 函数识别数据库

【免费下载链接】ghidraGhidra is a software reverse engineering (SRE) framework项目地址: https://gitcode.com/GitHub_Trending/gh/ghidra

假设你有一组已经编译好的库(或目标文件),希望在 Ghidra 中建立一个自己的函数识别数据库(.fidb),让后续分析的程序能自动恢复这些库的函数名。Ghidra 的 Function ID 分析器通过计算函数体的哈希来匹配已知软件库,而随 Ghidra 分发的数据库只覆盖 Microsoft Visual Studio 在 x86 上的库。要识别其他软件,需要用 Function ID Plug-in 从当前项目中的程序创建并填充自己的数据库。下面的操作路径来自仓库中的 Function ID Plug-in 帮助文档 与 building_fid.txt。

准备库文件:导入、分析与命名

填充数据库的前提是所有要收录的函数都已经导入到某一个 Ghidra 项目(共享或非共享)中,并且完成分析。几个文档明确给出的约束:

  • 同一个 Library 内的所有函数必须来自同一个处理器模型(由 Ghidra 的 Language ID 判定),理想情况下来自单一软件组件,且用相同编译器和设置编译。
  • 单个 Library 必须一次性写入数据库;ingest 对话框只接受一个根子文件夹,过程会递归遍历该文件夹下的所有程序,但所有程序必须位于同一个根之下。
  • 每个要收录的函数必须拥有非默认函数名。Function ID 使用函数的主符号(primary symbol)作为名字,符号通常来自调试信息,但脚本或手工命名也可以。仍叫FUN_00....的函数不会被收录
  • 做分析时建议关闭Function IDLibrary Identification分析器,避免不同数据库之间的交叉污染;如果符号是 mangled 的,还要关闭Demangler分析器,让原始 mangled 符号保留到数据库里,之后在新程序上分析时由其 Demangler 分析器再还原。

FunctionIDHeadlessPrescript.java 就是为这一准备阶段写的示例脚本:它会关闭Function IDLibrary Identification以及Demangler MicrosoftDemangler GNUDemangler RustDemangler Swift分析器,并开启Scalar Operand References。文档说明它设计为作为 pre-script 选项传给analyzeHeadless命令。如果库函数分布在多个文件中(常见情况),可以用analyzeHeadless对整组文件做批量分析,参考 analyzeHeadless 文档 中的用法,例如:

analyzeHeadless <项目文件所在目录> <项目名> \ -scriptPath <ghidra_scripts目录> \ -preScript FunctionIDHeadlessPrescript.java \ -import <要导入的库文件路径>

其中尖括号内是示例占位:项目路径、项目名、脚本目录和待导入文件替换为你自己的值,其余参数形式来自analyzeHeadless文档中的示例命令。

启用 Function ID Plug-in

Plug-in 的全部功能位于 Code Browser 主菜单Tools -> Function ID下。要看到该菜单,需要先在 Code Browser 中执行File -> Configure,在Ghidra Core部分点击Configure链接,勾选FidPlugin

创建空的 FidDb

选择Tools -> Function ID -> Create new empty FidDb...,文件选择对话框中指定新数据库位置。两个限制要注意:

  • 数据库不能放在 Ghidra 安装目录根之下,因为 Ghidra 把根目录下的文件视为只读;
  • 建议以.fidb作为扩展名保持一致(非强制)。

新创建的数据库会自动被 attach(即被系统"知晓")并且处于 active 状态,尽管此时尚无任何匹配条目。

用项目中的程序填充数据库

选择Tools -> Function ID -> Populate FidDb from programs...,在弹出的对话框中填写各字段(见上图,文档示例):

字段说明
Fid Database选择要填充的数据库,必须选一个已 attach 且可写的库
Library Family Name库的名称,匹配命中时会作为注释的一部分写入目标程序
Library Version正式版本字符串,常见<major>.<minor>.<patch>形式,也可以是任意能区分版本的值
Library Variant无法放入 Version 的区分信息,通常放编译器设置
Base Library可选。指向同一数据库中已 ingest 的库,用于跨库匹配父子关系
Root Folder当前项目中存放该库全部程序的根文件夹,递归收录其下所有程序中的函数
Language必填的 4 段 Ghidra Language ID(如x86:LE:64:default),ingest 时不匹配该处理器模型的程序会被自动跳过
Compiler Specs可选的逗号分隔编译器名列表;列出后仅匹配编译规范的程序会被收录并可查询该库
Source Languages可选的逗号分隔名称列表,与程序的 "Source Languages" 属性比较,不匹配的程序会被过滤
Common Symbol File可选。文本文件,每行一个函数符号;ingest 过程会把这些符号排除在"用于消歧的子函数"考虑之外

OK后所有选定函数开始 ingest,程序与函数较多时过程可能耗时。完成后会弹出一个汇总窗口,包含 ingest 统计以及库内被调用最频繁的函数列表——这份列表可以用来为本库定制一个 Common Symbol File(building_fid.txt 记载,随 Ghidra 分发的 Windows 32 位系统代码.fidb就是生成时把 common_symbols_win32.txt 作为 "Common Symbols File" 参数传入得到的)。之后再次从该对话框构建其他库时,把定制好的符号文件填入同一参数即可。

可选:headless 方式批量创建

如果不想用 GUI,仓库提供了可同时在 GUI 和 headless 模式执行的脚本:

  • CreateEmptyFidDatabase.java:创建并 attach 一个空 FidDb,等价于 "Create new empty FidDb...",但 headless 下也能运行(CreateMultipleLibraries.java要求项目里已存在用户附加的.fidb,否则抛出Could not find any fidb files that can be populated)。
  • CreateMultipleLibraries.java:在一个根文件夹下按固定层级批量建库——距根深度为 3 的子文件夹各自成为一个库的根,脚本注释给出目录结构应为compiler, project, version, options四级,库名、版本、变体从目录路径元素派生(compiler:options组合作为 Variant)。脚本会询问目标 FidDB、Language ID,以及可选的 Common symbols file,并支持可选的重复检测;每个库 ingest 后向控制台或日志文件输出 visited/added/excluded 统计与未解析符号列表,最后调用saveDatabase保存。

headless 执行时的分析准备仍适用上一节的 prescript 做法,即通过analyzeHeadless-preScript FunctionIDHeadlessPrescript.java选项传入。

验证数据库内容

  • ingest 汇总窗口:每次 Populate 完成后直接查看统计与被调用最多的函数列表,这是文档给出的第一手完成判据。
  • Debug Search Window:启用 Function ID Debug Plug-in(同样在File -> Configure中,改到Developer部分勾选FidDebugPlugin)后,Tools -> Function ID 菜单多出调试项。Search 对话框可按 Function ID、Name(子串匹配)、Domain Path、FH(full hash)、XH(specific hash)检索当前 active 数据库中的函数记录;在搜索框输入值后按 RETURN 发起查询,Result Window 以每行一条记录展示 Library、Code Unit Size、Spec. + Size 及 Warn 列等属性。这可以核对具体函数是否已入库。

收尾与限制

  • 如果数据库经过多次增删导致磁盘占用偏大,可以运行 RepackFid.java 重新打包,消除未使用块、尽量压缩磁盘镜像(building_fid.txt 记载官方.fidb最终就是用该脚本 defragment 的)。
  • 数据库建好后,Debug Plug-in 提供Create Read-only Database动作,把可写的.fidb转成只读的.fidbf形式——文档说明.fidbf在磁盘上未压缩,分析器可直接使用,而.fidb使用前需要转换,这是最终供 Function ID 分析器直接消费的高效形式。
  • 若干边界要注意:仍叫FUN_00....的函数不会被 ingest;Compiler Specs / Source Languages 一旦填写,不匹配的程序既不会被收录,默认也不能查询该库;数据库文件不能放在安装目录根下;随 Ghidra 交付的数据库只能停用(deactivate)不能 detach,自己 attach 的数据库可以随时 detach。
  • 若发现个别函数反复误报,文档给出的后续手段是在 Debug Search Window 的 Result Window 里对单条记录切换 Force Specific、Force Relation、Auto Fail、Auto Pass 等缓解策略(详见 Function ID 帮助 的 Specialized Mitigation 一节),或通过 Ghidra 脚本按 full hash 调用setAutoFailByFullHashsetForceRelationByFullHash等接口设置后再saveDatabase

【免费下载链接】ghidraGhidra is a software reverse engineering (SRE) framework项目地址: https://gitcode.com/GitHub_Trending/gh/ghidra

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询