BinaryAnalysisPlatform/bap
GitHub: BinaryAnalysisPlatform/bap
卡内基梅隆大学开发的多架构二进制分析框架,提供反汇编、IR 提升、控制流分析、符号执行等能力,支持通过 OCaml 或 Python 插件进行深度扩展。
Stars: 2227 | Forks: 282
# 二进制分析平台
[](https://github.com/BinaryAnalysisPlatform/bap/blob/master/LICENSE)
[](https://gitter.im/BinaryAnalysisPlatform/bap?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[][docs]
[][docs]
## 目录
* [概述](#overview)
* [安装](#installation)
* [使用](#using)
* [学习](#learning)
* [贡献](#contributing)
* [赞助商](#sponsors)
## 概述
卡内基梅隆大学二进制分析平台 (CMU BAP) 是一套实用程序和库,能够对二进制程序进行分析。BAP 支持 x86、x86-64、ARM、MIPS、PowerPC,并且可以通过插件添加新架构。BAP 包括各种分析、标准解释器、微执行解释器和符号执行器。BAP 拥有自己的领域特定语言 [Primus Lisp][primus-lisp],用于实现分析、指定验证条件、建模函数(编写 stub)甚至与 SMT solver 进行交互。[toolkit][toolkit] 仓库包含了多个可以使用 BAP 实现的程序分析工具示例,可以作为(除了 [教程][bap-tutorial] 之外的)实现自定义分析的起点。BAP 可以作为一个框架使用,通过单一的 [bap][demo] 实用程序并[通过插件扩展][extending],也可以作为库[嵌入][embedding]到用户应用程序中,这些应用程序可以使用 OCaml 或任何其他使用 [C bindings][bap-bindings] 的语言编写。我们还提供了一些[针对 Python 的最小支持][bap-python],以便更容易开始学习 BAP。
BAP 在 [CMU, Cylab](https://www.cylab.cmu.edu/) 开发,由美国国防部、Siemens、Boeing、ForAllSecure 和韩国政府的拨款赞助,有关更多信息,请参见 [赞助商](#Sponsors)。BAP 在各种机构中被使用,并作为许多有趣项目的基础,其中一些如下所示:
* [CGC 冠军][cgc] [ForAllSecure Mayhem][mayhem]
* [Draper 实验室 CBAT 工具][cbat]
* [Fraunhofer FKIE CWE Checker][cwe-checker]
## 安装
### 使用预编译包
我们提供了为 Debian 和 Red Hat 衍生版打包的二进制包。对于其他发行版,我们提供了 tgz 归档文件。要在 Debian 衍生版上安装 bap:
```
wget https://github.com/BinaryAnalysisPlatform/bap/releases/download/v2.5.0/{bap,libbap,libbap-dev}_2.5.0.deb
sudo dpkg -i {bap,libbap,libbap-dev}_2.5.0.deb
```
### 从源代码安装
我们的二进制包不包含 OCaml 开发环境。如果您打算用 OCaml 编写分析,您需要使用 [opam][opam-install] 或通过克隆并直接构建本仓库来从源代码安装 BAP。推荐使用 opam 方法。安装完成后,以下三个命令应该会在新创建的 switch 中安装该平台。
```
opam init --comp=4.14.1 # inits opam and install the OCaml compiler
opam install bap # installs bap and its dependencies
eval $(opam env)` # activates opam environment
```
或者,如果您已经有一个想要安装 bap 的 switch,那么只需执行
```
opam install bap
```
`opam install bap` 命令还将尝试使用您的操作系统包管理器安装 BAP 的系统依赖项。如果由于缺少系统依赖项而失败,请尝试手动安装它,然后重复 `opam install bap` 命令。如果仍然不起作用,请不要犹豫,访问我们的 [聊天室][gitter] 寻求帮助。那里有友好的人员会很乐意为您提供帮助。
上面的说明将为您提供 BAP 的最新稳定版本。如果您对我们的滚动发布版本感兴趣(每次向 master 分支提交时都会自动更新),您可以创建一个使用我们测试仓库的新 switch
```
opam switch create bap-testing --repos \
default,bap=git+https://github.com/BinaryAnalysisPlatform/opam-repository#testing 4.14.1
opam install bap
```
添加后,`bap` 仓库将优先于稳定仓库,您将直接从“农场”获得最新采摘的 BAP 包。
如果您想手动构建 BAP,或者只是想研究 BAP 内部结构,那么您可以克隆此仓库并手动构建它。我们建议您从没有安装 BAP 的新环境开始,以防止冲突,或者更好的是使用本地 switch,例如,
```
git clone git@github.com:BinaryAnalysisPlatform/bap.git && cd bap
opam switch create . --deps-only
dune build && dune install
```
上面的代码片段将克隆 bap,创建一个新的本地 switch,安装必要的依赖项(包括系统依赖项),最后使用 dune 构建并安装 bap。或者,如果您已经有一个想要构建并安装 bap 的 switch,您可以使用
```
git clone git@github.com:BinaryAnalysisPlatform/bap.git && cd bap
opam install . --deps-only
dune build && dune install
```
将 bap 及其依赖项安装到当前选定的 switch 中。
上面的命令将构建 bap 中所有可用的包,包括像 Ghidra 或 Radare 这样的实验性包(包含在 bap-extra 元包中)。要排除这些包(或任何其他包)的开发环境,只需在创建 switch 之前删除相应的 .opam 文件(别担心,opam 稍后会重新生成它们),例如,
```
rm bap-{extra,radare2,ghidra,primus-symbolic-executor,ida}.opam
opam switch create . --deps-only
dune build && dune install
```
请注意,如果您的路径中没有 `llvm-config` 可执行文件,请运行
```
ocaml tools/configure.ml --with-llvm-config=
```
其中 `` 通常是 `llvm-config-`,例如,`llvm-config-11`。
## 使用
BAP 与 Docker 或 Git 类似,由一个名为 [bap][man-bap] 的单一命令行实用程序驱动。只需在您的 shell 中输入 `bap`,它将打印一条展示 BAP 功能的消息。`disassemble` 命令将接收一个二进制程序,对其进行反汇编,将其提升为与架构无关的中间表示,构建控制流图,最后以反汇编遍的形式应用分阶段的用户定义分析。最后,`--dump` 选项(简写为 `-d`)将以指定格式输出结果程序。这是默认命令,因此您甚至不需要指定它,例如,以下命令将反汇编并转储您机器上的 `/bin/echo` 二进制文件:
```
bap /bin/echo -d
```
请注意,与 `objdump` 不同,此命令将构建程序的控制流图。如果您只想逐一转储二进制文件的每条指令(即所谓的线性扫描反汇编器模式),那么您可以使用 `objdump` 命令,例如,
```
bap objdump /bin/echo --show-{insn=asm,bil}
```
如果您的输入是一段机器码数据块,而不是可执行文件,那么您可以使用 `raw` loader,例如,
```
bap objdump /bin/echo --loader=raw --raw-base=0x400000 --show-{insn=asm,bil}
```
raw loader 带有一些参数,如偏移量、长度和基地址,这使其成为一把瑞士军刀,您可以用它作为开启 BAP 未知格式的开罐器。raw loader 适用于所有打开文件的命令,例如,如果将 `raw` loader 与 `disassemble` 命令一起使用,即使不知道代码在二进制文件中的确切位置,BAP 仍会自动识别函数入口点并构建合适的 CFG,
```
bap /bin/echo --loader=raw --raw-base=0x400000 -d
```
如果您想手动处理字节,例如,手动输入指令编码并查看 BAP 如何反汇编它以及它具有什么语义,那么 `mc` 就是您要找的命令。它的命名源于 LLVM 中相应的实用程序,代表机器代码,并具有与 `objdump` 命令相同的接口,不同之处在于它接收的是指令的 ASCII 编码而不是二进制文件,例如,
```
bap mc --show-{insn=asm,bil} -- 48 83 ec 08
```
或者
```
bap mc --show-{insn=asm,bil} "\x48\x83\xec\x08"
```
它能识别一些输入格式(包括 `llvm-mc` 在其 `-show-encoding` 选项中使用的格式)。请查阅文档以获取更详细的信息。
## 扩展
### 编写您自己的分析
BAP 是一个基于插件的框架,如果您想开发新的分析,您可以编写一个插件,构建、安装它,它将与 BAP 的其余部分协同工作而无需任何重新编译。有许多扩展点可用于添加新分析、更改现有分析,甚至构建您自己的应用程序。我们将从一个简单的例子开始,将一个反汇编遍注册到 disassemble 命令中。假设我们要编写一个分析,用来估算二进制文件中跳转指令与总指令数的比率。我们将首先在一个空文件夹中创建一个名为 `jmp.ml` 的空文件(文件夹名称无关紧要)。接下来,使用我们喜欢的文本[编辑器][emacs]将以下代码放入其中:
```
open Core_kernel
open Bap_main
open Bap.Std
let counter = object
inherit [int * int] Term.visitor
method! enter_term _ _ (jmps,total) = jmps,total+1
method! enter_jmp _ (jmps,total) = jmps+1,total
end
let main proj =
let jmps,total = counter#run (Project.program proj) (0,0) in
printf "ratio = %d/%d = %g\n" jmps total (float jmps /. float total)
let () = Extension.declare @@ fun _ctxt ->
Project.register_pass' main;
Ok ()
```
现在我们可以使用以下命令构建、安装并运行我们的分析:
```
bapbuild jmp.plugin
bapbundle install jmp.plugin
bap /bin/echo --pass=jmp
```
让我们简要过一遍代码。`counter` 对象是一个 visitor,其状态由一对计数器组成。第一个计数器跟踪 jmp 术语的数量,第二个计数器在我们进入任何术语时递增。`main` 函数只负责运行计数器并打印输出。我们使用 [Bap_main][bap-main] 库中的 [Extension.declare][extension-declare] 函数声明我们的扩展。扩展只是一个接收上下文(可用于获取配置参数)的函数。在此函数中,我们使用 `Project.register_pass` 函数将 `main` 函数注册为一个 pass。
一个稍微复杂一点的示例以及使用 Python 的示例可以在我们的[教程][bap-tutorial]中找到。
### 使用 dune 构建插件
您还可以使用 dune 构建和安装 bap 插件。为此,您需要定义一个库并使用使用该库的 `plugin` 节。以下是 `dune` 文件模板,
```
(library
(name FOO)
(public_name OUR-FOO.plugin)
(libraries bap bap-main))
(plugin
(name FOO)
(package OUR-FOO)
(libraries OUR-FOO.plugin)
(site (bap-common plugins)))
```
上述代码片段中所有大写的部分都是占位符,您应将其替换为适合您插件的私有和公共名称。请注意,`.plugin` 扩展名不是必需的,但被视为一种良好的约定。
### 交互式 REPL
BAP 还附带了一个交互式顶层实用程序 `baptop`。这是一个类似于 shell 的实用程序,可以交互式地评估 OCaml 表达式并打印它们的值。它将为您加载 BAP 库并初始化所有插件,以便您可以交互式地探索 BAP 的广阔世界。`baptop` 实用程序还可以用作非交互式解释器,以便您可以运行您的 OCaml 脚本,例如,`baptop myscript.ml`,或者您甚至可以在文件顶部使用 sha-bang 指定它,例如,`#!/usr/bin/env baptop`。我们使用 UTop 构建了 `baptop`,但您可以轻松使用任何其他 OCaml 顶层环境,包括 `ocaml` 本身,只需加载 `bap.top` 库即可,例如,对于原生的 `ocaml` 顶层环境,请使用以下指令
```
#use "topfind";;
#require "bap.top";;
```
## 学习
我们理解 BAP 非常庞大,很容易让人迷失。我们一直在不断改进文档,确保 [BAP API][docs] 中的每一个功能都得到详尽的记录。但是,编写手册或[教程][bap-tutorial]形式的高级指南要困难得多,而且非常耗时,特别是考虑到我们的研究人员和用户的目标差异巨大。因此,我们采用逆向链的方法,更倾向于回答真实的问题,而不是过早地试图解决所有可能的问题。我们将很高兴在您的[聊天室][gitter]中看到您,该聊天室具有可搜索的、被 Google 索引的存档。
我们偶尔会向我们的[博客][blog]和 [wiki][wiki] 投稿,并鼓励大家为两者做出贡献。您还可以在 [stackoverflow][so-ocaml] 上发布您的问题,或在 [OCaml][discuss-bap] 板块讨论 BAP。我们还有一个可爱的 [discord][discord-bap] 频道,其流量比我们的 [gitter][gitter] 要少得多。
## 赞助商
* [ForAllSecure][fas]
* [Boeing][boeing]
* [DARPA VET 项目](https://www.darpa.mil/program/vetting-commodity-it-software-and-firmware)
* [Siemens AG](https://www.siemens.com/us/en/home.html)
* Institute for Information & communications Technology Promotion(IITP) grant funded by the Korea government(MSIT) (No.2015-0-00565, Development of Vulnerability Discovery Technologies for IoT Software Security)
如果您想成为赞助商或寻求更深层次的合作,请[联系我们][contact-us]。
标签:BAP, CMU, C语言绑定, Findomain, Hakrawler, JA3, MIPS, OCaml, PowerPC, Primus Lisp, Python, SMT求解器, TLS抓取, Web安全扫描, x86, 二进制分析, 二进制插桩, 云安全监控, 云安全运维, 云资产清单, 可配置连接, 多架构支持, 形式化验证, 微执行, 恶意代码分析, 无后门, 漏洞数据库, 程序分析, 符号执行, 网络安全, 解释器, 调试插件, 软件安全, 逆向工具, 逆向工程, 配置文件, 隐私保护, 静态分析