1 个不稳定发布
| 0.1.0-rc.5 | 2022年10月29日 |
|---|
#11 in #souffle
34KB
293 行
treeedb
treeedb 通过生成表示程序AST的Soufflé类型和关系,使在 Soufflé Datalog 中编写源级程序分析变得容易。首先,treeedb 生成表示程序AST的Soufflé类型和关系。然后,treeedb 解析源代码并发出填充这些关系的事实。
treeedb 目前支持以下语言的解析
- C
- C#
- Java
- JavaScript
- Rust
- Soufflé
- Swift
treeedb 的解析器和AST基于 tree-sitter 语法,并且很容易 添加对任何具有tree-sitter语法的语言的支持。
treeedb 的名字是 "tree-sitter" 和 "EDB" 的组合,其中 EDB 代表 "扩展数据库",指的是Datalog程序中的事实集。
安装
您需要为每个要分析的编程语言准备两个工件
- 一个包含定义AST的类型和关系的Soufflé文件
- 解析该语言并发出事实的可执行文件
例如,对于Java,这些分别称为 treeedb-java.dl 和 treeedb-java。
要实际分析一些代码,您还需要 安装Soufflé。
从发布版本安装
转到 发布页面,下载与您要分析的语言相关的工件。预构建的可执行文件是静态链接的,但目前 仅 可用于Linux。
从crates.io构建
您可以从 crates.io 构建发布版本。您需要Rust编译器和 Cargo 构建工具。 rustup 使获取这些工具变得非常容易。然后,要为 <LANG> 语言安装工具,运行
cargo install treeedb-<LANG> treeedbgen-souffle-<LANG>
这将把二进制文件安装到 ~/.cargo/bin。要生成Datalog文件,运行 treeedbgen-souffle-<LANG> 二进制文件。
不幸的是,与Java相关的二进制文件目前还未在crates.io上提供。
从源代码构建
要从源代码构建,您需要Rust编译器和Cargo构建工具。《a href="https://rustup.rs/" rel="noopener ugc nofollow">rustup使获取这些变得非常简单。
然后,获取源代码
git clone https://github.com/langston-barrett/treeedb
cd treeedb
最后,构建所有内容
cargo build --release
您可以在target/release中找到treeedb-<LANG>二进制文件。要生成Datalog文件,运行相应的treeedbgen-souffle-<LANG>二进制文件。
示例:分析Java代码
要跟随此示例,请按照Java的安装说明进行操作。然后,创建一个名为Main.java的Java文件
class Main {
public static void main(String[] args) {
int x = 2 + 2;
}
}
(本节中显示的文件也可在examples/java/中找到。)
创建一个名为const-binop.dl的Datalog文件,其中包含treeedb-java.dl,并包含一个用于查找常量值二进制表达式的规则
#include "treeedb-java.dl"
.decl const_binop(expr: JavaBinaryExpression)
const_binop(expr) :-
java_binary_expression(expr),
java_binary_expression_left_f(expr, l),
java_binary_expression_right_f(expr, r),
java_decimal_integer_literal(l),
java_decimal_integer_literal(r).
.decl show_const_binop(text: JavaNodeText)
show_const_binop(text) :-
const_binop(expr),
java_node_text(expr, text).
.output const_binop(IO=stdout)
.output show_const_binop(IO=stdout)
生成输入文件(node.csv和field.csv)
treeedb-java Main.java
最后,使用Soufflé运行分析
souffle const-binop.dl
您将看到类似以下内容
---------------
const_binop
===============
94001952741472
===============
---------------
show_const_binop
===============
2 + 2
===============
深入挖掘
要查看可用的类型和关系名称,请查看treeedb-<LANGUAGE>.dl。如果某个类型或关系对应于语言的一部分并不明显,请查看tree-sitter语法(例如,Java中的tree-sitter-java存储库中的grammar.js)。
动机与与其他工具的比较
在用Datalog编写程序分析之前,您需要弄清楚(1)如何将程序表示为关系,以及(2)如何将程序导入到这种表示中。最先进的Datalog项目都是“手工”完成这些操作的。
- cclyzer++有一个“模式”目录(1)和事实生成器(2)。
- Doop有一个很大的imports.dl文件(1)和多种生成器(2)。
- ddisasm有gtirb-decoder(2)。
- securify有
analysis-input.dl(1)。
编写这些表示和导入工具需要花费宝贵的时间,并会分散编写分析的工作。`treeedb`旨在自动化它,与这些工具处于同一细分市场。
存储库结构
treeedb:从tree-sitter解析树生成Datalog事实treeedb-c:从C源代码生成Datalog事实treeedb-csharp:从C#源代码生成Datalog事实treeedbgen:解析tree-sitter语法中的node-types.jsontreeedbgen-souffle:从tree-sitter语法生成Soufflé类型和关系treeedbgen-souffle-c:从C的tree-sitter语法生成Soufflé类型和关系treeedbgen-souffle-csharp:从C#的tree-sitter语法生成Soufflé类型和关系treeedbgen-souffle-java:从Java的tree-sitter语法生成Soufflé类型和关系treeedbgen-souffle-javascript:从JavaScript的tree-sitter语法生成Soufflé类型和关系treeedbgen-souffle-rust:从Rust的tree-sitter语法生成Soufflé类型和关系treeedbgen-souffle-souffle:从Soufflé的tree-sitter语法生成Soufflé类型和关系treeedbgen-souffle-swift:从Swift的tree-sitter语法生成Soufflé类型和关系treeedb-java:从Java源代码生成Datalog事实treeedb-javascript:从JavaScript源代码生成Datalog事实treeedb-rust:从Rust源代码生成Datalog事实treeedb-souffle:从Soufflé源代码生成Datalog事实treeedb-swift:从Swift源代码生成Datalog事实
贡献
感谢您对treeedb感兴趣!我们欢迎并感谢所有类型的贡献。请随时提交问题或发起pull request。
添加语言
如安装部分所述,支持分析每种编程语言涉及两个工具:一个用于生成Soufflé类型和关系(例如,treeedbgen-souffle-c),另一个用于解析被分析的语言并生成事实(例如,treeedb-c)。
添加新语言
- 创建与现有目录结构相同的新目录
treeedb-<LANG>和treeedbgen--souffle-<LANG>(可能最简单的方法是直接递归复制现有的目录)。 - 将新目录添加到顶级
Cargo.toml。 - 通过复制和修改其他语言的现有行,将语言添加到
.github/workflows/release.yml中。
请参阅 PR #9 以获取完整示例。
脚本 ./scripts/add-language.sh 自动化了一些步骤 - 但它不一定是一个即插即用的解决方案。使用示例
bash scripts/add-language.sh python Python
依赖项
~13MB
~320K SLoC