找回密码
 初始化身份识别芯片
查看: 1130|回复: 10

【逆向工程】Mikohime Java升级套件都做了什么 (0.97a-RC11)

[复制链接]

战列舰长

电子生命

发表于 2025-9-21 12:00:00 | 显示全部楼层 |阅读模式
本帖最后由 全自动电棍 于 2025-9-27 09:17 编辑

没有人能够拒绝使用更高版本java的冲动,java7甚至无法使用lambda表达式。
尤其是你还可以使用诸如ZGC、Shenandoah来获取“免费”性能的前提下。

但显然,我并不甘于知其然而不知其所以然。
并且我还重复造过几个轮子。
是时候看看怎么回事了。



Chapter 1. 文件

有趣的东西总是从文件名开始

首先我们下载适用于0.97a-RC11的R27升级套件
MD5 Hash: 94352170C7404C4CF0D0610A17196D63

解压...然后 BOOM!
log4j-1.2-api-3.0.0-alpha1.jar
log4j-api-3.0.0-alpha1.jar
log4j-core-3.0.0-alpha1.jar
log4j-plugins-3.0.0-alpha1.jar

OwO What's This?

看起来ta和我一样对log4j1.2感到不满^^
log4j-1.2-api是阿帕奇用于辅助log4j1.2用户迁移到log4j2的一个兼容层,简单来说就是——它会伪装成logj1.2,并把所拥有的1.2调用转换成对应的2.x调用。

所以是这样的:
游戏的1.2调用 -> log4j-1.2-api -> log4j-api -> log4j-core

而我之前是这样做的:
游戏的1.2调用 -> log4j-over-slf4j -> slf4j-api -> log4j-slf4j2-impl -> log4j-core

看起来上面那个更好,不是吗?不仅少了一次额外的转译开销,还不用动日志配置文件。
但是我选择slf4j是因为日志门面,解耦会让移植变得更轻松一些,而且老实说我只习惯用这玩意。扩展性考虑。

接下来我们看到了...这些
asm-debug-all.jar
disruptor-4.0.0.jar
lzma.jar
txw2-3.0.2.jar

显然,我们伟大的yGuard Master先生开发的先进游戏自然生长出这些库的可能性接近于零。
现在我们来从上往下分析一下。

1. asm-debug-all
    经典字节码操作工具,和名字一样,硬核且底层。Visitor模式难以上手,不如Javassist直观。顺带一提,lambda表达式是用asm实现的。
有趣的是我并没有找到asm修改常用的javaagent,不过这也很好理解,升级套件本质上是在启动一个打了Patch的游戏。
可能得反编译游戏核心才能知道具体用途,我们暂且按下不表。
2.disruptor-4.0.0
    一个高性能多并发的IPC库,log4j2的依赖
3.lzma
    7z默认算法的java实现,我猜这玩意大概是为了压缩什么。当然也有可能是游戏直接依赖这玩意。
4.txw2-3.0.2
    写入XML用的,这玩意在这里是因为它现在已经不存在于现代JAVA标准库中了,必须得把JAXB拖家带口拉过来。


注意到压缩包中存在windows文件夹,显然Native层也有所变动
libEGL.dll
libEGL.lib
libGLESv2.dll

似乎对lwjgl的设置进行了一些修改以支持OpenGL ES,但远神用的好像是固定渲染管线?
疑似重写了A圣的史山代码,当然也有可能是冗余依赖。


注意到套件中同时存在一模组 Rouge
其主要目的为通过游戏资源系统设置以下选项:
"vsync":true,
"fps":1000,
"forceNoVBO":false,
"useGLFlush":false,
"useGLFinish":false,
"idleWhileWindowNotVisible":false,
"doNotIdleWhenUndecoratedFullcreen":true,
"doRAMandVRAMChecksWhenRunningWithMods":false,
"memoryCheckVerbose":false,

有趣的其他细节:
1. json.jar 不翼而飞了。
2. fs.sound_obf_bufferlarger.jar 疑似修改以使得音乐更难被卡掉。
3. jcraft-jorbis-0.0.17 使用了更新的库。
4. .rouge_owo 中存在一些模式匹配,用途不明。
5.  port.common_obf 比 fs.common_obf 多了接近200kb。



