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

42 lines
2.9 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.

# Обфускация 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 классов с такими именами нет.