早在9.15的时候其实就开始尝试分析YS了,不过那个时候没啥动力,后来一次面试说可能用到,就尝试做了一下。
以前都是试着搞一下小一点的游戏,第一次对这种有一点名气的厂商下手,心里还是挺打鼓的(典型欺软怕硬)。
全程边肝游戏边逆差不多陆陆续续搞了一周吧,对于我这种菜鸡大学生来说花了不少时间。
之前搞完丢一边没管了,最近放假加拔智齿导致茶饭不思,有人提到了就又想起来了,还是记录一下分析过程,方便拾遗。
以下源自于9.15时的开服版YS,地址等相关信息和现版本不同。
翻一下游戏目录,可以看出是一个登录器加U3D游戏的结构。
看到global-metadata.dat文件加UserAssembly.dll,il2cpp模式的没跑了。
试着上il2cppdumper,看看能不能行,结果理所应当地直接跑崩了。
上IDA,看看做了啥手脚。
要说il2cpp模式下的保护,最常见的应该就是在MetadataCache::InitializeMethodMetadata和MetadataCache::Initialize这两个个函数中对gm文件进行解密工作,我们可以通过比对Unity提供的源代码,就可以很快发现一些线索。
首先是载入gm文件的部分,根据字符串“global-metadata.dat”搜索定位到疑似MetadataCache::Initialize函数,找到加载的部分,发现在加载完文件之后以字节数组和文件长度为参数调用了一个未知的函数:
这种形式很明显了,加载文件之后调用的这个函数大概可以判断为解密函数了,找到这个函数指针看一下,发现它的初始化是来自于一个导出函数,这个函数初始化了三个其它函数地址:
标记一下这块区域,这三个函数地址应该是我们需要重点关注的对象了(图这里已经确定作用了做好标记了,原始文件没有信息)。
接下来去MetadataCache::InitializeMethodMetadata这个函数瞅瞅。
这里可以追踪s_GlobalMetadata和s_GlobalMetadataHeader两个指针,这里大部分操作都是围绕着这两个指针进行的。
在熟悉的kIl2CppMetadataUsageStringLiteral分支里发现了猫腻,这个分支会处理字符串相关的东西,返回Il2CppString类型的值。因此这里也常被用来加密字符串:
这里调用的GetStringLiteralFromIndex函数正好就是存在之前标记的那块区域的三个函数之一,可以确定这里也被魔改了,调用了外界的解密函数。
那么就剩下最后一个函数了,对那个函数进行交叉引用,发现之前加载gm文件的上级函数有调用过这个函数,跟进去,发现这里才是真正对应MetadataCache::Initialize函数的地方,前面那个函数应该是被摘出来用来加载gm文件的部分。
进入这个函数,对着官方的源代码找,确定了这个函数的作用:
除了这三个函数之外,还可以注意到Il2CppGlobalMetadataHeader也被动了手脚:
这里原本应该是:
这种打乱偏移的东西恢复起来没啥技巧,找使用的地方,然后对着还原就行,就是挺费精力的。
这几个地方搞好之后,就可以魔改il2cpp把信息dump出来了。
哦对了,还有一点小插曲,在这三个函数的使用上面,我一开始尝试直接载入这个dll然后调用这三个函数,发现炸了,看着三个函数还做了流程混淆直接就不想分析了,后来猜想可能是在游戏运行的时候对一些值进行了初始化,这三个函数需要读取外面的值,就动态注了一个dll进去,和外界魔改的il2cppdumper进行进程通信,才把符号搞出来。
还好非Unity引擎层面的常规保护米忽悠没怎么注重,就搞了常规的那一套,Object钩子之类的,要不然还得麻烦。
最后展示一下成功,一个小小的透视挂,前期缺经验找宝箱时做的:
总结一下米忽悠对于YS的保护思路:
1、常规保护,这个没啥可讲的,不是新鲜手段。
2、global-metadata.dat文件保护,这里米忽悠采取了两个方法,第一个是针对整个gm文件的加密,在加载这个文件时再对整个文件进行解密;第二个是打乱了Il2CppGlobalMetadataHeader结构,让il2cppdumper无法正确地按照原有的结构获取gm文件的头信息。
3、字符串保护,符号文件保护嘛,字符串保护也是手段之一,这里的GetStringFromIndex和GetStringLiteralFromIndex两个函数都是原本il2cpp就有的函数功能,米忽悠将它们替换为了一个带有解密功能的函数,使il2cppdumper无法正确地获取到字符串信息。
4、这里是最恶心的一种手段,因为它没有方法破解,所以我上面也没有提到。这是啥呢?直接Hash混淆字符串,它把非引擎或者不需要通过字符串使用的符号信息全给混淆了:
还记得我上篇记录这么提到过:
一个Unity游戏保护方案的分析和还原符号信息,偷学对global-metadata保护的思路
说啥来啥就出现了,这种直接把字符串变成无意义的(大概是某种Hash算法)信息永远是最恶心破解者的。
快要毕业了,下学期估计就是边毕设边实习了。
之前实习过一道了,感觉还不错,同事大家都挺好的,帮了我很多。之前在面经里看到各种实习陷阱云云,还在担心自己会不会踩坑,目前来看可以放心工作啦。
防御别人和攻击别人是两个难度,虽然现在的我可以说着这些保护的优缺点在哪里云云,但是真让我自己上去做保护,估计也得摔不少跤,慢慢来吧。
希望以后我能坐在办公室里思考怎么用更恶心的保护恶心别人吧。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)