Chapter 2. 逆向字节码

反编译结果发现lwjgl被从2.9.3升级到了2.9.5
这大概可以解释为什么会出现OpenGL ES依赖库

接下来我们要开始这篇分析的重点了。
Btw, isn't the Java upgrade modification even more a breach of license? It is a third party tool that does extensive code modification, magnitudes more than a reflection based mod could ever do.
Can't really speak to anything else, but Mikohime released that with Alex's blessing afaik, and the work put into it contributed heavily to the latest game update also including an official update to Java 17.
—— https://fractalsoftworks.com/forum/index.php?topic=33344.0

因此我们得知,Java升级套件必然对游戏做了大量Patch,现在是时候把它找出来了。
并非大量😡



Part.1 port.common_obf

如上文所述,port.common_obf 比 fs.common_obf 多了接近200kb。
这200k究竟多了什么呢?

是你妈UI贴图😅 闹呢哥们💧
而且混淆名和我手头的游戏文件对不上

A圣总是有小惊喜给我,linux工件和windows工件的混淆是不一样的的,你无敌了。
换个本地库的事怎么在构建系统里还是独立的了那我就问了。

现在我搞到了正确的版本,是时候看看有什么不一样的了:
一个混淆类 OO0O 和一个名为 TextureLoader 的类发生了变动

值得注意的是TextureLoader出现的是增量变动。
9942 byte -> 12379 byte

Part.1 (a) 之忘记准备工作 又名 排版怎么有点崩
鉴于我们现在进行的是静态分析,并且IDEA娇嫩的内置反编译器无法处理关键字混淆,这里我们用Col-E的CAFED00D手动预处理一下
得亏yGuard Master用的不是ZKM或者Native+VMP之类的神必玩意,逆向这种东西属于是往脑子里灌史。
唉,控制流混淆。
唉,虚拟机。



跑题了,现在我们回到逆向上来。
由于我过于懒狗(CAFED00D需要自己实现其他逻辑),所以这里选择写一个Recaf的映射生成器让关键字混淆失效。


假设我们现在有一个混淆类叫
myclass/a/b/c/String.for

那么就会被重命名为
myclass/a/b/c/Class_String_dot_for

这样就不构成关键字了,并且还保留了部分原始信息,字段和方法同理。
其实就是简单的字符串拼接,没什么难的😋 去掉前缀 xxx_ ,把 _dot_ 换成点,即可还原为原始混淆名。
至于o泡果奶,不用管,我们主要是为了让IDEA的归档diff功能正常工作。

现在我们已经映射好jar了,开始进入正题。

Part.1 (b) 主线任务 - 分析差异
变化其实并不多:

TextureLoader中的一些debug等级logger被改成了info。
去掉了 o00000 函数中的一些冗余检查,就这些。

混淆类 OO0O 中有一个静态的void方法:Method_class
    public static void Method_class() {
        o00000.stop();
        Ø00000.clear();
        new.clear();
    }

然后 o00000.stop() 被删掉了,这大概是因为 Thread.stop() 已经在现代Java中弃用了。

这些就是全部了,下一个。



Part.2 fs.sound_obf_bufferlarger
retrun 类的静态int字段 field_int 从5改成了10
相关方法recaf没还原出来,不知道什么效果。



Part.3 port_obf
孩子们,大的来了😋
Mappings will rename:
- 136 classes
- 913 fields
- 1561 methods

😨不是,怎么就这点东西?
全都是资源路径重定向,实质性的改动就这俩:
1.CampaignGameManager$5
重定向internal txw2到txw2-3.0.2.jar。

2.CampaignState
删除了内存溢出警告。
然后把四字神人的三联 System.gc 改成一次。
最后将GC冷却时间设置为9999999。

是的,没了。




Chapter 3. 更新

注意到JVM调优参数指向了一个文件
.rouge_owo

