Shirona1337 f59d4c121c fix(patchify): guard HEAD inject arity and correct Embeddium patch docs
Follow-up hardening for the Embeddium/Sodium XRay compat patch (#54).

- PatchTransformer.injectHead now validates a handler's parameter list
  against the forwarded (receiver, args..., CallbackInfo) sequence before
  emitting bytecode. Name-only (desc="") patches match by method name
  alone, so a handler could bind to a target with a different arity or
  primitive parameter types and produce a VerifyError at class load. Such
  mismatches are now logged and skipped instead.
- Name-only matching in apply() now resolves the target method name via
  getHandlerTargetMethodName(), covering all handler kinds instead of only
  Inject/Overwrite.
- BlockOcclusionCachePatch javadoc: drop the stale claim that registration
  is guarded by Class.forName() (it is registered unconditionally, and must
  be), and clarify that Object params only protect against type mismatches,
  not arity mismatches.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 00:46:40 +08:00
2026-05-21 13:51:00 +08:00
2026-06-08 20:32:28 +08:00
2026-05-21 13:51:00 +08:00
2026-05-21 13:51:00 +08:00
2026-05-21 13:51:00 +08:00
2026-06-12 00:23:58 +08:00
2026-05-21 13:51:00 +08:00

Open Zen

由于老群被精神马来西亚人的小狗疯狂举报,因此无法与您继续互动。欢迎加新群 660304532 讨论本项目。

当您发现有不可用的功能时,欢迎开 Issues 描述或直接提交 Pull Request,我们将不胜感激!

Open Zen 是 Zen Minecraft 客户端的反混淆源码版本,几乎是由 Claude 协助逆向得到。目标版本为 Minecraft 1.20.1 + Forge 47.4.20。

原始 Jar 经过完整混淆:类/字段/方法重命名、控制流扁平化。我使用 Opus 4.7 对其进行了反混淆,并结合 Enigma MCP 和 Sonnet 4.6 对其类/字段/方法重命名进行猜测,最后将其还原为可读的 Java。最终产物是一个可以直接用 Gradle 构建的工程,而不是一个二进制 blob。

⚠️ 本仓库仅供学习与研究目的发布 —— 用于研究客户端侧游戏改造、ASM 字节码补丁和混淆/反混淆技术。在你不拥有的服务器上使用作弊客户端违反绝大多数服务器规则,请自行承担后果。

许可

原始混淆字节码未授予任何许可。本仓库中的反混淆产物、构建脚本与文档仅供研究与学习使用。如果你是 Zen 的原作者并希望本仓库下架或重新授权,请提 Issues。虽然提了也不会搭理你。

截图

Open Zen ClickGUI

开挂死妈

开挂死妈

精神马来西亚人认为,笔者在游玩《三角洲行动》时使用了外挂程序是疑似右手残疾的表现,正确的做法是练习枪法。因此使用本项目在《我的世界》中作弊可能会导致右手残疾,在使用本项目进行作弊前,请确认您的右手没有残疾!本项目不会对您的右手残疾付任何责任。

如果您在使用本项目时出现了疑似右手残疾的症状(如右手无力等),请及时关闭键盘声音以避免自己的生物爹对自己进行家暴行为。

我有抑郁症

众所周知,精神马来西亚人患有严重的精神疾病。结合此前精神马来人对其他亲朋好友的倾诉,笔者得知精神马来西亚人曾在群直播自己使用作弊客户端游玩《我的世界》游戏。但是突然下播,在长达半个小时的等待时间后,精神马来西亚人称自己由于键盘声音过大而惨遭家暴。

自残

因此精神马来西亚人长期通过自残、过量使用药物等行为缓解自己长期惨遭家暴的事实。

嗑药

嗑药

嗑药

跟风

或许是出自自卑, 精神马来西亚人在公开时称嗑药是跟风行为。对于精神马来人对过量使用药物的态度,笔者暂且蒙在鼓里。

大孝子

可能由于常年的家暴,导致精神马来西亚人的认知出现了错乱。又或许是长期多次的家暴导致精神马来西亚人患上了创伤后应激障碍,精神马来西亚人认为自己滚刀爹妈。笔者尚不明确精神马来西亚人所述的滚刀爹妈是何意味,但是笔者希望精神马来西亚人早日康复。

大孝子 大孝子 大孝子

发送低保

低保

当精神马来西亚人急眼时,将会自动查询你爹妈的户籍并且强制向你爹妈发送两份低保。

尽管关于印发《山东省最低生活保障管理办法》的通知明确规定了:

第二十三条  家庭财产状况有下列情形之一的,原则上不纳入低保范围:

(一)人均金融资产超过当地年低保标准2倍的;
(二)拥有机动车辆(普通二轮和三轮摩托车、残疾人用于功能型补偿代步的机动车辆除外)、船舶、大型农机具的;
(三)拥有两套及以上住房且住房总面积超过当地住房保障标准面积2倍,或者申请低保之前1年内以及享受低保期间购买超过当地住房保障标准面积商品房的;申请低保之前1年内或者享受低保期间,兴建、购买非居住用房或者高标准装修住房的;
(四)具有投资行为且人均投资数额超过当地年低保标准2倍的;
(五)雇佣他人从事经营性活动的;
(六)实际生活水平明显高于当地低保标准的。

设区的市可根据各自实际和财力条件,对家庭财产状况规定进行细化和调整,增加的支出由当地筹集安排。

个人所得税

但仅笔者一人,2026年个人所得税申报仅有约四十万人民币,笔者家庭明显符合不纳入低保范围的条件。笔者暂且不清楚精神马来西亚人向笔者全家发送低保的动机,可能是因为笔者惨遭家暴精神错乱致使其认为拥有低保是一件非常令人羞耻的事情。笔者建议精神马来西亚人早日纠正错误想法。

后门

警告!在阅读以下内容时,您可能会感到不适!如有不适,请及时关闭本页面,以避免自己笑出声音而导致惨遭生物爹家暴。

我们在逆向时发现原版Zen存在大量后门,例如上报QQ、屏幕截图、扫描文件、上传文件、远程执行命令等。因此我们不推荐任何用户继续使用原版Zen,除非你愿意现在把你身上的衣服脱掉然后去本地人最多的广场裸舞,然后把自己裸舞的视频发送到Zen的群内。

当Zen被注入后,会自动触发截图并上传至服务器。精神马来西亚人回应如下:

Screenshot Response

由于精神马来西亚人从小父母双亡,无父无母的精神马来西亚人自幼脑回路不正常。他认为虽然自己没有说自己的外挂会截图,但是由于自己截图,并没有遭到用户反对,所以所有用户都心甘情愿被截图全屏并上传到其服务器上。当然不排除所有Zen客户端用户都喜欢把身上的衣服脱掉然后去本地人最多的广场裸舞的可能性。

Snapshot

对此,笔者综合精神马来西亚人由于半夜玩电脑惨遭自己生物爹家暴的事实猜测:精神马来西亚人的生物爹和生物妈可能对精神马来西亚人的控制欲极强,因此精神马来西亚人的生活空间内可能存在十万甚至九万个摄像头,对精神马来西亚人的生活进行了无孔不入的监控。因此,精神马来西亚人在拉屎、自慰、睡觉、上课时都时时刻刻被监控,所以自然认为截图用户是正常且合理的行为。

笔者在此提醒:对用户的电脑进行无提醒、未通知用户的全屏幕截图,是不合理的行为。建议精神马来人端正自己对这个世界的认知,从自己过往被家暴经历中走出来,祝你早日康复!

分析

当Zen启动时,会自动调用 iIiIiIiIIIiIiI/Ʊ Đ()Ljava/awt/image/BufferedImage (Mapping),可能由于精神马来西亚人自知是后门,因此精神马来西亚人将此方法严防死守,惨遭没有逼卵子用的Native混淆。

以下是对该方法的Trace。

Screenshot Trace

可见,此方法调用了 java/awt/Robot;createScreenCapture(Ljava/awt/Rectangle),会将用户的全屏截图后返回。

继续向下追踪,发现其新建了 iIiIiIiIIIiIiI/ɿ (CPacketSystemInfo) (Mapping) 对象,我们对该类反编译,发现精神马来西亚人妈妈死掉了所以忘记删除Lombok自动生成的@ToString方法,因此惨遭Claude还原。

CPacketSystemInfo

此包会上传用户处理器信息、模组列表、虚拟机参数、系统名称、上报截图等信息,但笔者认为除截图外,其他信息收集在提前告知用户的前提下是合理的,因此并无不妥。虽然精神马来西亚人没有提前告知用户。

随后,笔者继续分析。由于该类继承了 iIiIiIiIIIiIiI/ɰ (Packet) (Mapping),我们分析了所有该类的子类。

遗憾的是,其他类由于没有添加 Lombok 标识,我们不得不通过其他方式 Trace 这些类的具体用途。经过我们不懈努力的调试和追踪,我们还原出了我们认为可疑的部分行为。

  • 远程命令执行 iIiIiIiIIIiIiI/ʔ
  • 远程文件下发 iIiIiIiIIIiIiI/ʏ
  • 远程文件浏览 iIiIiIiIIIiIiI/ʑ

以上不是全部

RCE

对于这些后门,精神马来西亚人作此解释。

Backdoor

精神马来西亚人称这些后门全部都是由夏天233制造,并非自己。并且这些后门并没有实现,所以可能是由于精神马来西亚人产生幻觉导致笔者抓到了Trace。而且并不能解释同是一套Network系统,为什么上传截图包实现了但其他方法没有实现。

其后其在视频中表示,是服务器在迁移时没有实现,而不是客户端没有实现。同时,精神马来西亚人在视频中表示没有功能,但是在QQ群中表示是夏天233写的。

Backdoor

由于精神马来西亚人嘴硬,所以到底具体有没有实现,笔者暂且蒙古。

父子相爱相杀

锦良炸弹

在很久之前,作为知名野狗的许锦良曾对精神马来西亚人进行过攻击:许锦良认为精神马来西亚人是他儿子,去日本是为了成为慰安妇,抚平自己被家暴的过去。

十进十出

但很明显,在本项目发布后,许锦良对OpenZen交流群创下了高达十进十出的历史记录。笔者在此猜测,精神马来西亚人曾因为自己半夜玩电脑由于敲键盘声音过大惨遭家暴的事情中迟迟无法走出阴影,因此自小时便缺失来自生物爹的父爱。而许锦良称精神马来西亚人为儿子,因此刚好补上了自己缺失的父爱这一块,私下便偷偷称许锦良为自己的父亲。自始,二人幸终。

笔者在惨遭许锦良十进十出狗叫时,认为许锦良可能已经完成前脑叶白质切除术,许锦良坚持认为两张照片是同一个人,对此许锦良掏出了以下证据:

Gemini Pro

由此可见,许锦良并没有思考的能力,结合自己亲儿子精神马来西亚人患有多种精神疾病的事实与精神马来西亚人认为Telegram查询机器人的事实,证实了笔者在前提到的前脑叶白质切除术。笔者在此希望许锦良父子能够早日康复。

Xinxin

但精神马来西亚人在QQ群中指出,欣欣使用过外挂后门远程读取他人文件。不知作为德州骡子的许锦良见自己的亲生儿子如此指认自己作何感想。

原始 Jar + Mapping

原始Jar Mapping

需要说明的是,部分喜欢裸舞的忠实Zen用户认为本源码逆向自比较旧的Zen版本。可能是因为这部分用户的脑容量只允许自己导入其他配置,因此不认识Zen的老旧UI。因此必须要说明,此源码使用的原始Jar截止至2026年5月21日是最新的。

细节

经过Opus 4.7长达18秒的分析,Opus认为所有的类由惨遭魔改的Zelix KlassMaster混淆。除了Zelix的Invoke Dynamic和String Encryption外,还有部分未参与任何计算的 Integer / Long 变量花指令代码和仅在部分方法中出现的 Flow 混淆。

其中大部分类都可以经过小修小补的现有Zelix反混淆器完成,关键部分的cinit被Native保护,导致在Java层中没有对应的Master Key可以对Invoke Dynamic和String反混淆。但可能由于精神马来西亚人的脑袋在马来西亚骑摩托被其他车创飞导致脑溢血,即使你没有通过客户端认证也可以完整加载Native并对Class进行注册。因此我们完整的还原了所有类的Invoke Dynamic和String混淆。

其他的混淆经过Opus长达30秒的分析,顺利写出了反混淆器。 但被Rename后的代码几乎不可读,因此我用Opus 4.7制作了Enigma MCP,接入Sonnet 4.6对其参照部分客户端进行了反混淆。

再使用Opus 4.7对本项目经过长达6小时的修复和少量的人工修复,便得到了这份源码。

抄袭

此项目大部分功能模块几乎全部抄袭自Naven客户端,具体详见以下分析。

详细分析

状态与注意事项

  • 这是尽力而为的反混淆结果,部分符号是根据上下文重建的,可能与原作者的命名意图不一致。

构建

OpenZen 支持两种交付形式:Java Agent jar(挂到 Minecraft JVM 启动参数里)和 热注入器 (单文件 EXE,内嵌 DLL)。Agent 路径只要 JDK,注入器路径还需要 MSVC 工具链。

本项目不能作为 Forge mod 启动。 mods/ 加载路径不被支持,不要把 jar 丢进 .minecraft/mods/。

编译时类名混淆(重要)

每次构建,OpenZen 会自动把所有自有类(shit.zen.* / asm.patchify.*)重命名为随机的 16 位名字——包名和类名都随机,每次构建都不一样、互不重复,原始类名/包名一律不保留(连日志里残留的类名字符串也清理掉了)。引导链(Agent 入口、DLL 加载、Class.forName)会在构建时自动联动到新名字,无需手工处理。两种交付形式(jar / 注入器)都已混淆。

这是为了对抗按类名黑名单工作的反作弊(见下方常见问题)。正因为名字每次构建随机:

⚠️ 从 GitHub Actions / Release 下载到的是预编译版本,所有人拿到的是同一套混淆名——这套固定的名字随时可能被反作弊收录进黑名单。想要一套别人都不知道、独一无二的类名,请自己编译:

  • Fork 本仓库,在你自己的 GitHub Actions 里跑一次构建(每次运行都生成全新随机名),下载你自己的 artifact;或
  • clone 到本地自己 gradlew jar / gradlew dll(每次本地构建同样是全新随机名)。

每次构建的"旧名 → 新名"映射写在 build/rename-mapping.txt(CI 也会把它作为 artifact 上传、并附到 Release),这是反混淆崩溃日志的唯一依据。注意它每次构建都不同,务必和对应产物一起保存。

实现细节见 build.gradle 的 ext.obfuscateJar:用项目自带的 ASM 在 ForgeGradle reobf 之后对产出 jar 做 ClassRemapper 重命名,只改类名、不动方法/字段名(避免破坏反射、JNI、@SerializedName 等)。

共同前置

  • JDK 17(推荐 Microsoft Build of OpenJDK / Temurin / Azul Zulu 任一)。

  • 必须设置 JAVA_HOME 环境变量指向该 JDK 安装目录(PowerShell 验证:echo $env:JAVA_HOME)。

  • 仓库根目录用 gradlew.bat 即可,不需要单独安装 Gradle。

  • 可选:UPX —— 仅热注入器路径会用到,作用是把最终的 OpenZenLoader.exe 从 ~32 MB 压到 ~10 MB。在 PATH 上检测到 upx 时 ./gradlew upxCompress 会自动跑 --best --lzma;找不到就只打一条 warning 直接跳过,不影响功能。安装方式:

    choco install upx -y
    

    或者从 https://upx.github.io/ 下载 ZIP 并把 upx.exe 加进 PATH。

首次执行会从 ForgeMaven 下载 1.20.1 + Forge 47.4.20 的 mappings 和依赖,耗时几分钟到十几分钟,取决于网络。

1. 构建为 Java Agent jar

零额外依赖。

.\gradlew.bat jar

产物:build/libs/hey-1.0.jar。在 Forge 启动器的 JVM 启动参数里加上:

-javaagent:"完整\路径\到\hey-1.0.jar" -Djdk.attach.allowAttachSelf=true

PatchAgent.premain 会在 Minecraft 类加载之前装载所有 ASM 补丁;-Djdk.attach.allowAttachSelf=true 是让 installPatchesAndRetransform 在需要时能兜底走 Attach API。

2. 构建为热注入器 (单文件 EXE)

产出一个独立的 OpenZenLoader.exe,DLL 已经作为资源段嵌入 EXE 内部。用户分发只需要这一个文件,运行后 GUI 列出当前所有 javaw.exe 进程(含 Minecraft 窗口标题),选中后点 Inject 即可。

额外前置 — 必须项

  1. Visual Studio 2022(Community 版即可,免费)。安装时勾选:

    • "使用 C++ 的桌面开发" 工作负载
    • 该工作负载的可选组件里勾上 "适用于 Windows 的 C++ CMake 工具"("C++ CMake tools for Windows")
  2. JAVA_HOME 必须指向 JDK 17(不只是 JRE)。CMake 需要它定位 <JAVA_HOME>/include/jni.h 和 <JAVA_HOME>/include/win32/jvmti.h。

  3. CMake:VS 2022 自带,Gradle 会自动检测——也可以独立安装 CMake 并加入 PATH。Gradle 的检测顺序:

    1. PATH 上的 cmake.exe
    2. 通过 vswhere.exe 找 VS 2022 自带的 CMake
    3. 常见独立安装位置 (%ProgramFiles%\CMake\bin\cmake.exe 等)
  4. vcpkg(注入器 GUI 用 Qt6,由 vcpkg 提供静态库)。一次性安装:

    git clone https://github.com/microsoft/vcpkg.git C:\vcpkg
    C:\vcpkg\bootstrap-vcpkg.bat
    

    Gradle 检测顺序:环境变量 VCPKG_ROOT → C:\vcpkg → D:\vcpkg → %USERPROFILE%\vcpkg。 首次 ./gradlew dll 时 vcpkg 会按 native/vcpkg.json 编译静态 Qt6(30 分钟到 2 小时,看 CPU),之后增量 build 几分钟。Qt 完全静态链接进 EXE,所以分发依然单文件——OpenZenLoader.exe 自带 Qt6 + OpenZen.dll,零运行时依赖。

构建命令

.\gradlew.bat dll

产物:build/dist/OpenZenLoader.exe。如果已装 UPX 想顺便压缩,跑 .\gradlew.bat upxCompress。

使用注入器

  1. 用 HMCL / Forge 启动器正常启动 Minecraft 1.20.1 Forge(不需要任何特殊 JVM 参数)。
  2. 双击 OpenZenLoader.exe。
  3. GUI 自动列出系统里所有 Minecraft 实例,每秒自动刷新一次。
  4. 点击行最后的 Inject 按钮。

诊断日志:

  • Native 端:%TEMP%\openzen.log
  • Java 端:Minecraft 自己的 logs/latest.log(类名已被构建时混淆、logger 名是随机的,改用固定日志文案定位,如 bootstrap.start、bridge.load、agent attached、Runtime mapping)

常见问题

布吉岛反作弊绕过

截止至目前(2026/05/23),布吉岛并未检测本项目,考虑其反作弊为黑名单类名机制。 建议构建时修改类名。 类名已黑名单,请在构建时修改类名。 类名已黑名单。现在每次构建都会自动随机化全部类名(见上方编译时类名混淆)——但务必自己 Fork/clone 编译,别直接用 GitHub Actions / Release 上的预编译版:那是固定的一套名字,会被拉黑。

致谢

S
Description
完全开源的辱华客户端Zen。
Readme 55 MiB
Languages
Java 93.2%
C++ 5%
HTML 1.5%
CMake 0.3%