
Solleva i loop binari x86-64 in vincoli SMT in forma chiusa tramite analisi a intervalli strided, consentendo l'esecuzione simbolica O(1) e il recupero delle chiavi dei crackme.
Lifting SMT $O(1)$ di Loop ad Alte Prestazioni e Dominio a Intervalli Strided per l'Analisi Binaria x86_64
L'esecuzione simbolica tradizionale e i motori di Dynamic Binary Instrumentation (DBI) (come angr, Triton o KLEE) soffrono del noto Problema dell'Esplosione dei Percorsi e dei Loop. Quando si incontra un l[...]
Strilight risolve questo problema alla radice, trattando i loop come ricorrenze algebriche in forma chiusa all'interno del Dominio a Intervalli Strided:
$$\vec{\mathbf{R}}(N) = \vec{\mathbf{R}}_0 + \vec{\boldsymbol{\Delta}} \cdot N$$
Invece di simulare $N$ iterazioni, Strilight comprime le tracce di esecuzione ripetitive in strutture gerarchiche LoopBlock, valuta i loro passi astratti affini e policiclici e solleva l'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 in $<1\text{ ms}$.Strilight è distribuito come profili modulari indipendenti, così da portare con te solo i componenti di cui la tua pipeline ha bisogno:
# 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]
La suite di test valida ogni modulo con un tasso di superamento dei test del 100% su tutti i livelli disaccoppiati:
strilight)Zero dipendenze pesanti dal solver. Viene eseguita in $<1\text{ second}$ su qualsiasi piattaforma:
strilight[tracker])Valida il tracciamento completo del data-flow dinamico e delle dipendenze di controllo:
strilight[solver])Valida la generazione di equazioni BitVector, le sostituzioni shadow e la risoluzione dei vincoli Z3:
sl.analyze)Analizza qualsiasi loop di codice macchina x86-64 grezzo ed estrai la sua trasformazione in forma chiusa in una sola riga:
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}")
Risolve il numero di iterazioni ($N$) o la chiave di input necessaria per soddisfare una condizione obiettivo in $<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!")
Testato su eseguibili Windows a 64 bit complessi (CrackMe Suite) contenenti loop annidati, slicing di sotto-registri e pattern di stride offuscati:
Verifica Ground-Truth: tutte le chiavi recuperate vengono verificate eseguendo il binario nativo compilato (
.exe) tramite subprocess e verificando la rispostaACCESS GRANTED.
sl.analyze(code_bytes, iterations=1000, ...): disassemblaggio + valutazione in una sola riga.sl.disassemble(code_bytes, base_address=0x1000, bit_mode=64): disassembler di byte grezzi tramite Capstone.sl.compress(trace, min_iterations=3): compressore gerarchico di tracce.sl.evaluate(block_or_trace, k_passes=100): valutatore dello stato astratto e degli invarianti.sl.Instruction: rappresentazione unificata delle istruzioni assembly.sl.LoopBlock: nodo di loop gerarchico con limiti di iterazione.sl.LoopSummary: riepilogo della trasformazione in forma chiusa contenente delta, pattern ciclici e insiemi di costanti.sl.LoopInvariantContract: descrittore formale dell'invariante strutturale di uscita e generatore di regole di confine SMT.sl.StridedInterval: rappresentazione matematica di intervallo con allineamento dello stride e congruenza modulare.sl.Z3Translator: lifter SMT simbolico che converte i riepiloghi dei loop in vincoli BitVector Z3.Doppia Licenza: MIT / Proprietaria. Sviluppato con ❤️ per il reverse engineering ad alte prestazioni e l'analisi binaria.
| File di Test | Descrizione | Componenti Testati |
|---|
test_facade.py | API di alto livello per sviluppatori (sl.analyze, sl.disassemble, sl.compress, sl.evaluate) | Facade strilight |
test_capstone_decoupling.py | Disassemblaggio di byte di codice macchina grezzi e registrazione di bridge personalizzati per tracer | Instruction, `[...] |
test_invariant_contract.py | Contratti matematici di invarianza e descrittori di confine del Vincolo di Ferro $N-1$ | `LoopInvari[...] |
test_interval.py | Delimitazione di base degli intervalli, aritmetica degli intervalli e operazioni | Interval |
test_disjoint_set.py | Insiemi di memoria disgiunti, aritmetica degli intervalli non contigui e unioni | DisjointIntervalSet |
test_strided_interval_notion.py | Dominio a Intervalli Strided, bridge di congruenza GCD e bitmask dei sotto-registri | `Stri[...] |
test_circular_theorems.py | Teoremi di wrap-around dell'aritmetica modulare circolare ($x \pmod{2^w}$) | Matematica di StridedInterval |
test_loop_compressor.py | Folding delle tracce e rilevamento dei back-edge dei loop in alberi LoopBlock | TraceCompressor |
test_nested_loops.py | Compressione di loop annidati su più livelli (folding gerarchico $O(N \cdot M)$) | Alberi TraceCompressor |
test_vsa_evaluator.py | Passi di simulazione della Value-Set Analysis ed estrazione dei delta affini | LoopEvaluator |
test_polycyclic.py | Pattern periodici policiclici in memoria e registri ($P > 1$) | LoopEvaluator |
| File di Test | Descrizione | Componenti Testati |
|---|
test_tracker.py | Slicing delle istruzioni all'indietro/in avanti, catene def-use di registri/memoria | Tracker, BackwardTracker |
test_lazy_tracker.py | Valutazione lazy e salto dei loop block irrilevanti | Ottimizzazione del Tracker |
test_loop_taint.py | Propagazione del taint nei loop e tracciamento delle dipendenze di controllo all'uscita dai loop | Taint del Tracker |
test_path_tree.py | Caching delle decisioni di branching ed eliminazione dei percorsi senza uscita | PathTree |
test_stop_dict.py | Definizioni dei confini del taint nell'API | stop_dict |
test_hooks.py | Callback di intercettazione delle istruzioni e degli accessi alla memoria | hooks |
| File di Test | Descrizione | Componenti Testati |
|---|
test_translator.py | Traduzione completa delle istruzioni x86-64 in BitVector Z3 (aritmetica, flag, salti, memoria) | Z3Translator |
test_translator_edge_cases.py | Esaurimento profondo dell'AST, catene di aliasing della memoria e vincoli al contorno | `Z3Translato[...] |
test_deep_doubts.py | Wrap-around con segno, induzione cubica di Newton di grado 3 e congruenze di Bézout | Dimostrazioni Matematiche |
| # | Binario Target | Dimensione Slice | Stato Z3 | Chiave Scoperta | Esecuzione Nativa | Tempo | Risultato |
|---|
| 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] |