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

5.2 KiB
Raw Blame History

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)

{ "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 — не реверсился.