Proven by paranoid runs over lorep (17 classes, fully green), LoVisual (4081 classes) and oc2r (1278 classes) with per-class java -Xverify:all, each fix first reproduced as a red test: - merge: Top absorbs instead of Top-wins (javac declares Top for slots unwritten on some inflow; precise types reject those edges). Regression: loop_head_keeps_top_for_loop_local. - emit: collapse [Long|Double, Top] pairs on operand stacks (javac writes one entry; the pair is rejected). Regression: wide_stack_join_emits_single_entries. - xfer ArrayLoad: push the wide pair, fixing lcmp underflow. Regression: array_load_wide_pushes_pair. - xfer <init>: convert only the receiver's own allocation site instead of every Uninitialized (nested construction clobbered the outer object). Regression: nested_construction_keeps_outer. - xfer ANewArray: array operands gain one dimension ([B] -> [[B) instead of an illegal L-wrap ([L[B;). Covered by the same test. - jar load: duplicate class names (multi-release module-info twins) keep the first occurrence instead of crashing save. Test: duplicate_class_names_keep_first. - strings/constants: skip methods past MAX_METHOD_INSNS (8000) so giants cannot overflow the 64KB writer ceiling. Tests: oversized_methods_are_skipped in both passes. - merge errors now name both types being merged. Also: em-dash removed repo-wide (724 spots, rule added to todo.md), allow-lints only in tests (scratch example deleted), code comments migrated to English in every file this change touches.
5.7 KiB
Вырезка бэкенда, авторизации и телеметрии (2026-10-02)
Локальный патч их клиента (mod/evovis-dec.jar) по решению владельца: без их сервера,
без их аккаунта, без отправки данных. Ничего из этого не трогает LoVisual.
Артефакт
| Файл | Размер | Что это |
|---|---|---|
mod/evovis-dec-nobackend.jar |
47 481 810 B, sha256 8c1f262687c056b2… |
evovis-dec.jar +3 перепакованных класса |
Исходники патча: patch/src/ (копии из mod/jar-src/sources/defpackage/), смоук: patch/smoke/.
Метод
Их классы лежат в корне джара (default package; jadx называет его defpackage).
Классы v69 = Java 25 → компилировали /usr/lib/jvm/java-25-openjdk/bin/javac против
evovis-dec.jar + ~/.gradle/caches/fabric-loom/26.2/minecraft-merged.jar (mojmap) + gson,
затем jar uf в корень копии джара.
Важные артефакты jadx, которые пришлось учесть:
- jadx переименовал их класс
if→Cif(keyword): классCif.classв джаре не существует, поэтому весь мёртвый код с ссылками наCifвырезан, а не пересобран. ?? r1;(недообфусцированный фрагмент) иthrow th;вне catch - в вырезанных методах.- Обфускация
setDaemon((A^B)+((A&B)<<1))- это int-эквивалентtrue(A+B=1), javac не берёт.
Что заменено
cp = Avatar2 (аккаунт)
initialize()→setUser(new cr("Player", null, "user", 0, null)): нетPOST /api/auth/me, нет чтенияEVO_TOKEN, нет лаунчер-сессии, нетrefreshMe(HTTP). Профиль - локальный dummy.isAuthorized()→return true- открываются все их шлюзы (Panel,Camera2,First,Friends,Crosshair2,KeyAssembler,SessionHeartbeat).user()→ lazy-dummy: если профиль не задан, создаёт тот же dummy.token == null- принципиально:KeyAssembler.token()иSessionHeartbeat.token()возвращают null →AttestClient4(evovis-protect.vercel.app: challenge/attest/heartbeat) недостижим, поток сборки Shamir-ключа крутится вхолостую (sleep 500 мс).- Удалён приватный
refreshMe()(единственный источник HTTP на auth/me).
akj = Report (телеметрия)
submit(String)→ no-op (единственный внешний вызов -dn/Message2, их команда отчёта).- Удалены
feedback,buildBody,run(достигались только изsubmit).
alr = SessionHeartbeat (сессия/отключение модулей)
initialize()→ no-op: потокevo-session-heartbeatне стартует → ниACTIVE/REVOKEDкаждые 60 с, ниREVOKED×2 → «выключить все модули».- Удалены приватные
run/tick/suspend/restore/reassert/showNotification/manager/token/sleepQuietly.
Почему остальное работает без их сервера
- Обычные строки мода -
awc.d(String,int): статический LCG+XOR, ключа не требует. SecureStrings(5 API-блобов: probe/friends/messages/cosmetic_sync/config_share) -KeyAssembler.key()всегда null →get()возвращает null → их серверные фичи (синк друзей, сообщения, косметика, конфиги) выключаются сами, без крашей на старте (null проверяется в самомSecureStrings.get).KeyAssembler/SealedBoot/RuntimeGuard/JNINativeGuard- живут только после сборки ключа, то есть недостижимы приtoken == null.
Оставлено (осознанно)
| Что | Почему |
|---|---|
Ticket (тикеты поддержки) |
только по явному клику пользователя, с token==null отправлять нечего |
Evovisuals2 (аватарки head/*.png, mc-heads) |
косметика, грейсфейл, неактивно без друзей/аккаунта |
Route (зеркала delivery*.evoproject.xyz) |
бесполезен: запросов к их хостам больше нет |
| Сторонние API (lrclib, mc-heads, yt-dlp, whisper) | их бэкенд, не трогаем |
Проверки
javap -c:cp.isAuthorized→iconst_1/ireturn;cp.initialize→new cr(…Player…);akj.submit→return;alr.initialize→return.- Смоук (
patch/smoke/Smoke.java, JVM 25, classpath = патченный джар + MC + gson):
isAuthorized = true
user = Player token=null
isSuspended = false
OK: auth=local, report=no-op, heartbeat=off
Ограничение
В игре не прогоняли: здесь Linux, а их evojdk только win-x64. Запускать патченный джар -
на Windows (их лаунчер или свой fabric-лодер); при проблемах - смотреть лог на загрузке
модулей. Ожидаемо «пустым» (серверное) останется: список друзей, сообщения, косметика синк,
аватарки, тикеты.