记一次Chunithm的逆向

1411 字
7 分钟
记一次Chunithm的逆向

前言#

之前写过一篇关于中二的逆向,但是没什么成果,加上我确实没什么逆向的能力,所以删掉重新研究了一下

这次目标依然是实现AutoPlay,得益于Agent的发展,现在我们可以让Agent直接去访问IDA MCP来逆向,我们就不用啃反编译出来的狗屎了

注意:为了防止滥用,以下内容的函数偏移量/特征码被隐藏,仅提供思路给有能力的人去研究

所有操作都在私服进行,违规使用后果自负

逆向过程#

首先的话我想起我挺久以前看到的这篇文章

https://cloud.tencent.com/developer/article/2216947

里面实现全自动理论值的方式是修改游戏判定,使所有判定都指向大P

这是一个不错的方案,但是会带来一点小问题

比如说,Note会在越过判定线后变成大J,这样观感不会太好

我想起之前maimai的一个项目

通过内部钩子启动游戏内置的Autoplay

我们可以合理推测,中二也有Autoplay

怎么确定呢?我们想一想在Tutorial里就有自动击打Note的场景

寻找Hook点#

一开始想直接在String里搜索Autoplay,发现出来的并不是什么很有价值的东西

因此我打算从参考那篇文章,从判定的函数入手

我想起之前maimai的代码里面,与判定有关的函数一般都带有JudgeManger/JudgeTap之类的名字

因为中二是MSVC编译,因此大概率存在虚函数表,我们可以在IDA里搜索\\?\\?_7Judge.*

其中//?/_7是虚函数表在MSVC编译后的特征

Judge.*是通配符

很快就找到了 ??_7JudgeTapChecker@projView@@6B@ 这个函数虚表

我们对其交叉引用,发现在三个函数中被调用

第一个是这个

ida_MnbB3CUpMh.png
ida_MnbB3CUpMh.png

*this这个标志很明显,这是个构造器函数,因此我把他改名为了Constructor

顺着 xrefs 往下找,可以找到这个函数

NVIDIA_Overlay_7Nb7OGrDlk.png
NVIDIA_Overlay_7Nb7OGrDlk.png

很长,但是仔细看看可以发现这其实就是我们找的判定函数

里面有不少的if语句,最有意思的是截图中的这个if

这个 if 的判断在后面一大堆的 if 判定之前,后面的 if 是真正的判定逻辑,那这个 if 呢?

简单Hook一下发现这就是我们要的 Autoplay 的开关

直接用 Frida Hook 这个 if 判断的两个变量,使其恒成立,秒了

const engineInstance = safeReadPointer(ENGINE_INSTANCE_PTR);
if (engineInstance.isNull())
return;
const autoKeyA = engineInstance.add(OFFSET_AUTO_KEY_A);
const autoKeyB = engineInstance.add(OFFSET_AUTO_KEY_B);
safeWriteU8(autoKeyA, 1);
safeWriteU32(autoKeyB, 1);

说实话我不擅长读伪C 但MCP工具恰好弥补了这个缺点

虽然 LLM 做这方面并不聪明,但如果有思路提供给LLM的话他还是很强大的

别的实现思路#

我们也给自己加点难度,假如Agent能力不足其实是Token用完了,我的能力也不足以纯静态去分析,那还有什么办法呢?

我依然觉得一开始的那篇文章有些思路很有意思也很好玩

通过Frida-trace追踪函数的调用,我们只需要追踪游戏中负责处理Note判定的函数,然后直接在IDA中找到对应的函数分析 再用Frida-trace

一开始我发现IDA/CE的Debbuger无法附加,因为segatools或者游戏本身的反调试

后来我发现Frida是可以Attach的,因为Frida并不是传统意义上的 Debbuger

官方的定义 它属于动态二进制插桩工具,不走传统 Windows Debugger API

但因为需要注入chusanhook.dll保证游戏能启动,所以我们还是没有办法直接让Frida去spawn

我们看到inject.exe有个用法

