obfuskator/info/evo-obfuscation.md
loki5512344 a641e69455 Initial commit: noxis JVM bytecode obfuscator
Workspace of 9 crates (noxis, noxis-core, noxis-classfile, noxis-analysis,
noxis-passes, noxis-runtime, noxis-jar, noxis-verify, noxis-structure-check).
AGPL-3.0-only license, Rust 2024 edition, unsafe_code denied.
2026-10-08 22:01:03 +02:00

2.9 KiB
Raw Blame History

Обфускация EvoVis / EvolutionDLC

Три уровня

  1. Имена — 1277 классов вынесены в default package с именами вида a…aa…; миксины разбросаны по пакетам a/ и b/. Смысловых имён классов в коде нет.

  2. Строки — все строковые литералы зашифрованы вызовом awc.d(cipher, key):

    • LCG: state = state * 1103515245 + 12345 (32-бит переполнение);
    • байт: cipherChar ^ (state >>> 24);
    • результат — UTF-8 строка. Ключи передаются «непрозрачными» целыми (см. ниже). Второй вариант awc.g(...) — то же самое плюс session-gate: строка расшифровывается только после проверки сессии через рефлексию aln.key().
  3. Контрольный поток — тела методов разложены в машину состояний: while (true) { switch (состояние) { case <обфуск-константа>: ...; состояние = <следующая>; } }. Переходы между блоками — через присваивание целому и обратный goto. Из-за этого объём декомпилированного кода раздут примерно в 25 раз относительно реального.

Кодировка целочисленных констант

Все литералы записаны через тождества (по модулю 2³²):

Паттерн Равен
(A ^ B) + ((A & B) << 1) A + B
(A | B) + (A & B) A + B

Так прячутся даже 0, 1, 16, 255. Например, true/false приходят как выражение, равное 1/0 (javac такого не генерирует — это работа обфускатора). Сдвиги и маски тоже закодированы: сдвиговые константы в байткоде могут быть отрицательными — JVM маскирует количество бит по младшим 5 битам (ishl/ishr со сдвигом -8 работает как сдвиг на 24), поэтому >> -8 в байткоде эквивалентен >> 24 в исходнике.

Прочее

  • Декой-классы обфускатора — пустышки с бессмысленными членами, в логике не участвуют.
  • Из-за имён-ключевых слов (if, do, …) декомпилятор переименовывает такие классы (Cif, Cdo) — в самом jar классов с такими именами нет.