
Eleva bucles de binarios x86-64 a restricciones SMT de forma cerrada mediante análisis de intervalos escalonados, lo que permite ejecución simbólica O(1) y recuperación de claves crackme.
Elevación de bucles SMT de alto rendimiento $O(1)$ y dominio de intervalos con stride para análisis de binarios x86_64
Los motores tradicionales de Ejecución Simbólica e Instrumentación Binaria Dinámica (DBI) (como angr, Triton o KLEE) sufren el notorio Problema de Explosión de Caminos y Bucles. Cuando se encuentran con un l[...]
Strilight resuelve esto de forma fundamental al tratar los bucles como recurrencias algebraicas de forma cerrada dentro del Dominio de Intervalos con Stride:
$$\vec{\mathbf{R}}(N) = \vec{\mathbf{R}}_0 + \vec{\boldsymbol{\Delta}} \cdot N$$
En lugar de simular $N$ iteraciones, Strilight comprime las trazas de ejecución repetitivas en estructuras jerárquicas LoopBlock, evalúa sus pasos afines y policíclicos abstractos, y eleva la 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 en $<1\text{ ms}$.Strilight se distribuye como perfiles modulares independientes para que solo cargues los componentes que tu pipeline necesita:
# 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 de pruebas valida cada módulo con una tasa de aprobación del 100% en todas las capas desacopladas:
strilight)Sin dependencias pesadas de solucionadores. Se ejecuta en $<1\text{ segundo}$ en cualquier plataforma:
strilight[tracker])Valida el seguimiento completo del flujo de datos dinámico y las dependencias de control:
strilight[solver])Valida la generación de ecuaciones de BitVector, sustituciones sombra y resolución de restricciones con Z3:
sl.analyze)Analiza cualquier bucle de código máquina x86-64 crudo y extrae su transformación de forma cerrada en una sola línea:
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}")
Resuelve el número de iteraciones ($N$) o la clave de entrada necesaria para satisfacer una condición objetivo en $<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!")
Probado con ejecutables complejos de Windows de 64 bits (CrackMe Suite) que contienen bucles anidados, segmentación de sub-registros y patrones de stride ofuscados:
Verificación de referencia (ground-truth): Todas las claves recuperadas se verifican ejecutando el binario nativo compilado (
.exe) mediante subprocess y comprobando la respuestaACCESS GRANTED.
sl.analyze(code_bytes, iterations=1000, ...): Desensamblado y evaluación en una sola línea.sl.disassemble(code_bytes, base_address=0x1000, bit_mode=64): Desensamblador de bytes crudos mediante Capstone.sl.compress(trace, min_iterations=3): Compresor jerárquico de trazas.sl.evaluate(block_or_trace, k_passes=100): Evaluador de estados abstractos e invariantes.sl.Instruction: Representación unificada de instrucciones de ensamblador.sl.LoopBlock: Nodo jerárquico de bucle con límites de iteración.sl.LoopSummary: Resumen de transformación de forma cerrada que contiene deltas, patrones cíclicos y conjuntos constantes.sl.LoopInvariantContract: Descriptor formal de invariante estructural de salida y generador de reglas de frontera SMT.sl.StridedInterval: Representación matemática de intervalos con alineación de stride y congruencia modular.sl.Z3Translator: Elevador SMT simbólico que convierte resúmenes de bucles en restricciones BitVector de Z3.Licencia dual: MIT / Propietaria. Desarrollado con ❤️ para la ingeniería inversa de alto rendimiento y el análisis de binarios.
| Archivo de prueba | Descripción | Componentes probados |
|---|
test_facade.py | API de alto nivel para desarrolladores (sl.analyze, sl.disassemble, sl.compress, sl.evaluate) | Fachada de strilight |
test_capstone_decoupling.py | Desensamblado de bytes de código máquina crudo y registro de puentes de trazado personalizados | Instruction, `[...] |
test_invariant_contract.py | Contratos de invariante matemáticos y descriptores de frontera de la Restricción de Hierro $N-1$ | `LoopInvari[...] |
test_interval.py | Delimitación de intervalos principal, aritmética de intervalos y operaciones | Interval |
test_disjoint_set.py | Conjuntos de memoria disjuntos, aritmética de rangos no contiguos y uniones | DisjointIntervalSet |
test_strided_interval_notion.py | Dominio de Intervalos con Stride, puente de congruencia GCD y máscaras de bits de sub-registros | `Stri[...] |
test_circular_theorems.py | Teoremas de envoltura de la aritmética modular circular ($x \pmod{2^w}$) | Matemáticas de StridedInterval |
test_loop_compressor.py | Plegado de trazas y detección de bordes de retroceso de bucles en árboles LoopBlock | TraceCompressor |
test_nested_loops.py | Compresión de bucles anidados de múltiples niveles (plegado jerárquico $O(N \cdot M)$) | Árboles de TraceCompressor |
test_vsa_evaluator.py | Pasadas de simulación de Value-Set Analysis y extracción de deltas afines | LoopEvaluator |
test_polycyclic.py | Patrones periódicos policíclicos en memoria y registros ($P > 1$) | LoopEvaluator |
| Archivo de prueba | Descripción | Componentes probados |
|---|
test_tracker.py | Segmentación de instrucciones hacia atrás/adelante, cadenas def-uso de registros/memoria | Tracker, BackwardTracker |
test_lazy_tracker.py | Evaluación perezosa y omisión de bloques de bucle irrelevantes | Optimización de Tracker |
test_loop_taint.py | Propagación de taint en bucles y seguimiento de dependencias de control de salida de bucle | Tracker Taint |
test_path_tree.py | Caché de decisiones de rama y eliminación de caminos sin salida | PathTree |
test_stop_dict.py | Definiciones de límites de taint de la API | stop_dict |
test_hooks.py | Callbacks de intercepción de instrucciones y accesos a memoria | hooks |
| Archivo de prueba | Descripción | Componentes probados |
|---|
test_translator.py | Traducción completa de instrucciones x86-64 a BitVectors de Z3 (aritmética, flags, saltos, memoria) | Z3Translator |
test_translator_edge_cases.py | Agotamiento profundo del AST, cadenas de alias de memoria y restricciones de frontera | `Z3Translato[...] |
test_deep_doubts.py | Desbordamiento con signo, inducción cúbica de Newton de grado 3 y congruencias de Bézout | Pruebas matemáticas |
| # | Binario objetivo | Tamaño de slice | Estado de Z3 | Clave descubierta | Ejecución nativa | Tiempo | 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] |