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

9.5 KiB
Raw Blame History

Что улучшим: стратегия и приоритеты

Материал собран из 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 §4. B4 пока покрывает только SourceFile; ложные номера строк (fake_line_numbers) — см. ../../todo.md §3.6.

P2 — контрольный поток

пункт что это статус
C1 несколько схем флаттенинга вместо одной, с мешаниной внутри метода план
C2 верификатор обязателен: ошибка CFG = VerifyError ✅ готово (кадры + java -Xverify:all)
C3 реальный объём ≠ раздувание: бюджет на размер и время ✅ размер; время — план

Приоритет здесь строго подчинён: C2 раньше C1. Кадры StackMapTable и приёмка java -Xverify:all уже готовы (см. ../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. Без этого план P0–P3 превращается в один гигантский файл через месяц.
  2. Собственный IR с метками. Исходный план предполагал работу поверх готового парсера. Insn::Mark(Label) убирает пересчёт смещений из всех пассов — это меняет цену каждой техники, меняющей CFG.
  3. Детерминированный PRNG с доменным разделением. Без этого пункт «стабильность между сборками» невозможно проверить тестом.
  4. Keep как отдельный крейт (noxis-analysis), а не флаг CLI. Рефлексия, JNI, сериализация и entrypoint'ы — это анализ иерархии, а не настройка, которую надо помнить руками.

Порядок выполнения

Смотрите ../../todo.md. P0–P3 и P3-измеримость уже готовы; единственный крупный пункт, который остался, — схемы Flow (C1), потому что верификатор (C2) для них уже есть:

✅ P0 DebugInfo + Resources      → главные утечки сняты
✅ P1 Strings (B2) + Constants   → ключ выводится, схемы ротируются
✅ P1 backend (ristretto) + frames
⬜ P2 Flow (C1) — единственное, что ждёт реализации; верификатор готов
✅ P3 метрики, красные паттерны, CLI