【二进制静态分析工具-Binabsinspector】从入门到进阶
字数 2546 2025-08-29 22:41:24

BinAbsInspector 二进制静态分析工具从入门到进阶

1. 工具概述

BinAbsInspector 是由 Keenlab 开发的一款基于 Ghidra 的二进制静态分析工具,主要特点包括:

  • 基于 Ghidra 的中间语言 P-code 实现
  • 过程间数据流分析框架
  • 内置污点分析引擎
  • 支持多种架构:x86、x64、armv7 和 aarch64

支持的漏洞检测类型

CWE编号 漏洞类型
CWE119 缓冲区溢出(通用情况)
CWE125 缓冲区溢出(越界读)
CWE134 外部控制格式字符串使用
CWE190 整数溢出或回绕
CWE367 TOCTOU(检查时间与使用时间不一致)
CWE415 双重释放
CWE416 释放后使用
CWE426 不可信搜索路径
CWE467 对指针类型使用 sizeof()
CWE476 NULL 指针解引用
CWE676 潜在危险函数使用
CWE787 缓冲区溢出(越界写)

2. 安装与开发环境

安装方式

  • 使用官方发布的 release 版本
  • 手动构建(参考官方 README)

开发环境配置

  • 支持 IntelliJ IDEA 和 Eclipse
  • 开发指南中提供了详细的环境设置步骤

3. 核心概念

3.1 数据流分析基础

BinAbsInspector 的数据流分析基于 Ghidra 的 P-code 实现:

  • 一条汇编指令可能被翻译为多条 P-code
  • 分析是上下文敏感的
  • 支持过程内和过程间分析

3.2 分析流程

  1. analyze() - 主入口
  2. PcodeVisitor.visit() - 遍历 P-code 指令
  3. 使用 Worklist 算法进行迭代分析

过程内分析

  • 沿着控制流图(CFG)遍历函数的所有基本块
  • 分析 P-code 指令
  • 数据流到达不动点时结束

过程间分析

  • 函数调用时进行上下文切换
  • 生成当前数据流状态的拷贝作为子函数初始状态
  • 分析结束后合并子函数返回点的数据流状态

4. 关键接口与数据结构

4.1 主要类与接口

BinAbsInspector.java

  • 继承 GhidraScript 类并重写 analyze 方法
  • 关键接口:
    • public void run() - 初始化配置并调用 analyze
    • protected boolean analyze() - 设置分析入口
    • protected boolean analyzeFromAddress(Address entryAddress) - 从指定地址开始分析

关键全局数据结构

  1. GlobalState

    • 记录当前分析配置
    • 包含 currentProgram 对象和常用 API 对象
  2. FunctionModelManager

    • 管理函数模型(函数摘要)
    • 记录函数对数据流的副作用/影响
  3. CheckerManager

    • 管理漏洞检测器(Checker)

4.2 程序抽象结构设计

Aloc(抽象位置)

  • 表示五种抽象变量:
    1. 栈变量
    2. 堆变量
    3. 全局变量或数值
    4. 临时变量
    5. 寄存器变量
  • 使用 region 成员区分不同类型

AbsEnv

  • 表示程序点的数据流状态
  • 使用 JImmutableTreeMap 实现
    • Key: 抽象变量(Aloc)
    • Value: 对应的 Kset 值

KSet

  • 抽象数据流值的集合
  • 实现数据流值的插入、删除、合并等操作
  • 支持各种算术和逻辑运算
  • 为保证分析收敛,设置元素数量上限

AbsVal

  • 抽象的数据流值
  • Region 可能是全局、堆或栈

4.3 污点分析引擎

TaintMap

  • 管理污点源信息
  • 记录污点引入位置

主要成员变量

  • Source - 标识污点源
  • TaintID - 污点源唯一标识
  • MAX_TAINT_CNT - 最大污点源数量
  • taintSourceToIdMap - Source 到 TaintID 的映射

主要接口

  • getTaints() - 在指定位置引入新污点源
  • reset() - 重置 TaintMap

5. Checker 实现

5.1 Checker 管理

  • com.bai.checkers 路径下定义
  • CheckerManager 类注册各类漏洞检测器

5.2 典型 Checker 示例

CWE190 整数溢出检测

  • 检查 malloc 等函数的调用位置
  • 检查是否存在左移或乘法操作
  • 当前实现较为宽松,可能产生较多误报

CWE676 危险函数使用

  • 检测 gets、strcpy、std::cin 等危险函数
  • 在数据流分析收敛后进行检查

6. 架构扩展支持

当前支持架构

  • x86
  • x64
  • armv7
  • aarch64

添加新架构支持

  1. 修改 Architecture.java 文件
  2. 添加新架构的 SP 寄存器和 FLAG 寄存器索引
  3. 对于 MIPS32 等混合指令集架构,需考虑 ISA Mode 获取正确的 PC 地址

7. 进阶使用

7.1 自定义漏洞检测器

  1. 在 CheckerManager 中注册自定义 Checker
  2. com.bai.checkers 路径下实现 Checker 类
  3. 可选择在迭代分析过程中直接输出结果

7.2 自定义污点源

自定义污点源函数

参考 com.bai.env.funcs.externalfuncs 下的 GetsFunction:

addDefaultParam("s", PointerDataType.dataType); // 设置参数类型
setTaintedBufParamIndex(0); // 设置污点源参数索引
setReturnNewTaint(true); // 是否为不同调用生成新 TaintID

直接引入污点源

TaintMap.getTaints(addr, context, GlobalState.flatAPI.getFunctionContaining(addr));

7.3 其他高级功能

  • 识别循环结构
  • 为循环解析导致的越界读写漏洞建模
  • 增强缓冲区溢出检测(当前仅检测特定内存操作函数)