Usage: inject [options] program args...
All options must precede the program name.
The following options are understood:
-h Print this message.
-d Attach to target as a debugger and print debug messages.
-p Pause the target until a debugger attaches to it.
Cannot be used with -d.
-w Wait for target to terminate.
Cannot be used with -d.
-k dll Inject the named DLL into the target process.
Can be specified more than once.

Segatools本身就提供了一个Inject的功能,我们可以让Frida-Gadget注入到游戏里,便于我们研究

之前只听说过Gadget,没真的实际用过,借着这个机会好好试试

我们去Frida的Release里下载Windows的Gadget Dll

放到游戏目录

Terminal window
inject_x86.exe -d -k chusanhook.dll -k frida-gadget.dll chusanApp.exe

默认Gadget就是Listen模式,所以我们不需要改Gadget的配置,只需要确保27042端口是chusanApp在监听就是没问题的

那篇文章是通过frida-trace批量hook游戏的几乎所有函数

但其实现在不需要,我们可以用Stalker去做

我们可以用用Stalker.follow(mainThreadId)去追踪主线程的所有call行为,我们只在游戏里进行特定操作数次

最后会把所有可能的call输出出来,我们再全部hook,一边打Note一边看控制台输出,知道哪个函数是一定在我们打Note的时候调用的就可以

这样的好处是不用一下子Hook几万个函数让游戏直接闪退,也不用多次运行排除噪声了

题外话#

实际上不用Gadget也是可以的,因为Frida的特性直接Attach就可以

动态寻找Hook点#

现在的Hook代码依然是硬编码函数名和识别符,每次游戏大版本更新我们都要重新做这些,那有没有方法可以让Frida动态寻找函数并Hook呢

这里写不动了() 等我以后补上吧

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

记一次Chunithm的逆向
https://cainongw.github.io/posts/chunithm-reverse/
作者
Cainong
发布于
2026-05-25
许可协议
CC BY-NC-SA 4.0
相关文章 智能推荐
1
记一次某八按键音游的逆向
逆向 前言 兄弟炒币赚了大钱,买了ADX放家里 由于兄弟几个都很变态(当然不包括我),就想到是不是可以买个郊狼回来玩玩 当然不是电那种奇怪的地方(),只是电大腿之类的 我的提议就是,Miss一次电一次 开始 逆向基于的版本是DX 1.56 也就是Prism Plus
2
VoiceMeeter的逆向与破解
逆向 前言 如果您看到了这,您需要知道的: 我不是专业的逆向人员,一定会有错误,遗漏的地方,您可以联系我指正或交流 其次,这不是教程,您需要有一定的逆向基础 疫情期间,由于 每天上课摸鱼 ,大部分时间都和朋友在语音 我便需要一些整活神器,来在与语音里 爆破我的朋友 我想起几年前发现的神器——VoiceMeter
3
Unity游戏逆向与mod开发:与你共享Lo-Fi故事(2) Todo同步
逆向 前言 我大概是写完了那个同步SMTC的mod,接下来就是用DOTween加动效还有一些细节修改就好了 那么我要实现我第二个目标了,就是Todo的同步
4
Unity游戏逆向与mod开发:与你共享Lo-Fi故事(1)
逆向 前言 看Steam家庭共享库的时候发现个这个游戏 基本上就是一个番茄钟+音乐+ToDo List的游戏&工具 顺便放了一个少女陪你干活 做的还是很精致的 我也很喜欢 Mod已经写完了 是一个同步音乐信息到游戏的mod 感兴趣的可以下下来看看 ChillMusicInformationSyncMod
5
记一次从 Hexo Blog 到 Astro Firefly Blog 的迁移
前端 Hexo 目前还是不怎么够我用,一个是 JavaScript 并不是很好写(相较于Astro 而言。一个就是 Hexo 的主题和生态确实远远比不上新的基于 Astro Svelte这些前端框架,因此我决定迁移
随机文章 随机推荐
Profile Image of the Author
Cainong
Caiw there 👋
公告
欢迎来到我的博客!这是一则示例公告。
音乐
封面

音乐

暂未播放

0:00 0:00
暂无歌词
分类
站点统计
文章
38
分类
16
标签
48
总字数
57,650
运行时长
0
最后活动
0 天前

文章目录