
Eleva loops binários x86-64 para restrições SMT de forma fechada via análise de intervalos com stride, permitindo execução simbólica O(1) e recuperação de chaves de crackme.
Lifting de Loops SMT de Alto Desempenho em $O(1)$ e Strided Interval Domain para Análise de Binários x86_64
Mecanismos tradicionais de Execução Simbólica e Instrumentação Dinâmica de Binários (DBI) (como angr, Triton ou KLEE) sofrem do notório Problema de Explosão de Caminhos e Loops. Ao encontrar um l[...]
O Strilight resolve esse problema de forma fundamental ao tratar loops como recorrências algébricas de forma fechada dentro do Strided Interval Domain:
$$\vec{\mathbf{R}}(N) = \vec{\mathbf{R}}_0 + \vec{\boldsymbol{\Delta}} \cdot N$$
Em vez de simular $N$ iterações, o Strilight comprime traces de execução repetitivos em estruturas hierárquicas LoopBlock, avalia seus passos afins e policíclicos abstratos e eleva o e[...]
graph LR
A[Raw Machine Code / Trace] --> B[sl.disassemble & sl.compress]
B --> C[sl.evaluate / LoopEvaluator]
C -->|Strided Interval Domain| D[LoopSummary + Invariant Contract]
D -->|O1 Closed-Form Lifting| E["Z3 SMT-LIB2 Solver"]
E --> F[Instant Solution in less than 100 ms]
LoopBlock em $<1\text{ ms}$.O Strilight é empacotado como perfis modulares independentes para que você carregue apenas os componentes que seu pipeline precisa:
# Profile 1: Core Engine (Pure Compressor + Embedded Def-Use Slicer + Capstone)
pip install strilight
# Profile 2: Symbolic Engine (Core Compressor + Z3 O(1) SMT Lifter)
pip install strilight[solver]
# Profile 3: Dynamic Slicing Suite (Core Compressor + Full PathTree Backward/Forward Tracker)
pip install strilight[tracker]
# Profile 4: Complete Bundle (All Engines + Full Tracker + Z3 Solver)
pip install strilight[all]
A suíte de testes valida todos os módulos com 100% de taxa de aprovação nos testes em todas as camadas desacopladas:
strilight)Nenhuma dependência pesada de solver. Executa em $<1\text{ segundo}$ em qualquer plataforma:
strilight[tracker])Valida o rastreamento completo de fluxo de dados dinâmico e de dependências de controle:
strilight[solver])Valida a geração de equações BitVector, substituições de sombra e a resolução de restrições com Z3:
sl.analyze)Analise qualquer loop de código de máquina x86-64 bruto e extraia sua transformação de forma fechada em uma única linha:
import strilight as sl
# Loop bytecode: add eax, 8; sub ebx, 3; inc ecx; cmp ecx, 100000; jl 0x1000
loop_bytes = bytes.fromhex("83c008 83eb03 ffc1 81f9a0860100 7ced")
# ONE-LINE ANALYSIS:
summary = sl.analyze(loop_bytes, iterations=100000)
print(summary.deltas)
# Output: {'eax': 8, 'ebx': -3, 'ecx': 1}
# View the mathematical invariant contract:
print(summary.invariant_contract.to_dict())
import strilight as sl
# 1. Disassemble machine code bytes
instructions = sl.disassemble(loop_bytes, base_address=0x1000)
# 2. Package into a symbolic loop block
block = sl.LoopBlock(body=instructions, iterations=100000)
# 3. Extract closed-form mathematical steps (Deltas & Exit Predicates)
summary = sl.evaluate(block)
print(f"Exit Condition: {summary.exit_condition}")
Resolva o número de iterações ($N$) ou a chave de entrada necessária para satisfazer uma condição de objetivo em $<100\text{ ms}$:
import strilight as sl
import z3
# Disassemble and evaluate
summary = sl.analyze(loop_bytes, iterations=100000)
# Initialize Z3 translator
translator = sl.Z3Translator()
translator.solver.add(translator.get_register('eax') == 0)
translator.solver.add(translator.get_register('ebx') == 500000)
translator.solver.add(translator.get_register('ecx') == 0)
# Lift loop summary in O(1) into Z3
translator.translate_loop_summary(summary, max_iterations=100000)
# Goal: When does EAX reach 800,000?
translator.solver.add(translator.get_register('eax') == 800000)
# Solve in milliseconds!
if translator.solver.check() == z3.sat:
model = translator.solver.model()
solved_N = model.eval(summary.loop_counter_var).as_long()
print(f"[+] Solved N = {solved_N:,} iterations in O(1) time!")
Testado com executáveis Windows de 64 bits complexos (CrackMe Suite) contendo loops aninhados, fatiamento de sub-registradores e padrões de stride ofuscados:
Verificação Ground-Truth: Todas as chaves recuperadas são verificadas executando o binário nativo compilado (
.exe) via subprocess e confirmando a respostaACCESS GRANTED.
sl.analyze(code_bytes, iterations=1000, ...): Desmontagem + avaliação em uma linha.sl.disassemble(code_bytes, base_address=0x1000, bit_mode=64): Desmontador de bytes brutos via Capstone.sl.compress(trace, min_iterations=3): Compressor hierárquico de traces.sl.evaluate(block_or_trace, k_passes=100): Avaliador de estado abstrato e invariantes.sl.Instruction: Representação unificada de instruções de assembly.sl.LoopBlock: Nó de loop hierárquico com limites de iteração.sl.LoopSummary: Resumo da transformação de forma fechada contendo deltas, padrões cíclicos e conjuntos constantes.sl.LoopInvariantContract: Descritor formal do invariante estrutural de saída e gerador de regras de contorno SMT.sl.StridedInterval: Representação matemática de intervalos com alinhamento de stride e congruência modular.sl.Z3Translator: Elevador SMT simbólico que converte resumos de loops em restrições BitVector do Z3.Licença Dupla: MIT / Proprietária. Desenvolvido com ❤️ para engenharia reversa e análise de binários de alto desempenho.
| Arquivo de Teste | Descrição | Componentes Testados |
|---|
test_facade.py | API de alto nível para desenvolvedores (sl.analyze, sl.disassemble, sl.compress, sl.evaluate) | Fachada strilight |
test_capstone_decoupling.py | Desmontagem de bytes brutos de código de máquina e registro de ponte de tracer customizada | Instruction, [...] |
test_invariant_contract.py | Contratos matemáticos de invariantes e descritores de contorno da Restrição de Ferro $N-1$ | LoopInvari[...] |
test_interval.py | Limites de intervalo principais, aritmética de intervalos e operações | Interval |
test_disjoint_set.py | Conjuntos de memória disjuntos, aritmética de faixas não contíguas e uniões | DisjointIntervalSet |
test_strided_interval_notion.py | Domínio Strided Interval, ponte de congruência GCD e bitmasks de sub-registradores | Stri[...] |
test_circular_theorems.py | Teoremas de wrap-around de aritmética modular circular ($x \pmod{2^w}$) | Matemática do StridedInterval |
test_loop_compressor.py | Dobramento de trace e detecção de back-edges de loops em árvores LoopBlock | TraceCompressor |
test_nested_loops.py | Compressão de loops aninhados em vários níveis ($O(N \cdot M)$ dobramento hierárquico) | Árvores TraceCompressor |
test_vsa_evaluator.py | Passes de simulação de Value-Set Analysis e extração de delta afim | LoopEvaluator |
test_polycyclic.py | Padrões periódicos policíclicos em memória e registradores ($P > 1$) | LoopEvaluator |
| Arquivo de Teste | Descrição | Componentes Testados |
|---|
test_tracker.py | Fatiamento de instruções para trás/para frente, cadeias def-use de registradores/memória | Tracker, BackwardTracker |
test_lazy_tracker.py | Avaliação preguiçosa e omissão de blocos de loop irrelevantes | Otimização do Tracker |
test_loop_taint.py | Propagação de taint em loops e rastreamento de dependências de controle na saída do loop | Taint do Tracker |
test_path_tree.py | Cache de decisões de desvio e eliminação de caminhos sem saída | PathTree |
test_stop_dict.py | Definições de limites de taint da API | stop_dict |
test_hooks.py | Callbacks de interceptação de instruções e de acessos à memória | hooks |
| Arquivo de Teste | Descrição | Componentes Testados |
|---|
test_translator.py | Tradução completa de instruções x86-64 para BitVectors Z3 (aritmética, flags, saltos, memória) | Z3Translator |
test_translator_edge_cases.py | Exaustão profunda de AST, cadeias de aliasing de memória e restrições de contorno | Z3Translato[...] |
test_deep_doubts.py | Wrap-around com sinal, indução cúbica de Newton de grau 3 e congruências de Bezout | Provas Matemáticas |
| # | Binário Alvo | Tamanho do Slice | Status Z3 | Chave Descoberta | Execução Nativa | Tempo | Resultado |
|---|
| 1 | crackme_boss.exe | 662 | SAT | 1729 | ACCESS GRANTED | ~60 ms | [PASS] |
| 2 | crackme_subregs.exe | 671 | SAT | 1337 | ACCESS GRANTED | ~75 ms | [PASS] |
| 3 | crackme_nested_loops.exe | 1369 | SAT | 1337 | ACCESS GRANTED | ~110 ms | [PASS] |
| 4 | crackme_pointers.exe | 859 | SAT | 1337 | ACCESS GRANTED | ~85 ms | [PASS] |
| 5 | crackme_license.exe | 657 | SAT | 1337 | ACCESS GRANTED | ~65 ms | [PASS] |
| 6 | crackme_strided_circular.exe | 829 | SAT | 1337 | ACCESS GRANTED | ~95 ms | [PASS] |