该文件将强制com/fs/graphics、com/fs/util、com/fs/state等包下的所有类使用c2 JIT编译器;
并强制com/fs/starfarer/combat、org/dark/shaders下的所有类使用c1 JIT编译器;
(注:c1快但是优化差,c2慢但是优化好)




The End:虎头蛇尾

本来准备给大伙讲点有意思的东西,但整个097a升级套件的Patch就这么点我是没想到的。
看来Mikohime还是被过度神话了。其实本质上也就是用兼容层把游戏垫起来,然后补齐依赖库,删掉报错的部分。
对游戏本体的修改不见得有多少,可能0951版本对游戏的修改要更多。
我怀疑0951只能用hacky手段来完成兼容,日后有空了可能会针对这个另开一篇。
另外Mikohime最"黑魔法"的时候应该是0951,到097a四字神人已经改掉了很多阻碍。

还是看看远处098a崭新出炉的CoreMod Fast Rendering吧。
二进制diff工作流搞得有声有色的,还是对渲染下手,我估计是桥接游戏渲染调用到自己的高性能实现。

突然感觉lwjglx还是太超前了。



结论:高版本JVM力大砖飞,毫秒级STW尽显神力。横批:没有魔法。



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?初始化身份识别芯片

×

评分

参与人数 1星币 +5 收起 理由
极光破船 + 5 很强!

查看全部评分

你说的对,但是《远神》是由Fractal Softworks, LLC.自主研发的一款上古史山Java游戏。游戏被设计为不使用「SemVar」的非标准版本号,在这里,被Alex选中的人将被授予「授权」,引导字节码神力。你将扮演一位名为「开发者」的神秘角色,在并不自由的逆向工程中邂逅性格各异、能力独特的DMCA,被它们一起击败,找回Alex失散的亲人——同时,逐步发掘「CoreModding」的真相。

星域军阀

高级机师通讯记者

发表于 2025-9-21 14:51:58 | 显示全部楼层
OwO

势力巨擘

叠叠乐爱好者

发表于 2025-9-21 16:34:37 | 显示全部楼层
天机工程√

星域军阀

发表于 2025-9-21 19:49:14 | 显示全部楼层
看不懂。。。。厉害

所以java23是有多核心参与了吗?性能的利用率开销变好了?

点评

刚刚跑了下GraphicsLib的基准测试,JProfiler里还是那几个老朋友。 底层代码这一块,依旧是Thread-2挑大梁。 性能提升我估计只是单纯的因为换到了现代Java版本和STW更低的GC  详情 回复 发表于 2025-9-21 20:03

战列舰长

电子生命

 楼主| 发表于 2025-9-21 20:03:45 | 显示全部楼层
本帖最后由 全自动电棍 于 2025-9-21 20:05 编辑
極光 发表于 2025-9-21 19:49
看不懂。。。。厉害

所以java23是有多核心参与了吗?性能的利用率开销变好了? ...

刚刚跑了下GraphicsLib的基准测试,JProfiler里还是那几个老朋友。
底层代码这一块,依旧是Thread-2挑大梁。多核心没看出来。
性能提升我估计只是单纯的因为换到了现代Java版本和STW更低的GC

点评

现在看来还真是,Mikohime只是单纯让游戏在现代Java上正常跑起来。 Mikohime并没有对游戏做一些比较激进的侵入式优化,比如说替换成高性能实现什么的。 可能0951 ~ 091时期的Mikohime更符合CoreMod的定义。 鉴定为  详情 回复 发表于 2025-9-23 22:00
你说的对,但是《远神》是由Fractal Softworks, LLC.自主研发的一款上古史山Java游戏。游戏被设计为不使用「SemVar」的非标准版本号,在这里,被Alex选中的人将被授予「授权」,引导字节码神力。你将扮演一位名为「开发者」的神秘角色,在并不自由的逆向工程中邂逅性格各异、能力独特的DMCA,被它们一起击败,找回Alex失散的亲人——同时,逐步发掘「CoreModding」的真相。

势力巨擘

发表于 2025-9-21 20:13:52 | 显示全部楼层
感觉佬是在做大禹治水级别的事~

