obfuskator/docs/learnings/priorities.md
loki5512344 c3b8d4dd62 docs: sync status with code, add AI-resistance research, restyle README
Documentation had drifted from the actual implementation: the noxis
(CLI) and noxis-verify crates were fully built and tested but every
doc called them "not started". Verified against the code (build +
test run) and corrected status across README.md, todo.md,
architecture.md, techniques.md and learnings/{lessons,priorities}.md.

Also:
- restyled README.md (badges, no em dashes, usage examples, dropped
  the redundant "Принципы" section already covered elsewhere)
- added docs/learnings/ai-resistance.md: a sourced writeup of what
  actually works against LLM-driven reverse engineering (Elastic
  Security Labs' Opus 4.6 vs Tigress study, the Acoda paper) and what
  of it applies to noxis, plus concrete todo.md §7 items
- noxis-structure-check: the 250-line/4-file gate was scanning
  docs/**, which fought against writing documentation freely; it now
  only scans crates/*/{src,tests,benches} and only counts .rs files
2026-10-08 22:34:00 +02:00

120 lines
9.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Что улучшим: стратегия и приоритеты
Материал собран из `info/evo-improvements.md` (план после разбора EvoVis) и
`info/evo-weaknesses.md` (провалы). Здесь — что мы берём, в каком порядке
и **что осознанно не делаем**.
## Стратегия в одном абзаце
Максимум защиты при минимуме риска сломать рантайм. Дешёвые техники,
дающие 80% результата, включаются по умолчанию; дорогие и опасные —
включаются **только** после того, как для них есть верификатор. Каждая
техника имеет измеримый критерий «сработала/не сработала», иначе это
не защита, а мнение.
## P0 — базовый уровень (дёшево, снимает главные утечки)
| пункт | что это | пасс | статус |
|---|---|---|---|
| A1 | переименование **всех** символов: классы, поля, методы, локальные переменные, параметры, record-компоненты, enum-константы, `SourceFile` | Rename | ✅ готово |
| A2 | вычистить `LineNumberTable`/`LocalVariableTable`/`SourceFile`/`InnerClasses`/`Signature`/`MethodParameters` | DebugInfo | ✅ готово |
| A3 | никаких сигнатурных имён у защитного кода, защитный код смешан с обычным | Rename + Noise | ✅ готово |
| A4 | обфусцировать **весь** архив, включая ресурсы, mixin-JSON, access widener, service loader'ы | Resources | ✅ готово |
| — | маппинг в отчёт (иначе не читаем свои же stack trace) | Rename | ✅ готово |
Это самый дешёвый блок и одновременно **самый большой утечка** в разобранном
образце: оригинальные `SourceFile` у 160 классов, имена полей и методов,
каталог модулей в атрибутах.
## P1 — строки и константы
| пункт | что это | пасс | статус |
|---|---|---|---|
| B1 | ключ на строку + ротация 3–5 схем + MAC + уникальный nonce | Strings | ✅ готово |
| B2 | **вывод** ключа в рантайме, а не константа в вызове | Strings + генератор декодера | ✅ готово |
| B3 | константы — не тождества, а вычисления, разнесённые по блокам | Constants | ✅ готово (int/long) |
| B4 | **ложная** отладочная информация: чужие имена переменных и строк | DebugInfo | ✅ `SourceFile` |
B2 — главное отличие от разобранного образца: у него ключ был константным
выражением в вызове и расшифровывался статически, без JVM. Мастер-секрет
теперь собирается в рантайме из двух частей (`k1 ^ k2`) декодером класса —
см. [`../stack.md`](../stack.md) §4. B4 пока покрывает только `SourceFile`;
ложные номера строк (`fake_line_numbers`) — см. [`../../todo.md`](../../todo.md) §3.6.
## P2 — контрольный поток
| пункт | что это | статус |
|---|---|---|
| C1 | **несколько схем** флаттенинга вместо одной, с мешаниной внутри метода | план |
| C2 | верификатор обязателен: ошибка CFG = `VerifyError` | ✅ готово (кадры + `java -Xverify:all`) |
| C3 | реальный объём ≠ раздувание: бюджет на размер и время | ✅ размер; время — план |
Приоритет здесь строго подчинён: **C2 раньше C1**. Кадры `StackMapTable`
и приёмка `java -Xverify:all` уже готовы (см. [`../stack.md`](../stack.md)
§3) — единственное, чего не хватает, это сами схемы флаттенинга (C1).
## P3 — измеримость (метрики, без которых ничего не доказано)
Обязательный блок, иначе фраза «обфускация есть» ничего не означает.
Крейт `noxis-verify` реализован — вот что из списка уже цифра, а что ещё мнение:
1. **Утечки имён.** ✅ `collect_names`/`find_leaks` — сверка идентификаторов
с учётом keep-списка.
2. **Читаемость декомпилята.** ⬜ Прогон JADX/CFR → доля распознанных
структур — не начато.
3. **Противник.** ✅ `scan_secrets` + `RED_PATTERNS` держим в репозитории;
⬜ полноценный скрипт-деобфускатор (свёртка констант) как тест — план.
4. **Семантика.** ⬜ Эталонные программы до/после — не начато
(сейчас семантику подтверждает только `java -Xverify:all`).
5. **Бюджеты.** ✅ размер (`inflation_ratio`/`check_inflation`);
⬜ время исполнения — не начато.
6. **Стабильность между сборками.** ✅ `mappings_changed` — маппинги
обязаны отличаться между прогонами с разным seed.
Итог: `noxis-verify` закрывает красные паттерны, утечки имён,
`java -Xverify:all`, бюджет размера и стабильность маппингов. Остаются
декомпилят-метрика, бюджет времени и эталонная семантика — три пункта,
где «нам кажется защищённым» всё ещё мнение, а не цифра.
## P4 — долгий горизонт (пока не делаем)
| пункт | что это | почему не сразу |
|---|---|---|
| D1 | маленький VM/interpreter для ценных кусков | цена окупается только на ключевом коде |
| D2 | split-function / раскрываемое по шагам тело | режет обычный профилировщик, сложная отладка |
| D3 | мягкий анти-анализ в рантайме | требует своего нативного компонента |
| D4 | честный anti-tamper, а не «зашейрь ключ» | целая инженерная задача, не пасс |
| E | собственный нативный/Rust-цель вместо JVM | другой продукт, не наша цель |
D1 — явно ограничен: включать только для действительно ценных функций,
остальное оправдания не имеет. E — отдельный продукт; если он когда-нибудь
понадобится, наш IR как раз делает его возможным (те же пассы, другой
writer).
## Что мы добавили сверх исходного плана
1. **Структурный гейт при компиляции.** Лимиты «250 строк / 4 файла»
гоняются в `build.rs` — см. [`../README.md`](../README.md). Без этого
план P0–P3 превращается в один гигантский файл через месяц.
2. **Собственный IR с метками.** Исходный план предполагал работу поверх
готового парсера. `Insn::Mark(Label)` убирает пересчёт смещений из
всех пассов — это меняет цену каждой техники, меняющей CFG.
3. **Детерминированный PRNG с доменным разделением.** Без этого
пункт «стабильность между сборками» невозможно проверить тестом.
4. **Keep как отдельный крейт (`noxis-analysis`), а не флаг CLI.**
Рефлексия, JNI, сериализация и entrypoint'ы — это анализ иерархии,
а не настройка, которую надо помнить руками.
## Порядок выполнения
Смотрите [`../../todo.md`](../../todo.md). P0–P3 и P3-измеримость уже
готовы; единственный крупный пункт, который остался, — схемы `Flow` (C1),
потому что верификатор (C2) для них уже есть:
```text
✅ P0 DebugInfo + Resources → главные утечки сняты
✅ P1 Strings (B2) + Constants → ключ выводится, схемы ротируются
✅ P1 backend (ristretto) + frames
⬜ P2 Flow (C1) — единственное, что ждёт реализации; верификатор готов
✅ P3 метрики, красные паттерны, CLI
```