20 个版本
0.7.2 | 2023年10月27日 |
---|---|
0.7.1 | 2021年10月21日 |
0.7.0 | 2021年8月26日 |
0.6.4 | 2021年4月23日 |
0.1.1 | 2019年11月26日 |
#18 in 模拟器
141 每月下载
在 haybale-pitchfork 中使用
705KB
12K SLoC
haybale
: 用 Rust 编写的 LLVM IR 符号执行引擎
haybale
是一个用 Rust 编写的通用符号执行引擎。它操作于 LLVM IR,这使得它可以分析用 C/C++、Rust、Swift 或任何其他编译为 LLVM IR 的语言编写的程序。因此,它可以与 KLEE 相比,因为它们有相似的目标,除了 haybale
是用 Rust 编写的,并做出了不同的设计决策。尽管如此,haybale
并不声称在功能上与 KLEE 相等。
好吧,那么符号执行引擎是什么?
符号执行引擎是一种推理方式——严格且数学化——关于函数或程序的行为。它可以对函数的所有可能的输入进行推理,而无需逐个硬暴力。例如,像 haybale
这样的符号执行引擎可以回答以下问题:
- 有哪些输入会导致(某个函数)返回 0?它们是什么?
- 这个循环是否能恰好执行 17 次?
- 这个指针是否可能为 NULL?
符号执行引擎通过将程序或函数中的每个变量转换为依赖于函数或程序输入的数学表达式来回答这些问题。然后,它们使用 SMT 求解器来回答关于这些表达式的问题,例如上述问题。
入门指南
1. 安装
haybale
在 crates.io 上,所以您只需将其添加到您的 Cargo.toml
中的依赖项,选择与您想要的 LLVM 版本对应的特性
[dependencies]
haybale = { version = "0.7.2", features = ["llvm-14"] }
目前支持的 LLVM 版本有 llvm-9
、llvm-10
、llvm-11
、llvm-12
、llvm-13
和 llvm-14
。
haybale
依赖于(间接地)LLVM 和 Boolector 库。
- LLVM 必须在您的系统上可用,版本应与所选功能匹配。(例如,如果您选择了
llvm-14
功能,则您的系统上必须有 LLVM 14。)有关安装 LLVM 的详细信息以及确保 Cargo 可以找到它的说明,请参阅llvm-sys
README。 - 对于 Boolector,您有两个选项
- 您可以在系统上编译并安装 Boolector 3.2.1 作为共享库。(确保将其配置为共享库,例如,使用
./configure.sh --shared
,然后使用make install
安装。) - 或者,您可以启用
haybale
功能vendor-boolector
。使用此选项,Cargo 将自动下载并构建 Boolector 并将其静态链接。例如,
此选项可能仅在 Linux 和 macOS 上工作,并且需要您的系统上有标准构建工具 -- 例如,对于基于 Debian 的发行版,[dependencies] haybale = { version = "0.7.2", features = ["llvm-14", "vendor-boolector"] }
build-essential
、cmake
、curl
和git
。
- 您可以在系统上编译并安装 Boolector 3.2.1 作为共享库。(确保将其配置为共享库,例如,使用
2. 获取要分析的位代码
由于 haybale
在 LLVM 位代码上运行,您需要一些位代码才能开始。如果您想要分析的程序或函数是用 C 编写的,您可以使用 clang
的 -c
和 -emit-llvm
标志生成 LLVM 位代码(*.bc
文件)
clang -c -emit-llvm source.c -o source.bc
出于调试目的,您可能还需要 LLVM 文本格式(*.ll
)文件,您可以使用 clang
的 -S
和 -emit-llvm
标志生成
clang -S -emit-llvm source.c -o source.ll
如果您想要分析的程序或函数是用 Rust 编写的,您同样可以使用 rustc
的 --emit=llvm-bc
和 --emit=llvm-ir
标志。
请注意,为了使 haybale
能够在错误消息和回溯中打印源位置信息(例如,源文件名和行号),LLVM 位代码需要包含调试信息。您可以通过在生成位代码时将 -g
标志传递给 clang
、clang++
或 rustc
来确保包含调试信息。
3. 创建项目
haybale
的 Project
包含目前正在分析的代码,这可能是一个或多个 LLVM 模块。要开始,只需从单个位代码文件创建一个 Project
即可
let project = Project::from_bc_path("/path/to/file.bc")?;
有关创建 Project
的更多方法,包括分析整个库,请参阅 Project
文档。
4. 使用内置分析
haybale
目前包含两个简单的内置分析:一个get_possible_return_values_of_func()
,它描述了函数对于任何输入可能返回的所有值,另一个是find_zero_of_func()
,它找到一个函数的输入集合,使得函数返回 0
。这些分析之所以提供,一方面是因为它们可能有用,另一方面是因为它们展示了如何使用 haybale
。
作为一个入门示例,假设 foo
是以下 C 函数
int foo(int a, int b) {
if (a > b) {
return (a-1) * (b-1);
} else {
return (a + b) % 3 + 10;
}
}
我们可以使用 find_zero_of_func()
来找到使得 foo
返回 0
的输入
match find_zero_of_func("foo", &project, Config::default(), None) {
Ok(None) => println!("foo can never return 0"),
Ok(Some(inputs)) => println!("Inputs for which foo returns 0: {:?}", inputs),
Err(e) => panic!("{}", e), // use the pretty Display impl for errors
}
编写自定义分析
haybale
可以做的不仅仅是描述可能的功能返回值和找到功能零点。在本节中,我们将通过不使用内置的 find_zero_of_func()
来找到上述 foo
函数的零点。这将为如何使用 haybale
编写自定义分析提供示例。
ExecutionManager
所有分析都将使用一个 ExecutionManager
来控制符号执行的进度。在下面的代码片段中,我们调用 symex_function()
来创建一个 ExecutionManager
,该管理器将分析函数 foo
- 它将从函数的顶部开始,并在函数返回时结束。在此期间,它还将根据 Config
设置分析 foo
调用的任何函数。
let mut em = symex_function("foo", &project, Config::<DefaultBackend>::default(), None);
这里不仅需要指定与调用 find_zero_of_func()
时相同的默认 haybale
配置,还需要指定我们想要使用的“后端”。对于大多数目的而言,DefaultBackend
应该是足够的。
Paths
ExecutionManager
类似于函数 foo
中的 路径 迭代器。每条路径都是可能导致函数返回某些值的控制流决策的可能序列(例如,在每次 if
语句中我们选择哪个方向)。在这个示例中,函数 foo
有两条路径,一条是“true”分支,另一条是“false”分支。
让我们检查通过函数的第一条路径
let result = em.next().expect("Expected at least one path");
在常见情况下,result
包含此路径上的函数返回值,作为 Boolector BV
(位向量)封装在 ReturnValue
枚举中。由于我们知道 foo
不是一个空类型函数(并且不会抛出异常或中止),我们可以简单地解包 ReturnValue
以获取 BV
let retval = match result {
Ok(ReturnValue::Return(r)) => r,
Ok(ReturnValue::ReturnVoid) => panic!("Function shouldn't return void"),
Ok(ReturnValue::Throw(_)) => panic!("Function shouldn't throw an exception"),
Ok(ReturnValue::Abort) => panic!("Function shouldn't panic or exit()"),
...
result
也可以是一个 Err
,描述了在处理路径时遇到的 Error
。在这种情况下,我们可以忽略错误并继续调用 next()
来尝试找到没有错误的路径。或者,我们可以这样获取有关错误的信息:
...
Err(e) => panic!("{}", em.state().full_error_message_with_context(e)),
};
这将从程序 State
中获取错误信息,我们将在下一节讨论。但在本教程的其余部分,我们将假设我们得到了 Ok
的结果,此时 retval
是表示第一个路径上函数返回值的 BV
。
状态
对于每条路径,ExecutionManager
不仅提供路径的最终结果(要么是 ReturnValue
,要么是 Error
),还提供该路径末尾的最终程序 State
。我们可以使用 state()
获取对 State
的不可变访问,或者使用 mut_state()
获取可变访问。
let state = em.mut_state(); // the final program state along this path
要测试在这个 State
中 retval
是否可以等于 0
,我们可以使用 state.bvs_can_be_equal()
let zero = state.zero(32); // The 32-bit constant 0
if state.bvs_can_be_equal(&retval, &zero)? {
println!("retval can be 0!");
}
获取变量的解
如果 retval
可以等于 0
,让我们找出哪些函数参数的值会导致这种情况。首先,我们将向 State
添加一个约束,要求返回值必须是 0
retval._eq(&zero).assert();
然后我们将根据这个约束请求每个参数的解
// Get a possible solution for the first parameter.
// In this case, from looking at the text-format LLVM IR, we know the variable
// we're looking for is variable #0 in the function "foo".
let a = state.get_a_solution_for_irname(&String::from("foo"), Name::from(0))?
.expect("Expected there to be a solution")
.as_u64()
.expect("Expected solution to fit in 64 bits");
// Likewise the second parameter, which is variable #1 in "foo"
let b = state.get_a_solution_for_irname(&String::from("foo"), Name::from(1))?
.expect("Expected there to be a solution")
.as_u64()
.expect("Expected solution to fit in 64 bits");
println!("Parameter values for which foo returns 0: a = {}, b = {}", a, b);
或者,我们也可以像这样从 ExecutionManager
获取参数的 BV
:
let a_bv = em.param_bvs()[0].clone();
let b_bv = em.param_bvs()[1].clone();
let a = em.state().get_a_solution_for_bv(&a_bv)?
.expect("Expected there to be a solution")
.as_u64()
.expect("Expected solution to fit in 64 bits");
let b = em.state().get_a_solution_for_bv(&b_bv)?
.expect("Expected there to be a solution")
.as_u64()
.expect("Expected solution to fit in 64 bits");
println!("Parameter values for which foo returns 0: a = {}, b = {}", a, b);
文档
有关 haybale
的完整文档可以在 docs.rs 上找到,或者当然,您可以使用 cargo doc --open
生成本地文档。
兼容性
目前,haybale
的官方 crates.io 版本(0.7.0
及以后)依赖于 Boolector 3.2.1 和 LLVM 9、10、11、12、13 或 14,通过功能标志 llvm-9
到 llvm-14
选择。截至本文写作时,选择 LLVM 版本对 haybale
的功能或接口几乎没有影响;唯一的区别是能够分析使用较新 LLVM 生成的基本代码。(并且 LLVM 10+ 版本可以处理 AtomicRMW
指令;参见 #12。)
对于LLVM 8,您可以尝试使用本仓库的llvm-8
分支。这个分支不再维护,其功能和haybale
0.2.1大致相同。它可能满足您的需求;或者,您可以升级到LLVM 9或更高版本以及最新的haybale
。
LLVM 7及以下版本不受支持。
haybale
在稳定的Rust上运行,需要Rust 1.45或更高版本。
底层
haybale
使用Rust的llvm-ir
crate和Boolector SMT求解器(通过Rust的boolector
crate)构建。
变更日志
版本 0.7.2(2023年10月26日)
- 支持通过
llvm-14
功能使用LLVM 14 - 修复/改进了对一些内建的兼容性
版本 0.7.1(2021年10月21日)
- 通过
llvm-13
功能支持LLVM 13 haybale
现在需要Rust 1.45+(之前为1.43或1.44)
版本 0.7.0(2021年8月26日)
- 通过
llvm-12
功能支持LLVM 12 - 新增了Cargo功能以集成Boolector:在
haybale
构建过程中自动下载、构建和静态链接Boolector。请参阅README中的“安装”部分。 symex_function()
现在接受一个额外的参数params
。您可以使用此参数指定函数参数的约束,甚至指定特定的硬编码值。或者,您可以只传递None
并得到之前的haybale
行为,将所有参数视为完全未加约束。find_zero_of_func()
和get_possible_return_values_of_func()
同样现在接受一个params
参数以指定函数参数的约束。State
有一个新的公共字段proj
,提供对Project
的访问。- 函数钩子不再显式地接受
Project
参数。相反,您可以通过State
对象的proj
字段访问Project
。 ExecutionManager
有一个新的公共方法.func()
,它提供了对顶层Function
的访问。State
有一个新的公共方法get_path_length()
,也作为顶层函数get_path_length()
可用。- 将
llvm-ir
依赖更新到0.8.0,这导致haybale
API的部分发生了一些小的破坏性更改,其中暴露了llvm-ir
类型。
版本 0.6.4 (2021年4月22日)
- 修复了使用 Rust 1.51+ 构建的问题 (#16)。(
haybale
的最低 Rust 版本保持不变:LLVM 9 或 10 用户为 1.43+,LLVM 11 用户为 1.44+)。
版本 0.6.3 (2020年10月26日)
版本 0.6.2 (2020年10月20日)
- 通过
llvm-11
功能支持 LLVM 11 get_possible_return_values_of_func()
现在正确处理 void 函数 (#10)- 支持 LLVM
atomicrmw
指令(仅限 LLVM 10+)(#12) - 支持 LLVM
freeze
指令(仅存在于 LLVM 10+) - 内置了对更多与 panic 处理相关的 Rust 标准库函数的支持
State
有一个新的公共方法get_bv_by_irname()
- 由于
llvm-ir
的要求,LLVM 11 用户需要 Rust 1.44+,而 LLVM 9 或 10 用户仍需 Rust 1.43+。
版本 0.6.1 (2020年9月17日)
- 现在
State
和Project
都有一个方法size_in_bits()
,该方法以位为单位获取任何Type
的大小,考虑了Project
的指针大小和结构定义。这是为了取代state.size()
和state.size_opaque_aware()
,这两个方法现在已弃用,并将从haybale
0.7.0 中移除。同样,state.fp_size()
已弃用并重命名为state.fp_size_in_bits()
。- 注意:这些弃用方法实际上已在 0.7.1 中移除。
版本 0.6.0 (2020年9月1日)
haybale
现在同时支持 LLVM 9 和 LLVM 10,使用相同的分支和相同的 crates.io 发布。当使用haybale
时,您必须选择llvm-9
或llvm-10
功能。- 已更新
llvm-ir
依赖项至 0.7.1(从 0.6.0),其中包括运行时和内存使用性能改进,尤其是对于大位代码文件。这也涉及对haybale
API 的部分破坏性更改。 - 由于
llvm-ir
0.7.1 的要求,haybale
现在需要 Rust 1.43+(以前为 1.40+)。
版本 0.5.1 (2020年8月31日)
- 修复了关于零元素数组的问题 #9(尤其是在分析 Rust 代码时可能出现)
- 内置对
llvm.ctlz
和llvm.cttz
内置函数的支持
版本 0.5.0(2020年7月29日)
兼容性
haybale
默认现在依赖于 LLVM 10(由 LLVM 9 升级)。LLVM 9 仍然在单独的分支上得到支持;请参阅上面的“兼容性”。- 更新
boolector
依赖项到 crate 版本 0.4.0,该版本需要 Boolector 版本 3.2.1(由 3.1.0 升级)。
影响公共 API 的重命名
- 将
SimpleMemoryBackend
重命名为DefaultBackend
并将其设置为默认。将BtorBackend
重命名为CellMemoryBackend
,并将memory
模块重命名为cell_memory
。 - 移除
layout
模块。其函数现在作为State
的方法提供。此外,许多这些函数现在返回u32
而不是usize
。
32 位目标及相关更改
- 使用
DefaultBackend
,haybale
现在支持为 32 位目标编译的 LLVM 位码(之前仅支持 64 位目标)。 - 在
new_uninitialized()
和new_zero_initialized()
方法上,simple_memory::Memory
和cell_memory::Memory
现在将接受一个额外的参数,表示指针大小。 Project
新增一个公共方法pointer_size_bits()
。
其他
- 内置对
llvm.expect
内置函数的支持,以及内置对具有向量操作数的llvm.bswap
内置函数的支持(之前仅支持标量操作数) solver_utils::PossibleSolutions
有新的构造函数empty()
、exactly_one()
和exactly_two()
(用于测试),并且还实现了FromIterator
,允许您将迭代器收集到其中- 修复了
solver_utils
模块中{min,max}_possible_solution_for_bv_as_binary_str()
函数的 bug
版本 0.4.0(2020年3月31日)
新功能
- 支持 LLVM
cmpxchg
指令 - 支持指令回调 - 请参阅
Config.callbacks
。这允许您根据即将处理的指令采取任意操作。
配置
Config.null_detection
已重命名为Config.null_pointer_checking
,并且其类型已更改,以允许更多的选项。Config::new()
现在不再接受参数。它与Config::default()
相同,只是它不包含函数钩子。
其他实用函数/方法
- 现在
hook_utils
模块包含两个新的函数memset_bv
和memcpy_bv
。 layout::size_opaque_aware
现在返回一个Option
而不是引发恐慌。Location
上的to_string_*
方法现在是公共的,而不是仅在crate内部,这使用户能够更多地控制String
的表示。
错误处理
Error
有三个新的变体UnreachableInstruction
、FailedToResolveFunctionPointer
和HookReturnValueMismatch。所有这些以前都被报告为
Error::OtherError
,但现在有专门的变体。Error::LoopBoundExceeded
现在还包括超过循环界限的值。
其他注意事项
haybale
现在不再选择log
crate 的功能。这允许下游用户选择这些功能或不选择,特别是允许用户在发布构建中启用调试日志。
版本 0.3.2(2020 年 2 月 28 日)
- 新选项
Config.max_callstack_depth
允许您限制分析时的调用栈深度 - 自动忽略会超过该调用栈深度的 LLVM 函数调用。此设置的默认值为无限制,与haybale
的先前行为一致。 - 新选项
Config.max_memcpy_length
允许您限制memcpy
、memset
和memmove
操作的最大大小。此设置的默认值为无限制,与haybale
的先前行为一致。 - 新方法
FunctionHooks::add_default_hook()
允许您提供一个“默认钩子”,当没有找到其他定义或钩子时,将使用该钩子。如果没有提供默认钩子,这将导致FunctionNotFound
错误,就像以前一样。 - 分析函数指针调用时的性能改进。
- 改进了一些错误消息。
版本 0.3.1(2020 年 2 月 5 日)
- 修复 README 和文档中的一些损坏链接。没有功能上的更改。
版本 0.3.0(2020 年 2 月 5 日)
求解器超时
- 新设置
Config.solver_query_timeout
控制了haybale
在返回Error::SolverError
之前对单个求解器查询的最大时间。此设置默认为 300 秒(5 分钟)。该设置也可以完全禁用,这将导致haybale
(求解器查询无时间限制)的先前版本的行为。
错误处理
ExecutionManager.next()
返回的错误现在是haybale::Error
,而不是String
,这使得调用者能够更容易地以不同的方式处理不同类型的错误。要获取Error
的字符串表示,请使用.to_string()
,它会提供简短描述,而State.full_error_message_with_context()
提供完整描述,该描述之前由ExecutionManager.next()
返回。相应的 README 文件中的使用示例也已更新。- 顶层函数
find_zero_of_func()
现在返回一个Result
,错误类型为String
。 - 新设置
Config.squash_unsats
控制是否将Error::Unsat
静默地压缩(默认行为,以及haybale
的先前版本的行为),或返回给用户。有关更多详细信息,请参阅该设置的文档。
日志记录、错误消息、回溯等
haybale
现在在错误消息和回溯中打印源位置信息(例如,源文件名和行号),当可用时。同样,HAYBALE_DUMP_PATH
环境变量现在有LLVM
、SRC
和BOTH
选项。有关所有这些的更多详细信息,请参阅Config.print_source_info
。- 您现在也可以在错误消息、回溯、路径转储和日志消息中禁用打印与 LLVM 位置信息一起的 LLVM 模块名称。有关更多详细信息,请参阅
Config.print_module_name
。 haybale
现在将默认自动检测是否适用于Project
的 C++ 或 Rust demangling,除非在Config.demangling
中选择不同的设置。- 表示日志消息、
HAYBALE_DUMP_VARS
转储中等中BV
值的数值常量现在都以十六进制打印(以前是二进制,或二进制和十六进制的混合)。
函数钩子和内联函数
- 内置对 LLVM 加载溢出内联函数的支持。
- 内置对 LLVM 满足算术内联函数的支持。
- 内置对
llvm.assume
内置函数的支持,相关设置请参考Config.trust_llvm_assumes
。 - 内置对
llvm.bswap
内置函数的支持,参数大小为 48 或 64 位(之前仅支持 16 或 32 位)。 - 为一些总是会导致 panic 的 Rust 标准库函数提供了默认的钩子,例如
core::result::unwrap_failed()
。 - 新模块
hook_utils
包含了由相应的内置钩子使用的memset
和memcpy
的实现。现在这些实现对公共领域开放,可供其他函数的自定义钩子使用。
数据结构和特性更改
Location
和PathEntry
结构体已被重构,以便在可用时包含源位置信息,能够指示基本块终止符(除了正常指令外),并支持一些内部重构。backend::BV
特性新增了一个必需方法,get_solver()
,它返回适当类型的SolverRef
。(这与backend::Memory
特性上的相同方法类似。)- 在
backend::BV
上现在提供了饱和算术方法(有符号和无符号加法和减法),默认实现基于其他特性方法。这意味着,一旦实现了所需的特性方法,这些方法就“免费提供”。 zero_extend_to_bits()
和sign_extend_to_bits()
现在作为backend::BV
的特性方法提供,默认实现基于其他特性方法。之前它们是haybale
中的私有实用函数。- 许多其他结构体都进行了小的更改和改进,包括一些小的破坏性更改。
兼容性
- 将
boolector
依赖更新到版本 0.3.0,该版本需要 Boolector 版本 3.1.0(从 3.0.0 升级)。 haybale
的此版本现在需要 Rust 1.40+,高于之前版本haybale
的 1.36+。
版本 0.2.1(2020 年 1 月 15 日)
- 新增
HAYBALE_DUMP_PATH
和HAYBALE_DUMP_VARS
环境变量选项HAYBALE_DUMP_PATH
:如果设置为1
,则在出错时,haybale
将打印错误路径的描述:从函数顶部到错误位置的每个 LLVM 基本块,按顺序。HAYBALE_DUMP_VARS
:如果设置为1
,则在出错时,haybale
将打印出包含错误的功能中每个变量的最新赋值。
- 新增设置
Config.demangling
,允许您将错误消息和回溯中的函数名应用C++或Rust去混淆。 - 支持挂钩内联汇编调用,继承自
llvm-ir
的一些限制(见FunctionHooks::add_inline_asm_hook()
的注释) - 内置支持(最常见的)
llvm.bswap
内省 - 其他细微调整 - 例如,将一个panic降级为警告
版本 0.2.0(2020年1月8日)
- 支持LLVM
extractvalue
和insertvalue
指令 - 支持LLVM
invoke
、resume
和landingpad
指令,以及C++的throw/catch
。还提供了一些相关C++ ABI函数的内置钩子,如__cxa_throw()
。这项支持并不完美,特别是在匹配catch块和异常方面:haybale
可能会探索一些实际上并不有效的路径。但所有实际有效的路径都应被正确找到和探索。 - 由于函数不仅可以使用LLVM
call
指令调用,还可以使用LLVMinvoke
指令调用,因此函数钩子现在接收一个可能代表call
或invoke
指令的&dyn IsCall
对象。 haybale
现在使用LLVM 9而不是LLVM 8。请参阅README中的“兼容性”部分。- 针对包含C++和/或Rust代码的
Project
的改进- 对于
symex_function()
、get_possible_return_values_of_func()
、find_zero_of_func()
和Project::get_func_by_name()
的函数名参数,您现在可以传递(混淆的)函数名,它在LLVM中(如先前所支持),或者去混淆的函数名。也就是说,您可以传递"foo::bar"
而不是"_ZN3foo3barE"
。 - 同样,您可以根据挂钩函数的去混淆名称添加函数钩子。请参阅
FunctionHooks::add_cpp_demangled()
和FunctionHooks::add_rust_demangled()
。 - 此外,
llvm-ir
版本 0.3.3 及以上包含了一个重要的错误修复,用于解析由rustc
生成的 LLVM 位码。haybale
0.2.0 使用llvm-ir
0.4.1。
- 对于
ReturnValue
枚举现在有额外的选项Throw
,表示未捕获的异常,以及Abort
,表示程序中止(例如 Rust panic,或调用 C 的exit()
)。- 相关地,
haybale
现在为 C 的exit()
函数和 Rust panic(以及一些其他 LLVM 内置函数)提供了内置钩子。 haybale
还现在包含了一个内置的generic_stub_hook
和abort_hook
,您可以将它们作为钩子提供给任何您想忽略实现或始终中止的函数。请参阅function_hooks
模块的文档。Config.initial_mem_watchpoints
现在是一个对HashMap
的哈希集合,而不是对对的哈希集合。
版本 0.1.3(2020 年 1 月 1 日)
- 内存监视点:指定一组内存地址范围,并为读取或写入该范围内任何数据的任何内存操作获取日志消息。请参阅
State::add_mem_watchpoint()
。 - 在
State
上添加了方便的方法来构建具有常量值的BV
(而不是必须使用BV
的相应方法并传递state.solver
):bv_from_i32()
、bv_from_u32()
、bv_from_i64()
、bv_from_u64()
、bv_from_bool()
、zero()
、one()
和ones()
。 - 一些内部代码重构,为 0.2.0 功能做准备
版本 0.1.2(2019 年 12 月 18 日)
- 新增方法
Project::get_inner_struct_type_from_named()
,它通过在整个Project
中搜索给定结构的定义来处理不透明结构类型 - 支持大小为 1-7 位的内存读取(特别是 LLVM
i1
的读取) - 性能优化:在
State
初始化期间,全局变量现在仅分配,而不会在首次使用之前进行初始化(惰性初始化)。这使 SMT 求解器需要考虑的内存写入更少,特别是对于包含许多实际上在给定分析中不会使用的全局变量的大型Project
,特别有帮助。 - 小的错误修复和改进的错误信息
版本 0.1.1(2019 年 11 月 26 日)
仅更改 README 中的文本;没有功能更改。
版本 0.1.0(2019 年 11 月 25 日)
首次发布!
依赖关系
约 6.5MB
约 148K SLoC