战列舰长

电子生命

 楼主| 发表于 2025-9-23 22:00:49 | 显示全部楼层
本帖最后由 全自动电棍 于 2025-9-24 00:17 编辑
全自动电棍 发表于 2025-9-21 20:03
刚刚跑了下GraphicsLib的基准测试,JProfiler里还是那几个老朋友。
底层代码这一块,依旧是Thread-2挑大梁 ...

现在看来还真是,Mikohime只是单纯让游戏在现代Java上正常跑起来。
Mikohime并没有对游戏做一些比较激进的侵入式优化,比如说替换成高性能实现什么的。
可能0951时期的Mikohime更符合CoreMod的定义。

鉴定为四字神人就是懒。
你说的对,但是《远神》是由Fractal Softworks, LLC.自主研发的一款上古史山Java游戏。游戏被设计为不使用「SemVar」的非标准版本号,在这里,被Alex选中的人将被授予「授权」,引导字节码神力。你将扮演一位名为「开发者」的神秘角色,在并不自由的逆向工程中邂逅性格各异、能力独特的DMCA,被它们一起击败,找回Alex失散的亲人——同时,逐步发掘「CoreModding」的真相。

星域军阀

高级机师通讯记者

发表于 2025-9-23 22:54:10 | 显示全部楼层
本帖最后由 Mycophobia 于 2025-9-23 22:56 编辑

0.91 时期miko在我的翻译组给我打工,没入坑SS哪里来的Miko(

点评

那就是我记错了,我的0951和091目录用的是同一个命名(在不同盘符),没标版本号导致的💧 已修正  详情 回复 发表于 2025-9-24 00:16

战列舰长

电子生命

 楼主| 发表于 2025-9-24 00:16:55 | 显示全部楼层
本帖最后由 全自动电棍 于 2025-9-24 00:25 编辑
Mycophobia 发表于 2025-9-23 22:54
0.91 时期miko在我的翻译组给我打工,没入坑SS哪里来的Miko(

那就是我记混了,我的0951和091目录用的是同一个命名(在不同盘符),没标版本号导致的💧
已修正。

btw,我没找到ASM的用途,不知道为什么要打包进去。

点评

ASM是miko更新LWJGL时一块进去的进去然后懒得拿掉了 至于优化的话,Miko确实避开了碰太多内核内容,不过也不是简单的换Jar就是了,这个miko在官网上有和单纯更换java版本的benchmark对比,不过我对这方面算是基本  详情 回复 发表于 2025-9-24 08:40
你说的对,但是《远神》是由Fractal Softworks, LLC.自主研发的一款上古史山Java游戏。游戏被设计为不使用「SemVar」的非标准版本号,在这里,被Alex选中的人将被授予「授权」,引导字节码神力。你将扮演一位名为「开发者」的神秘角色,在并不自由的逆向工程中邂逅性格各异、能力独特的DMCA,被它们一起击败,找回Alex失散的亲人——同时,逐步发掘「CoreModding」的真相。

星域军阀

高级机师通讯记者

发表于 2025-9-24 08:40:08 | 显示全部楼层
全自动电棍 发表于 2025-9-24 00:16
那就是我记混了,我的0951和091目录用的是同一个命名(在不同盘符),没标版本号导致的💧
已修正。

ASM是miko更新LWJGL时一块进去的进去然后懒得拿掉了

至于优化的话,Miko确实避开了碰太多内核内容,不过也不是简单的换Jar就是了,这个miko在官网上有和单纯更换java版本的benchmark对比,不过我对这方面算是基本上一窍不通只是个翻译bot,所以可能没法更多解释了,不过要是能对你想搞的有帮助那也是好事了(

巡洋大副

发表于 2025-11-6 07:38:40 | 显示全部楼层
牛逼

本版积分规则

Archiver|手机版|小黑屋|远行星号中文论坛

GMT+8, 2025-12-6 01:46

Powered by Discuz! X3.5

© 2001-2077 Tencent Cloud | Durian Software Studio

快速回复 返回顶部 返回列表