8. 总结

BinAbsInspector 是一款基于迭代数据流分析的 Ghidra 插件,具有以下优势:

  1. 代码可读性和可扩展性良好
  2. 基于 Ghidra 的强大分析能力
  3. 支持快速定制开发
  4. 填补了二进制程序静态数据流分析工具的空白

通过深入理解其核心数据结构和分析流程,安全研究人员可以高效地进行二次开发,满足各种定制化的静态分析需求。

BinAbsInspector 二进制静态分析工具从入门到进阶 1. 工具概述 BinAbsInspector 是由 Keenlab 开发的一款基于 Ghidra 的二进制静态分析工具,主要特点包括: 基于 Ghidra 的中间语言 P-code 实现 过程间数据流分析框架 内置污点分析引擎 支持多种架构:x86、x64、armv7 和 aarch64 支持的漏洞检测类型 | CWE编号 | 漏洞类型 | |---------|---------| | CWE119 | 缓冲区溢出(通用情况) | | CWE125 | 缓冲区溢出(越界读) | | CWE134 | 外部控制格式字符串使用 | | CWE190 | 整数溢出或回绕 | | CWE367 | TOCTOU(检查时间与使用时间不一致) | | CWE415 | 双重释放 | | CWE416 | 释放后使用 | | CWE426 | 不可信搜索路径 | | CWE467 | 对指针类型使用 sizeof() | | CWE476 | NULL 指针解引用 | | CWE676 | 潜在危险函数使用 | | CWE787 | 缓冲区溢出(越界写) | 2. 安装与开发环境 安装方式 使用官方发布的 release 版本 手动构建(参考官方 README) 开发环境配置 支持 IntelliJ IDEA 和 Eclipse 开发指南中提供了详细的环境设置步骤 3. 核心概念 3.1 数据流分析基础 BinAbsInspector 的数据流分析基于 Ghidra 的 P-code 实现: 一条汇编指令可能被翻译为多条 P-code 分析是上下文敏感的 支持过程内和过程间分析 3.2 分析流程 analyze() - 主入口 PcodeVisitor.visit() - 遍历 P-code 指令 使用 Worklist 算法进行迭代分析 过程内分析 : 沿着控制流图(CFG)遍历函数的所有基本块 分析 P-code 指令 数据流到达不动点时结束 过程间分析 : 函数调用时进行上下文切换 生成当前数据流状态的拷贝作为子函数初始状态 分析结束后合并子函数返回点的数据流状态 4. 关键接口与数据结构 4.1 主要类与接口 BinAbsInspector.java 继承 GhidraScript 类并重写 analyze 方法 关键接口: public void run() - 初始化配置并调用 analyze protected boolean analyze() - 设置分析入口 protected boolean analyzeFromAddress(Address entryAddress) - 从指定地址开始分析 关键全局数据结构 GlobalState 记录当前分析配置 包含 currentProgram 对象和常用 API 对象 FunctionModelManager 管理函数模型(函数摘要) 记录函数对数据流的副作用/影响 CheckerManager 管理漏洞检测器(Checker) 4.2 程序抽象结构设计 Aloc(抽象位置) 表示五种抽象变量: 栈变量 堆变量 全局变量或数值 临时变量 寄存器变量 使用 region 成员区分不同类型 AbsEnv 表示程序点的数据流状态 使用 JImmutableTreeMap 实现 Key: 抽象变量(Aloc) Value: 对应的 Kset 值 KSet 抽象数据流值的集合 实现数据流值的插入、删除、合并等操作 支持各种算术和逻辑运算 为保证分析收敛,设置元素数量上限 AbsVal 抽象的数据流值 Region 可能是全局、堆或栈 4.3 污点分析引擎 TaintMap 管理污点源信息 记录污点引入位置 主要成员变量 : Source - 标识污点源 TaintID - 污点源唯一标识 MAX_TAINT_CNT - 最大污点源数量 taintSourceToIdMap - Source 到 TaintID 的映射 主要接口 : getTaints() - 在指定位置引入新污点源 reset() - 重置 TaintMap 5. Checker 实现 5.1 Checker 管理 在 com.bai.checkers 路径下定义 CheckerManager 类注册各类漏洞检测器 5.2 典型 Checker 示例 CWE190 整数溢出检测 检查 malloc 等函数的调用位置 检查是否存在左移或乘法操作 当前实现较为宽松,可能产生较多误报 CWE676 危险函数使用 检测 gets、strcpy、std::cin 等危险函数 在数据流分析收敛后进行检查 6. 架构扩展支持 当前支持架构 x86 x64 armv7 aarch64 添加新架构支持 修改 Architecture.java 文件 添加新架构的 SP 寄存器和 FLAG 寄存器索引 对于 MIPS32 等混合指令集架构,需考虑 ISA Mode 获取正确的 PC 地址 7. 进阶使用 7.1 自定义漏洞检测器 在 CheckerManager 中注册自定义 Checker 在 com.bai.checkers 路径下实现 Checker 类 可选择在迭代分析过程中直接输出结果 7.2 自定义污点源 自定义污点源函数 参考 com.bai.env.funcs.externalfuncs 下的 GetsFunction: 直接引入污点源 7.3 其他高级功能 识别循环结构 为循环解析导致的越界读写漏洞建模 增强缓冲区溢出检测(当前仅检测特定内存操作函数) 8. 总结 BinAbsInspector 是一款基于迭代数据流分析的 Ghidra 插件,具有以下优势: 代码可读性和可扩展性良好 基于 Ghidra 的强大分析能力 支持快速定制开发 填补了二进制程序静态数据流分析工具的空白 通过深入理解其核心数据结构和分析流程,安全研究人员可以高效地进行二次开发,满足各种定制化的静态分析需求。