thxa/baseer

GitHub: thxa/baseer

一个用 C 语言编写的模块化可扩展二进制分析框架,支持通过魔数识别文件格式并进行反汇编、反编译、调试等操作。

Stars: 2 | Forks: 0

# بصير (Baseer) ![License](https://img.shields.io/badge/license-MIT-blue.svg) ![Version](https://img.shields.io/badge/version-0.3.0-green.svg) ![Language](https://img.shields.io/badge/language-C99-orange.svg) ![Platform](https://img.shields.io/badge/platform-Linux-lightgrey.svg) **بصير (Baseer)** 是一个用 C 语言编写的模块化、可扩展的二进制分析框架。 它允许开发者使用灵活的回调系统来检查、反汇编、调试和反编译二进制文件。 Baseer 使用魔数识别文件格式,并动态执行相应的处理程序。 ## 架构 ![Architecture](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/777aa1e7ae143526.png) ### 1. 核心 核心模块处理基本操作: - **打开文件**:以原始字节格式读取文件。 - **提取字节块**:将字节块加载到内存中。 - **关闭文件**:完成后释放资源。 - **处理扩展**:加载和管理各种扩展。 - **管理管道**:按顺序或并行方式将字节块传递给扩展。 ### 2. 扩展 扩展添加了高级功能: - **修复头部**:修复文件头部或顺序。 - **识别块类型**:检测字节块类型或元数据。 - **反汇编器**:将二进制转换为汇编指令。 - **反编译器**:将二进制转换为可读的源代码。 - **调试器**:动态监控和分析文件。 ## Baseer 详解 Baseer 基于回调树设计。 每种文件格式(例如 ELF、TAR 等)都由一个分支表示,该分支定义了自己的回调。 回调可以执行读取元数据、反汇编、调试或反编译等操作。 ### Baseer 架构图 ![Baseer Architecture Diagram](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/9d193c0683143527.png) ### 关键概念 - `bparser` — 保存文件信息的主解析器结构。 - `bmagic` — 定义魔数、文件类型名称以及用于解析的函数回调。 - `inputs` — 保存运行时参数和用于回调之间通信的哈希表。 - `bparser_apply()` — 为给定格式分派回调的执行。 - 回调(`bx_`)— 特定格式的处理程序(例如 `bx_elf`、`bx_tar`),用于解释命令行标志。 - 工具(`b_`)— 回调执行的操作,如 `b_debugger`、`b_disasm`、`b_elf_metadata` 等。 图中的每个分支都代表一条回调路径:从主函数 → Baseer 回调 → 格式处理程序 → 特定工具。 [文档](./docs/html) ## 使用的库 - **udis86**:用于反汇编 x86 和 x64 架构的二进制文件。 [GitHub 仓库](https://github.com/vmt/udis86) - **RetDec**:用作反编译器,将二进制文件转换为更高级的表示形式。 [GitHub 仓库](https://github.com/avast/retdec) ## 构建说明 Baseer 使用标准的 Makefile 进行编译。 ### 克隆仓库 ``` git clone https://github.com/thxa/baseer.git cd baseer ``` ### 构建 Baseer ``` cmake CMakeLists.txt make ``` ### 在二进制文件上运行 Baseer ``` ./build/baseer -m ``` ### 编译并分析文件 - 64 位 ``` cmake CMakeLists.txt && make && ./build/baseer examples/64bit_x86_64 -m | less -r ``` - 32 位 ``` cmake CMakeLists.txt && make && ./build/baseer examples/32bit_x86 -m | less -r ``` ### 要求 - GCC - CMake(>= 3.10) - Linux 环境 ### 运行测试 ``` cmake -S . -B build && cmake --build build --target check ``` ## 环境变量 | 变量 | 描述 | 默认值 | |----------|-------------|---------| | `BASEER_RETDEC_BIN` | RetDec 反编译器二进制文件的路径 | `/opt/baseer/decompiler/bin/retdec-decompiler` | | `BASEER_LOG_LEVEL` | 日志详细程度(0=错误,1=警告,2=信息,3=调试) | `2` | | `BLOCK_LENGTH` | 每行十六进制转储的字节数 | `16` | ## 安装 Baseer ### 在 Arch Linux 上安装 [Baseer on AUR](https://aur.archlinux.org/packages/baseer) 您可以使用 AUR 辅助工具(如 `yay`)从 AUR 安装 **Baseer**: ``` yay -S baseer ``` ### 卸载 要移除 **Baseer**,请使用: ``` pacman -Rs baseer ``` ### 从源码安装 要从源码安装 **Baseer**: ``` cmake CMakeLists.txt && make install ``` 要卸载: ``` cmake CMakeLists.txt && make uninstall ``` ## 使用方法 使用以下模式之一分析文件: - 显示元数据: ``` baseer -m ``` - 反汇编: ``` baseer -a ``` - 启动调试器: ``` baseer -d ``` - 启动 REPL: ``` baseer -i ``` ## 特性 - 使用 C 语言编写,速度快且底层控制能力强。 - 语言无关:可处理任何编程语言生成的文件。 - 模块化且可扩展的架构。 - 支持复杂的分析管道。 - 易于创建新扩展的 API。 ## Baseer 工作原理 当您使用目标文件运行 Baseer 时,它会: 1. 读取文件头部并检测其魔数。 2. 在 `bmagic` 数组中搜索匹配项。 3. 调用相应的回调(`bx_`)来处理文件。 4. 根据命令行标志(例如 `-m` 用于元数据,`-a` 用于反汇编,`-d` 用于调试)执行工具(`b_`)。 ### 格式注册示例: ``` bmagic magics[] = { {"ELF", ELF_MAGIC, reverse_bytes(ELF_MAGIC), bx_elf, 0}, {"TAR", TAR_MAGIC, reverse_bytes(TAR_MAGIC), bx_tar, 257}, // {"PDF", PDF_MAGIC, reverse_bytes(PDF_MAGIC), NULL, 0}, // {"PNG", PNG_MAGIC, reverse_bytes(PNG_MAGIC), NULL, 0}, // {"ZIP", ZIP_MAGIC, reverse_bytes(ZIP_MAGIC), NULL, 0}, // {"Mach-o", MACHO_MAGIC, reverse_bytes(MACHO_MAGIC), NULL, 0}, }; ``` ### 示例:ELF 扩展 以下是已构建的 ELF 扩展示例。 ``` bool bx_elf(bparser* parser, void *arg) { int argc = *((inputs*)arg)->argc; char** args = ((inputs*)arg)->args; for (int i = 2; i < argc; i++) { if (strcmp("-m", args[i]) == 0) bparser_apply(parser, print_meta_data, arg); else if (strcmp("-a", args[i]) == 0) bparser_apply(parser, print_elf_disasm, arg); else if (strcmp("-d", args[i]) == 0) bparser_apply(parser, b_debugger, arg); else if (strcmp("-c", args[i]) == 0) bparser_apply(parser, decompile_elf, arg); else fprintf(stderr, "[!] Unsupported flag: %s\n", args[i]); } return true; } ```