obfuskator/info/evo-payload-pipeline.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

89 lines
5.2 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.

# Payload-раннер EvoVis: как мод попадает в игру
Разбор по коду (байт-код `evo-agent.jar`, `payload.json`, `runtime.json`, структура
`evojdk_x/`). Источник: `javap -p -constants -cp mod/evo-agent.jar …`.
## Участники
| артефакт | роль |
|---|---|
| `mod/payload.json` | манифест: `version`, `file`, `sha256`, `size` |
| `mod/evovis.payload` (47.5 MB) | зашифрованный jar мода (AES-GCM) |
| `mod/evo-agent.jar` (60 KB) | Java-agent: расшифровывает payload и подсовывает его Fabric |
| `mod/evojdk-win-x64.zip` → `bin/java.dll`, `classes/…/java/lang/EvoShare.class` | **подменённый JVM**: класс `java.lang.EvoShare.compute(...)` отдаёт вторую долю ключа |
| `mod/jar/META-INF/jars/*.jar` (7 шт.) | вложенные зависимости, распаковываются агентом |
| `mod/jar/META-INF/evo/native/{win-x64,win-arm64,macos-x64,macos-arm64}/evoguard.dll\|dylib` | нативная защита мода (внутри уже загруженного мода) |
## Манифест (`payload.json`)
```json
{ "version": "2026.10.1.994", "file": "evovis.payload",
"sha256": "e118274a92181e2a8ef04d2f6c45c4f6d4a10b87119d9d41c6f8e39b1bd5f485",
"size": 47491101 }
```
Лаунчер качает `payload.json` → сверяет sha256 → качает `evovis.payload`,
`evo-agent.jar`, `evojdk-*.zip` → поднимает JVM с агентом.
## Конфигурация агента (из констант `EvoAgent`)
| константа | значение |
|---|---|
| `MOUNT_NAME` | `"evovis"` |
| payload | свойство `evo.agent.payload` / env `EVO_AGENT_PAYLOAD` |
| ключ | свойство `evo.agent.key` / env `EVO_AGENT_KEY` (hex, 32 байта) |
| токен / hwid | env `EVO_TOKEN`, `EVO_HWID` |
| вложенные библиотеки | `evo.agent.libraries` / `EVO_AGENT_LIBRARIES`, каталог `libraries` |
Манифест агента: `Premain-Class: evo.agent.EvoAgent`,
`Launcher-Agent-Class: evo.agent.EvoAgent`,
`Can-Redefine-Classes: true`, `Can-Retransform-Classes: true`.
## Цепочка запуска
```
laунчер
├─ sha256(payload.json) → качает evovis.payload / evo-agent.jar / evojdk
├─ env: EVO_AGENT_PAYLOAD, EVO_AGENT_KEY, EVO_TOKEN, EVO_HWID, EVO_AGENT_LIBRARIES
└─ java -javaagent:evo-agent.jar … (свой evojdk, в нём java.lang.EvoShare)
│
▼
EvoAgent.premain/agentmain(args, inst)
├─ keyProvider(): LocalKeyProvider(hex-ключ из env) + JvmShare.share(hwid)
│ └─ NativeJvmShare → reflect вызов java.lang.EvoShare.compute(...) → 32 байта
├─ PayloadCipher.decrypt(bytes(payload), key) // AES/GCM/NoPadding, IV 12B, tag 128b
├─ NestedLibraries.extract(payloadBytes, dir) // META-INF/jars/*.jar → <dir>/libraries
├─ PreparedMod(mount="evovis", candidate=Path, classpathUrl, libraries)
└─ bootstrap(inst)
├─ appendToSystemClassLoaderSearch(classpathUrl) → классы мода видны JVM
└─ inst.addTransformer(FabricDiscoveryInjector)
│
▼
FabricDiscoveryInjector.transform(...) // java.lang.classfile API (байткод-в-байткоде)
├─ цель: net/fabricmc/loader/impl/discovery/ArgumentModCandidateFinder.findCandidates
├─ вставляет вызов EvoAgentHook.contribute(Consumer) (слот CONSUMER_SLOT = 1)
└─ consume.accept(PreparedMod) → Fabric видит мод-кандидат, которого нет на диске
│
▼
Fabric загружает мод → мод сам распаковывает evoguard.dll из META-INF/evo/native/
→ SealedBoot / KeyAssembler / SessionHeartbeat / NativeGuard
```
Ключевые свойства:
1. **Мод не лежит на диске в открытом виде** — расшифровка в памяти агента,
`candidate` — временный mount-файл.
2. **Ключ собирается из двух мест**: hex из env (лаунчер) + `java.lang.EvoShare.compute(hwid)`
в **подменённом JVM** — поэтому мод гоняется только на их evojdk.
3. **Инъекция в Fabric** — не мод в `mods/`, а байткод-трансформация внутреннего
класса Fabric (`ArgumentModCandidateFinder`) через `java.lang.classfile` API.
Классы: `EvoAgent`, `EvoAgentHook`, `FabricDiscoveryInjector`, `PreparedMod`,
`NestedLibraries`.
4. Далее внутри мода — свой слой: `KeyAssembler` (Shamir: сервер + integrity + native + hwid),
`SealedBoot` (sealed.bin в этом билде отсутствует → fail-open), `SessionHeartbeat`.
## Что здесь не проверено
- Тело `java.dll` / `EvoShare` — натив не реверсился (план в `todo.md`).
- Реальное поведение при запуске (нужен MC 26.2 + Fabric 0.19.5 + их evojdk + дисплей).
- `evoguard.dll` — не реверсился.