
Поднимает циклы бинарных x86-64 программ в SMT-ограничения в замкнутой форме посредством страйдового интервального анализа, обеспечивая символьное исполнение за O(1) и восстановление ключей crackme.
Высокопроизводительный $O(1)$ SMT-лифтинг циклов и страйдовый интервальный домен для анализа бинарных файлов x86_64
Традиционные движки символьного исполнения и динамической бинарной инструментации (DBI) (такие как angr, Triton или KLEE) страдают от печально известной проблемы взрыва путей и циклов. При обнаружении l[...]
Strilight решает эту проблему фундаментально, рассматривая циклы как алгебраические рекурренции в замкнутой форме в пределах страйдового интервального домена:
$$\vec{\mathbf{R}}(N) = \vec{\mathbf{R}}_0 + \vec{\boldsymbol{\Delta}} \cdot N$$
Вместо симуляции $N$ итераций, Strilight сжимает повторяющиеся трассы исполнения в иерархические структуры LoopBlock, вычисляет их абстрактные аффинные и полициклические шаги и выполняет лифтинг 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 за $<1\text{ ms}$.Strilight поставляется в виде независимых модульных профилей, чтобы вы могли нести только те компоненты, которые нужны вашему конвейеру:
# 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]
Тестовый набор проверяет каждый модуль со 100% прохождением тестов на всех развязанных уровнях:
strilight)Ноль тяжёлых зависимостей от решателей. Выполняется за $<1\text{ second}$ на любой платформе:
strilight[tracker])Проверяет полное отслеживание динамического потока данных и управляющих зависимостей:
strilight[solver])Проверяет генерацию BitVector-уравнений, теневые подстановки и решение ограничений Z3:
sl.analyze)Проанализируйте любой цикл в сыром машинном коде x86-64 и извлеките его преобразование в замкнутой форме одной строкой:
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}")
Найдите количество итераций ($N$) или входной ключ, необходимый для выполнения целевого условия, за $<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!")
Протестировано на сложных 64-битных исполняемых файлах Windows (CrackMe Suite), содержащих вложенные циклы, субрегистровый слайсинг и обфусцированные страйдовые паттерны:
Проверка по эталону (Ground-Truth): Все восстановленные ключи проверяются запуском нативного скомпилированного бинарного файла (
.exe) через subprocess и проверкой ответаACCESS GRANTED.
sl.analyze(code_bytes, iterations=1000, ...): дизассемблирование и оценка одной строкой.sl.disassemble(code_bytes, base_address=0x1000, bit_mode=64): дизассемблер сырых байтов через Capstone.sl.compress(trace, min_iterations=3): иерархический компрессор трасс.sl.evaluate(block_or_trace, k_passes=100): вычислитель абстрактного состояния и инвариантов.sl.Instruction: унифицированное представление инструкций ассемблера.sl.LoopBlock: иерархический узел цикла с границами итераций.sl.LoopSummary: сводка преобразования в замкнутой форме, содержащая дельты, циклические паттерны и множества констант.sl.LoopInvariantContract: формальный дескриптор структурного инварианта выхода и генератор правил границ SMT.sl.StridedInterval: математическое представление интервала с выравниванием страйдов и модулярной конгруэнцией.sl.Z3Translator: символьный SMT-лифтер, преобразующий сводки циклов в BitVector-ограничения Z3.Двойная лицензия: MIT / проприетарная. Разработано с ❤️ для высокопроизводительного реверс-инжиниринга и анализа бинарного кода.
| Тестовый файл | Описание | Проверяемые компоненты |
|---|
test_facade.py | Высокоуровневый API разработчика (sl.analyze, sl.disassemble, sl.compress, sl.evaluate) | strilight Facade |
test_capstone_decoupling.py | Дизассембляция сырых байтов машинного кода и регистрация пользовательского моста трассировки | Instruction, `[...] |
test_invariant_contract.py | Математические инвариантные контракты и граничные дескрипторы $N-1$ Iron Constraint | `LoopInvari[...] |
test_interval.py | Базовое ограничение интервалов, интервальная арифметика и операции | Interval |
test_disjoint_set.py | Непересекающиеся множества памяти, арифметика несмежных диапазонов и объединения | DisjointIntervalSet |
test_strided_interval_notion.py | Страйдовый интервальный домен, GCD-мост конгруэнтности и битовые маски субрегистров | `Stri[...] |
test_circular_theorems.py | Теоремы циклического переполнения модулярной арифметики ($x \pmod{2^w}$) | StridedInterval Math |
test_loop_compressor.py | Свёртывание трасс и обнаружение обратных рёбер циклов в деревья LoopBlock | TraceCompressor |
test_nested_loops.py | Многоуровневое сжатие вложенных циклов ($O(N \cdot M)$ иерархическое свёртывание) | TraceCompressor Trees |
test_vsa_evaluator.py | Симуляционные проходы анализа множества значений (Value-Set Analysis) и извлечение аффинных дельт | LoopEvaluator |
test_polycyclic.py | Полициклические периодические паттерны в памяти и регистрах ($P > 1$) | LoopEvaluator |
| Тестовый файл | Описание | Проверяемые компоненты |
|---|
test_tracker.py | Обратный/прямой слайсинг инструкций, цепочки def-use регистров/памяти | Tracker, BackwardTracker |
test_lazy_tracker.py | Ленивые вычисления и пропуск нерелевантных блоков циклов | Tracker Optimization |
test_loop_taint.py | Распространение taint-меток в циклах и отслеживание управляющих зависимостей выхода из цикла | Tracker Taint |
test_path_tree.py | Кэширование решений ветвлений и устранение тупиковых путей | PathTree |
test_stop_dict.py | Определения границ taint-анализа в API | stop_dict |
test_hooks.py | Колбэки перехвата инструкций и обращений к памяти | hooks |
| Тестовый файл | Описание | Проверяемые компоненты |
|---|
test_translator.py | Полный перевод инструкций x86-64 в Z3 BitVector (арифметика, флаги, переходы, память) | Z3Translator |
test_translator_edge_cases.py | Глубокое исчерпание AST, цепочки алиасинга памяти и граничные ограничения | `Z3Translato[...] |
test_deep_doubts.py | Знаковое переполнение, кубическая ньютоновская индукция (степень 3) и конгруэнции Безу | Mathematical Proofs |
| # | Целевой бинарный файл | Размер слайса | Статус Z3 | Обнаруженный ключ | Нативное исполнение | Время | Результат |
|---|
| 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] |