吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 21750|回复: 328
收起左侧

[Android 原创] 元气骑士存档解密(Unity IL2Cpp 游戏逆向记录)

    [复制链接]
mlgmxyysd 发表于 2023-10-10 20:40
声明:以元气骑士为例,仅用于学习研究。



最近玩元气骑士玩的有些上头,一闲下来就想打两把。

新出的迷迭岛游记赛季更新了神器级别武器,但能开出神器的赛季宝箱限制了每周只能购买 10 个。放着一大把之前赛季攒下来的赛季币没处花,精炼低的神器打的又不爽。

想到商店是联网更新的,那么可以抓一下商店请求包,扔进 Charles 中,没抓到任何有用的东西,应该不是 HTTP 请求,放弃。于是更换思路,直接修改存档。

image.png




说干就干,先使用游戏自带的 Google Play Games 云存档功能,将游戏存档同步到另一台有 root 权限的设备中,经过简单的目录和文件结构分析,我们得到了有用的文件列表:

[Shell] 纯文本查看 复制代码
files/backup.data # 游戏数据备份 加密方式 1
files/battles.data # 未完成的游戏 明文 JSON
files/game.data # 游戏基础数据 加密方式 1
files/item_data.data # 物品存档 加密方式 2
files/mall_reload_data.data # 商城刷新数据 加密方式 2
files/monsrise_data.data # 怪兽崛起数据 加密方式 2
files/net_battle.data # 在线联机数据 明文 JSON
files/sandbox_config.data # 电脑配置 明文 JSON
files/sandbox_maps.data # 电脑地图 明文 JSON
files/season_data.data # 赛季数据 加密方式 2
files/setting.data # 游戏设置 加密方式 2
files/statistics.data # 地下室统计 加密方式 2
files/task.data # 任务数据 加密方式 2
shared_prefs/com.ChillyRoom.DungeonShooter.v2.playerprefs.xml # 游戏数据 明文 XML


使用文本编辑器打开,可以大致得出,一共有两种加密方式,还有一些是未加密的明文。

image-5.png




打开 split_base_asset.apk 和 split_config.arm64_v8a.apk,发现了 assets/bin/Data 和 lib/arm64-v8a/libil2cpp.so,可以判定这是一个使用了 Unity 引擎,并使用 IL2Cpp 打包方式写的游戏。我们直接取出 split_base_assets/assets/bin/Data/Managed/Metadata/global-metadata.dat 和 split_config.arm64_v8a/lib/arm64-v8a/libil2cpp.so 两个文件,喂给 Il2CppDumper 辅助分析,程序报错 ERROR: This file may be protected.

image-2.png

根据文档提示,加保护的软件要用 GameGuardian 来 dump 内存中的 libil2cpp.so,但我没搞懂怎么 dump。(浇浇)

以普遍理性而论,旧版可能没有加保护,并且旧版的加密方法和新版一样,不然用户从旧版更新到新版,存档直接就报废了。

image-3.png

依照这个前提,我们在 APKMirror 里下载了一个 1.8.4 远古版,提取文件再次喂给 IL2CppDumper,成功跑出分析文件。

image-4.png

IDA 打开 libil2cpp.so,等分析完之后点击 File – Script File...,选择 IL2CppDumper 里的 ida_py3.py ,选择分析出的 stringliteral.json。

image-6.png

等脚本跑完再次执行脚本,这次选择 ida_with_struct_py3.py,选择分析出的 script.json 和 il2cpp.h,脚本运行时间比较长,让 IDA 先在后台跑。

image-7.png

用文本编辑器打开 stringliteral.json,搜索文件名 game.data,复制 address 中的地址。

image-8.png

等 IDA 跑完脚本,找到 IDA View 窗口,按 G 键,粘贴刚才复制的地址,点击 OK 跳转。

image-9.png

右键这个字符串的名字,点击 List cross references to… 来列出字符串的交叉引用。

image-10.png

我们需要知道的是,IL2Cpp 后的方法名是 Package.Class$$Method,在伪代码中,.$ 都会显示成 _,例如 System.String.Contact() -> System.String$$Contact() -> System_String__Contact(),了解这个规律会对我们之后的代码分析有帮助。

交叉引用中有一个 RGSaveManager.get_Path,直觉告诉我们这个就是读取存档的方法,跳转过去按 F5 查看伪代码。

image-11.png

右键方法名,选择 Jump to xref…

image-12.png
image-13.png

我们找到了 RSSaveManager.LoadGameData

image-14.png

