记对某安卓Unity3D音游的逆向

查看 83|回复 11
作者:rsjw   
0x00 背景
在打某个单机音游时手残打不过一关
不能透露包名
0x01 解包
Unity脚本后处理的两种方式 Mono / IL2CPP,将C#脚本转为中间语言il,所以关键的脚本都在其中。
使用 APKTOOL 解包之后,在 lib/arm64-v8a 下发现了 libil2cpp.so,说明这个用了 il2cpp。


a.png (128.34 KB, 下载次数: 0)
下载附件
2022-8-30 11:13 上传

用 IDA 打开之后无从下手,按照 il2cpp 的方式,需要先找到元数据 Metadata。
打开 assets\bin\Data\Managed\Metadata 目录,但是惊讶地发现只有一个 game.dat,而且不是 global-metadata.dat。为了方便,决定直接从内存里找。global-metadata_dump 就是从内存中 DUMP metadata 的工具,原理是识别 Metadata 特殊的文件头,效果十分好。
安装 Frida 和安卓虚拟机,连接好之后使用 global-metadata_dump,得到正确的 global-metadata.dat,再使用 il2cppDumper 成功恢复 Assembly-CSharp.dll 等。


a.png (600.66 KB, 下载次数: 0)
下载附件
2022-8-30 11:16 上传



a.png (175.17 KB, 下载次数: 0)
下载附件
2022-8-30 11:16 上传

0x02 逆向
使用 il2cppdumper 自带的功能将 dump 出的信息用py脚本导入 IDA 中。
初心是想研究一下存档文件,文件看上去是这样子的:


a.png (1.12 MB, 下载次数: 0)
下载附件
2022-8-30 11:17 上传

编码显然是 Base64,但是解码后乱七八糟,说明有什么特殊的编码/加密方法。
是用 UnityEngine::PlayerPrefs 生成的,于是来到这个函数,使用 jump to xref


a.png (145.97 KB, 下载次数: 0)
下载附件
2022-8-30 11:18 上传



a.png (244.19 KB, 下载次数: 0)
下载附件
2022-8-30 11:18 上传

看上去应该和 SaveManagement 有关系,


a.png (274.45 KB, 下载次数: 0)
下载附件
2022-8-30 11:18 上传

改好之后发现加密在这个 Encrypt 函数:
现在使用 DnSpy 导入 DLL:


a.png (171.87 KB, 下载次数: 0)
下载附件
2022-8-30 11:19 上传



a.png (241.63 KB, 下载次数: 0)
下载附件
2022-8-30 11:19 上传

反复研究之后,发现这是先都转化成 UTF-16,然后使用 C# 自带的 DESCryptoServiceProvider 加密,然后再转成 Base64 的。经过查阅资料,默认方式为 CBC,PAD 是 PAD_PKCS5。
问题就在于找到这个密码了。根据以上规则,C# 默认方式一定需要恰好4个英文字符。


a.png (63.1 KB, 下载次数: 0)
下载附件
2022-8-30 11:20 上传

刚好是四个大写字母。
0x03 验证
经过这一遭,我写了一个丑陋的 Python 代码。
import pyDes, base64
DES_SECRET_KEY = "????".encode("utf_16_le")
def Dec(base64_str):
    base64_str = base64_str.replace("%2B", "+")
    base64_str = base64_str.replace("%2F", "/")
    base64_str = base64_str.replace("%3D", "=")
    des_obj = pyDes.des(DES_SECRET_KEY, pyDes.CBC, DES_SECRET_KEY, padmode=pyDes.PAD_PKCS5)
    s = des_obj.decrypt(base64.b64decode(base64_str))
    return s.decode("utf-16")
def Enc(s):
    s = s.encode('utf_16_le')
    des_obj = pyDes.des(DES_SECRET_KEY, pyDes.CBC, DES_SECRET_KEY, padmode=pyDes.PAD_PKCS5)
    base64_str = base64.b64encode(des_obj.encrypt(s))
    base64_str = base64_str.decode()
    base64_str = base64_str.replace("+","%2B")
    base64_str = base64_str.replace("/","%2F")
    base64_str = base64_str.replace("=","%3D")
    return base64_str
raw = input()
print(Dec(raw))
果然成功了。


a.png (47.55 KB, 下载次数: 0)
下载附件
2022-8-30 11:20 上传

不过改完之后立马就索然无味了。
0x04 Patch
我还有些想法,想放宽游戏中的判定时间:


a.png (139.94 KB, 下载次数: 0)
下载附件
2022-8-30 11:21 上传

ARM 的架构使得 IDA 不支持直接修改汇编指令。所以要自己计算 HEX,用这个 网站 改了数据。
具体来说,如果像我一样不熟悉,网站不能自动识别部分格式的命令,可以导入 HEX 转出来汇编再编辑。
重新打包签名安装之后:果然奏效了。


a.png (227.87 KB, 下载次数: 0)
下载附件
2022-8-30 11:21 上传

下载次数, 下载附件

RandomUsername   

注册就是为的这篇帖子,感谢
但是±80ms还不够宽吗(
飞龙project   

使用存档解密的脚本,发现解不出来任何字符串,这是为什么?还有在对name进行解密时会报错[Python] 纯文本查看 复制代码UnicodeDecodeError: 'utf-16-le' codec can't decode bytes in position 32-33: illegal UTF-16 surrogate
icjhao   

这个软件什么功能
rsjw
OP
  

某一个音乐游戏
skywalker0123   

不会是Phigros吧
GJH588   

这个没点基础的人很难看懂,不错的分析
xixicoco   

楼主厉害的额
hesqiang   

感谢分享
p1b234   

打个标签,正好学习。先进收藏夹。
您需要登录后才可以回帖 登录 | 立即注册

返回顶部