语法引导修复/转换包
项目描述
Tourniquet
一个用于轻松进行C/C++语法引导程序转换/修复的Python库。这仍处于开发初期。
安装
PyPI
Tourniquet可通过PyPI获取
$ pip install tourniquet
您需要相对较新的CMake和LLVM(支持9、10和11)。
Docker
Tourniquet也可以在Docker容器中构建和运行
$ docker build -t trailofbits/tourniquet .
$ docker run -it trailofbits/tourniquet
进入一个ipython
实例并导入tourniquet
语法引导程序修复TL;DR
修复程序很困难,而自动修复中最受欢迎的技术之一是搜索。如果您熟悉模糊测试,它基本上是相反的。在模糊测试中,您正在突变输入以导致崩溃,但在基于搜索的程序修复中,您正在突变程序直到通过一些特定的测试。
这种基于搜索的方法的一个巨大缺点是搜索空间很大,其中大多数突变都是无用的。语法引导程序修复背后的想法是提出一些通用的语法模式,并使用这些模式作为您的搜索空间。这意味着您的搜索空间更小(由语法模式限制)并且您专注于可能实际上修复您面前任何错误的补丁候选。
那么,Tourniquet到底是什么?
止血带是一个用于语法引导程序修复的库和领域特定语言。当前的工具有硬编码的修复模式,这使得人类难以与之交互和调整。止血带的目标是快速轻松地创建可立即用于尝试修复错误的修复模板。我们计划将止血带与程序分析工具一起使用,以便人类创建具有语义意义的修复模式。
领域特定语言
而不是编写单个树转换遍历或其他类型的源操作,止血带使得描述修复的部分语法和部分语义变得容易,让计算机完成剩余的工作。以下是一个简单的示例模板:
class YourSemanticAnalysis(Expression):
def concretize(self, _db, _location):
yield "SOME_ERROR_CONSTANT"
def your_matcher_func(line, col):
return True
demo_template = PatchTemplate(
FixPattern( # Location 1
IfStmt(
LessThanExpr(Variable(), Variable()), # Location 2
NodeStmt() # Location 3
),
ElseStmt(
ReturnStmt(YourSemanticAnalysis()) # Location 4
)
),
your_matcher_func # Location 5
)
位置 1 是 FixPattern
的开始。 FixPattern
描述了修复的整体形状。这意味着人类提供了修复的部分语法和部分语义。
位置 2 展示了 DSL 中的不同类型。这一行描述的是两个变量的小于语句,所有变量信息都自动从 Clang AST 中提取。
位置 3 是你的匹配函数匹配到的源代码,也来自 Clang AST。
位置 4 是如何将程序分析工具与止血带集成的示例。 FixPattern
尝试进行一个基本的 if...else
语句,其中 else
情况返回某个值。返回值具有语义属性,返回任意整数通常不是一个好主意。这意味着你可以使用某些程序分析技术来推断可能合适的返回代码,或者简单地要求人类干预。
位置 5 是匹配器。匹配器是一个可调用的函数,它应该接受源行和列信息,并返回 True
或 False
,如果 FixPattern
适用于该源位置。这里的想法是将特定类型的修复与特定类型的错误相结合。我们打算使用其他工具(例如 Manticore)来帮助确定错误类别。
使用止血带
# Create a new Tourniquet instance
demo = Tourniquet("test.db")
# Extract info from its AST into the database
demo.collect_info("demo_prog.c")
# Create a new patch template
demo_template = PatchTemplate(
FixPattern(
IfStmt(
LessThanExpr(Variable(), Variable()),
NodeStmt()
)
),
lambda x, y: True,
)
# Add the template to the tourniquet instance
demo.register_template("demo_template", demo_template)
# Tell Tourniquet you want to see results from this program, with this template,
# matching against some location
location = Location("demo_prog.c", SourceCoordinate(44, 3))
samples = demo.concretize_template("demo_template", location)
# Look at all the patch candidates!
print(list(samples))
# Attempt to automatically repair the program using that template
# Specify the file, some testcases, and the location information again
demo.auto_patch(
"demo_template"
[
("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 1),
("password", 0)
],
location
)
自动修补将返回 True
或 False
,取决于你是否成功找到了修复所有测试用例的补丁。最终我们将支持测试用例目录等,这仍处于开发早期。
有关更多详细信息,请查看止血带的 API 文档。
开发
安装 venv 以能够运行 make
命令
$ docker build -t trailofbits/tourniquet .
$ docker run -it trailofbits/tourniquet
root@b9f3a28655b6:/tourniquet# apt-get install -y python3-venv
root@b9f3a28655b6:/tourniquet# python3 -m venv env
root@b9f3a28655b6:/tourniquet# make test
贡献者
- Carson Harmon (carson.harmon@trailofbits.com)
- Evan Sultanik (evan.sultanik@trailofbits.com)
- William Woodruff (william@trailofbits.com)
致谢
该项目或工作由美国空军研究实验室(AFRL)和 DARP 在合同 FA8750-19-C-0004 下赞助。本材料中表达的意见、发现、结论或建议是作者的观点,不一定反映美国空军研究实验室(AFRL)和 DARP 的观点。
分发声明:批准公开发布,分发不受限制
项目详情
tourniquet-0.0.5.tar.gz的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 0a577e85b76d69d5709cf1d34328ecd7139afccf10f759e8d22dd70ddef84a63 |
|
MD5 | 6b74bf9296fd506c52f88447e9db20b3 |
|
BLAKE2b-256 | 4dcaba6568888fb765a486e5e7087e2f30d5a85df4b50848eeca7f2edec8f19a |