Dna 是一个基于 LLVM 构建的静态二进制分析框架。值得注意的是,它几乎完全用 C# 编写,包括 LLVM、Remill 和 Souper 的托管绑定。
Dna 实现了一种迭代控制流图重建,其灵感主要来自 SATURN 论文。它迭代地应用递归下降、提升(使用 remill)和路径求解,直到恢复完整的控制流图。对于跳转表,我们使用基于 Souper 和 z3 的递归算法来求解可能的跳转表目标集合。迭代探索算法可在此处找到,跳转表求解算法可在此处找到。
一旦控制流图被完全探索,就可以使用此处和此处的算法将其重新编译为 x86 并重新插入到二进制文件中。尽管编译后的代码绝不好看,但只要恢复的控制流图正确,它就应该能运行。话虽如此,它仍然是一个研究原型——错误和边缘情况是意料之中的。控制流图探索可能会在例如无界跳转表或无法提升的指令的情况下失败。
其他一些值得注意的特性:
try/catch 语句和 filter 内嵌函数会被插入到控制流图中。不过,重新编译器(目前)还不支持 SEH(SEH 条目未被修复),因此异常会导致崩溃。MemorySSA、LoopInfo、支配树、pass 管道管理等的绑定。一些注意事项:
请注意,Dna 目前基于 LLVM 17。
Dna 包含一个 VMProtect 去虚拟化插件,位于 Dna.BinaryTranslator/VMProtect。更多信息请参见此 PR。
Dna 当前针对 LLVM 17,并期望在 Windows x64 上使用 Visual Studio 2022 构建。
在 Release 模式下构建 Dna.LLVMInterop;本地依赖树是 Release 构建的,不支持 Debug interop 构建。
从 VS x64 开发者命令提示符,或另一个将 VS C++ 工具加入 PATH 的 shell 中运行以下命令。
依赖项超级构建将 LLVM 17、Remill、Z3、XED、gflags/glog 及相关本地库安装到 Dna.LLVMInterop/dependencies/install。
cmake -S Dna.LLVMInterop/dependencies `
-B Dna.LLVMInterop/dependencies/build `
-G Ninja `
-DCMAKE_BUILD_TYPE=Release `
-DCMAKE_C_COMPILER=clang-cl `
-DCMAKE_CXX_COMPILER=clang-cl
cmake --build Dna.LLVMInterop/dependencies/build
如果更改编译器、构建类型或 CRT 设置,请在重新配置前删除 Dna.LLVMInterop/dependencies/build 和 Dna.LLVMInterop/dependencies/install。
Dna.Example 和简化器项目会从 Cargo 发布输出中复制 eq_sat.dll。
cargo build --manifest-path Simplifier/EqSat/Cargo.toml --release
& "C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exe" `
Dna.sln `
/restore `
/p:Configuration=Release `
/p:Platform=x64 `
/m