分析代码,程序获取到路径后首先判断是否存在,如果存在就读取,然后跳转到 0x57C188,否则跳转到 0x57C170。按 G 跳转到 0x57C188

image-15.png

如果调用方法签名有问题,记得右键重命名一下方法签名。分析代码得出加密方式为 Xor,数据格式为 JSON。

跳转到 Abo.CryptUtil.DecryptXor 方法,再次跳转找到真实方法。

image-17.png


for 内的是加解密方法实现,使用一个递增变量,对每个字符进行两次 Xor 运算。第一次 v15 是遍历一个 15 位(i % 0xF)的固定密码表,第二次 v7 是遍历传入的密钥。



往前翻代码,并没有找出传入的密钥是什么,只能看到一个没解析出来的字符串 (v8 + 36),但这不妨碍我们继续反编译。

我们已经知道了数据格式是 JSON,那么文件的前两位解密后应该是 {"(左花括号和双引号),转为十六进制 0x7B 0x22

重写一下密码表的算法,运行程序得到密码表。

image-18.png

用 010 Editor 打开 game.data,得出前两位为 0x08 0x4E

image-19.png



打开 Windows 计算器 – 程序员,计算 0x7B XOR 0x08 XOR 0x00,得出密钥第一位为 0x73(ASCII 字符为 s),计算 0x22 XOR 0x4E XOR 0x01,得出密钥第二位为 0x6D(ASCII 字符为 m)。

image-20.png image-21.png

在 stringliteral.json 中搜索以 sm 开头的字符串,一共有两个结果。

image-22.png

其中 small 下面还有两个字符串为 mediumlarge,明显是一组,不大可能是密钥。在刚才的密码表算法基础上加入密钥计算,尝试使用另一个搜索结果 smg 作为密钥解密。

image-23.png

解密成功,图中为皮肤数据。

image-25.png



这一种加密方式我们就解出来了,那么还剩下另一种明显不一样的加密方式,文件做了 Base64 处理。

image-26.png

在 Functions Window 中可以看到,除了 Xor,还有 DES 加密,猜测应该就是他了,先看下他是怎么实现的。

image-27.png

同样,跳转两次找到真实方法。

image-28.png
image-29.png

已知 DES 加解密需要 8 位的密钥和 8 位的初始化矢量。传入参数 passwordCopyTo 到了 v11 变量,然后 GetBytesv21 作为解密的 Key;v16 变量 GetBytesv23 作为解密的 IV,往上翻发现 v16v6 的 CopyTo,而 v6 为一次 Xor 解密的结果,其中 StringLiteral_8985StringLiteral_8986 分别作为 Xor 的密文和密钥。

image-30.png

StringLiteral_8985 包含一个不可见字符,IDA 看不到。

image-31.png

在 stringliteral.json 中找到这两个,复制过来,这个 DES 加解密方法就重写好了,由于 IV 不够 8 位,需要用 0 补足。

image-32.png

方法写好了,但我们还不知道密钥,按照一开始的方法,在 stringliteral.json 中搜索文件名。

image-33.png

复制地址跳转分析。

image-34.png
image-35.png

进入 Abo.JsonUtil.LoadJsonWithCrypt.ItemData 这个方法,使用了 DES 解密,刚才我们已经重写好了。

image-36.png

根据方法签名,第三个参数 StringLiteral_9924 是就密钥,原来就在文件名下面。

image-37.png

运行代码,解密成功。

image-38.png



按照这个方法,把其他几个文件也都分析了一遍,除了 statistic.data 的密钥是独立的,其他相同加密方式的文件都用了同一个密钥。

image-39.png

修改一下程序,自动根据文件名判断加解密方式和密钥。

image-40.png
image-41.png



分析存档内容,发现神器精炼等级保存在 item_data.data 的 mythicWeapons 对象中。

image-42.png

level 字段全改成 3,重新加密,覆盖数据,运行游戏,精炼等级已经变成我们想要的结果。

image-43.png



其他存档文件里面还有一些很有意思的字段,这里不再赘述,有兴趣的可以自行解密研究。

免费评分

参与人数 123吾爱币 +121 热心值 +111 收起 理由
AkaiSuisei + 1 + 1 用心讨论,共获提升!
soest + 1 + 1 牛波一
piboos + 1 热心回复!
0ling + 1 用心讨论,共获提升!
fjj945 + 1 用心讨论,共获提升!
TLPG + 1 用心讨论,共获提升!谢谢你的帖子
milu2004 + 1 谢谢@Thanks!
evalPrivateJS + 1 + 1 谢谢@Thanks!
juliusnan + 1 + 1 思路清晰!
Lanly + 1 + 1 我很赞同!
peiqihaoshuai + 1 我很赞同!
SilentNocturne + 1 + 1 我的天。。。这绝对是大神啊,每一步的逻辑都写清楚了。。。
LIN24 + 1 + 1 我很赞同!
lelele1 + 1 我很赞同!
abcdef969 + 1 + 1 谢谢@Thanks!
JerryGod + 1 + 1 谢谢@Thanks!
youren4987 + 1 + 1 我很赞同
ruocai + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
Victoryship + 1 + 1 我很赞同!
GUANXUN + 1 我很赞同!
lkyhr + 1 我很赞同!
liliqingchuan + 1 + 1 我很赞同!
Tisfy + 1 + 1 谢谢@Thanks!
awesomewyz + 1 + 1 我很赞同!
Jshow + 1 + 1 用心讨论,共获提升!
yuzaizi521 + 1 + 1 我很赞同!
junjia215 + 1 + 1 谢谢@Thanks!
Tushen + 1 + 1 我很赞同!
JBYJLW + 1 我很赞同!
cflollolcf + 1 谢谢@Thanks!
ohssr + 1 + 1 谢谢@Thanks!
nyazhou + 1 + 1 谢谢@Thanks!
yunshaoa + 1 谢谢@Thanks!
chuan9 + 1 + 1 谢谢@Thanks!
shenzhouruoyi + 1 + 1 我很赞同!
ykss2023 + 1 我很赞同!
twl859588 + 1 谢谢@Thanks!
cenmuyan + 1 我很赞同!
zzz2580 + 1 + 1 谢谢@Thanks!
wangduanqueqiao + 1 + 1 用心讨论,共获提升!
cncprz + 1 + 1 鼓励转贴优秀软件安全工具和文档!
zhoumeto + 1 + 1 用心讨论,共获提升!
ctmaomao + 1 谢谢@Thanks!
wolaipao + 1 + 1 用心讨论,共获提升!
pelephone + 1 + 1 我很赞同!
unknownAI + 1 + 1 我很赞同!
jiangrui98 + 1 + 1 我很赞同!
q6790296 + 1 + 1 谢谢@Thanks!
fjtu04 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
dizzy0001 + 1 + 1 热心回复!
Vik09 + 1 + 1 谢谢@Thanks!
soyiC + 1 + 1 用心讨论,共获提升!
Baichun + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
hzlei + 1 + 1 用心讨论,共获提升!
qiaoyong + 1 + 1 热心回复!
jsyczxyh + 1 用心讨论,共获提升!
LvMou + 1 + 1 用心讨论,共获提升!
Zhenzhuo + 1 + 1 谢谢@Thanks!
linsen6733 + 1 + 1 热心回复!
Leo625 + 1 + 1 我很赞同!
龙骑士尹志平 + 1 我很赞同!
LonelyCrow + 1 + 1 用心讨论,共获提升!
林暮云 + 1 谢谢@Thanks!
freehds588 + 1 + 1 用心讨论,共获提升!
lingyan + 1 我很赞同!
heimaojingzhang + 1 + 1 我很赞同!
erzi + 1 + 1 我很赞同!
1436581545 + 1 + 1 谢谢@Thanks!
Fanqim + 1 + 1 高手受教了
debug_cat + 2 + 1 用心讨论,共获提升!
杨顶天 + 1 + 1 厉害厉害
wjks86 + 1 谢谢@Thanks!
_小白 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
fengbolee + 2 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
DamonLin + 1 + 1 用心讨论,共获提升!
三滑稽甲苯 + 2 + 1 用心讨论,共获提升!
zqds + 1 用心讨论,共获提升!
paomianhaochi + 1 + 1 我很赞同!
一个电脑小白 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
Laign + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
k854053320 + 1 + 1 --------看不懂,但是我被震撼到了
ainstan + 1 + 1 热心回复!
aatrox、 + 1 + 1 用心讨论,共获提升!
vaycore + 1 + 1 用心讨论,共获提升!
hamxbb + 1 + 1 我很赞同!
wurenxi + 1 我很赞同!
M1SAKAZ + 1 + 1 用心讨论,共获提升!
Coldandcolder + 1 + 1 我很赞同!
tenleaf + 1 + 1 谢谢@Thanks!
gunxsword + 1 + 1 谢谢@Thanks!
HundSimon + 1 + 1 用心讨论,共获提升!
杨辣子 + 1 + 1 热心回复!
peiki + 1 + 1 我很赞同!
crizquan + 1 + 1 谢谢@Thanks!
2025888543 + 1 + 1 谢谢@Thanks!
xxxesa6xxx + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
courierma + 1 + 1 我很赞同!
DaKxhq54zDH + 1 好评加鹅
Bob5230 + 1 + 1 热心回复!
mq5123 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

diary 发表于 2023-10-29 23:05
本帖最后由 diary 于 2023-10-29 23:09 编辑

贴一个可行的解码的脚本代码,拿到存档可以直接破解
[PHP] 纯文本查看 复制代码
<?php
//存档解密
function xor_crypt($ciphertext, $password)
{
    for ($i = 0; $i < strlen($ciphertext); ++$i) {
        $ciphertext[$i] = chr(ord($ciphertext[$i]) ^ ord($password[$i % strlen($password)]) ^ $i % 15 * ($i % 5) % 92);
    }
    return $ciphertext;
}

function des_crypt($ciphortext, $password, $encrypt = false)
{
    $iv = str_pad(substr(xor_crypt(hex2bin("112035352023"), "PASSWORD"), 0, 8), 8, hex2bin("00"));
    if ($encrypt) {
        return base64_encode(openssl_encrypt($ciphortext, "des-ede3-cbc", $password, OPENSSL_RAW_DATA, $iv));
    } else {
        return openssl_decrypt(base64_decode($ciphortext), "des-ede3-cbc", $password, OPENSSL_RAW_DATA, $iv);
    }
}
$keys = [];
$keys["game"] = "smg";
$keys["data"] = "iambo";
$keys["statistic"] = "crstl";
// 获取外部终端输入的文件路径
if (!isset($argv[1])) {
    die("请输入文件路径,例如:php sk.php file/game.data\n");
}
$file_path = $argv[1];

// 根据文件名来判断使用哪种解密方法
$name = pathinfo($file_path, PATHINFO_FILENAME); // 获取不带扩展名的文件名
$content = file_get_contents($file_path);
$decrypted_data = '';

switch ($name) {
    case "game":
        echo "Using XOR mode with game key.\n";
        $decrypted_data = xor_crypt($content, $keys["game"]);
        break;
    case "task_*_":
    case "item_data_*_":
    case "season_data_*_":
    case "moonrise_data_*_":
    case "mall_reload_data_*_":
        echo "Using DES mode with data key.\n";
        $decrypted_data = des_crypt($content, $keys["data"]);
        break;
    case "statistic_*_":
    case "statistic":
        echo "Using DES mode with statistic key.\n";
        $decrypted_data = des_crypt($content, $keys["statistic"]);
        break;
    default:
        echo "\033[32mFile is plaintext, nothing to do.\033[0m\n";
        exit;
}

$output_directory = './data_new/';
if (!file_exists($output_directory)) {
    mkdir($output_directory, 0777, true);
}
// Save the decrypted content to .txt and .json files
file_put_contents($output_directory . $name . ".txt", $decrypted_data);
// file_put_contents($output_directory . $name . "_diff.json", $decrypted_data);
// file_put_contents($output_directory . $name . ".json", $decrypted_data);

echo "Decryption completed and saved as .txt!\n";
?>

免费评分

参与人数 1吾爱币 +2 热心值 +1 收起 理由
mlgmxyysd + 2 + 1 用心讨论,共获提升!

查看全部评分

 楼主| mlgmxyysd 发表于 2023-12-13 03:04
awesomewyz 发表于 2023-12-5 15:54
厉害了,忽然明白了为啥版本加密之后一样被破解掉了,原来还能从老版本摸索出门道

哈哈,不过我在新帖子中,把新版本的也一样破掉了
https://www.52pojie.cn/forum.php?mod=viewthread&tid=1844587
zxy1992123 发表于 2023-10-11 10:53
上次玩了破解版的,也没啥好玩的。其实关卡都一样的,纯打材料
diweiyi123 发表于 2023-10-10 20:47
学到了学到了
菜苗小豆 发表于 2023-10-10 21:12
非常奈斯
aa361328 发表于 2023-10-10 23:21
标记一下!!!!
k452b 发表于 2023-10-10 23:42
好厉害,没看懂
zhouxinyi 发表于 2023-10-10 23:55
这个可以标记备用,分析得不错
amami520 发表于 2023-10-11 07:08
看不明白,看个热闹,还需要努力才行啊
ErenLuo 发表于 2023-10-11 08:02
大佬求抱大腿
feizaier 发表于 2023-10-11 08:29
逆向真是条漫长的路啊
chyduck 发表于 2023-10-11 08:34
太厉害了
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-4 00:20

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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