
Framework de análise estática de binários baseado em LLVM
Dna é um framework de análise binária estática construído sobre o LLVM. Notavelmente, é escrito quase inteiramente em C#, incluindo bindings gerenciados para LLVM, Remill e Souper.
Dna implementa uma reconstrução iterativa de grafo de fluxo de controle fortemente inspirada no artigo SATURN. Ele aplica iterativamente descida recursiva, lifting (usando remill) e resolução de caminhos até que o grafo de fluxo de controle completo seja recuperado. No caso de tabelas de jump, usamos um algoritmo recursivo baseado em Souper e z3 para resolver o conjunto de possíveis alvos da tabela de jump. Você pode encontrar o algoritmo de exploração iterativa aqui, e o algoritmo de resolução de tabelas de jump aqui.
Uma vez que um grafo de fluxo de controle tenha sido totalmente explorado, ele pode então ser recompilado para x86 e reinserido no binário usando os algoritmos de aqui e aqui. Embora o código compilado não seja bonito de forma alguma, ele deve funcionar desde que o grafo de fluxo de controle recuperado esteja correto. Dito isso, ainda é um protótipo de pesquisa - bugs e casos extremos são esperados. A exploração do grafo de fluxo de controle pode falhar no caso de, por exemplo, tabelas de jump ilimitadas ou instruções não levantáveis.
Algumas outras funcionalidades notáveis:
try/catch e intrínsecos filter são inseridos no grafo de fluxo de controle. Embora o recompilador não (ainda) suporte SEH (as entradas SEH não são corrigidas), portanto, exceções causarão travamentos.MemorySSA, LoopInfo, árvores de dominância, gerenciamento de pipeline de passes, etc.Algumas ressalvas:
Observe que o Dna atualmente é baseado no LLVM 17.
Dna contém um plugin de desvirtualização VMProtect localizado em Dna.BinaryTranslator/VMProtect. Veja este PR para mais informações.
O Dna atualmente tem como alvo o LLVM 17 e deve ser compilado no Windows x64 com Visual Studio 2022.
Compile Dna.LLVMInterop no modo Release; a árvore de dependências nativas é construída em Release e compilações Debug interop não são suportadas.
Execute os comandos abaixo a partir de um shell de desenvolvedor VS x64, ou outro shell com as ferramentas C++ do VS no PATH.
O superbuild de dependências instala LLVM 17, Remill, Z3, XED, gflags/glog e bibliotecas nativas relacionadas em 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
Se alterar o compilador, tipo de compilação ou configurações CRT, exclua tanto Dna.LLVMInterop/dependencies/build quanto Dna.LLVMInterop/dependencies/install antes de reconfigurar.
Dna.Example e os projetos simplificadores copiam eq_sat.dll da saída de release do Cargo.
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