吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 12380|回复: 33
收起左侧

[原创] Galgame汉化中的逆向(五):Switch平台下的Unity后端il2cpp分析

  [复制链接]
小木曾雪菜 发表于 2020-8-1 23:46
本帖最后由 小木曾雪菜 于 2020-8-2 00:32 编辑

Galgame汉化中的逆向(五):Switch平台下的Unity后端il2cpp分析

0x0 前言

前面我们主要介绍了一下pc平台下galgame的一些分析方法, 比如说如何去解密文本,如何调用系统字库,以及涉及到动态生成的shellcode相关的内容,寻找密钥等内容。 可是,主机平台往往无法动态调试,分析算法通常只能静态,ida loader也远没有pc平台的好用,相关的资料也比较少。 并且主机平台往往都会用各种自定义字库,这个往往会增加不小的难度。  

因此主机平台测试和分析起来就会异常的麻烦,非常需要耐心。 本节将以il2cpp为例,谈谈switch平台下如何分析。这个游戏日版官方屏蔽了其他语言,我们将分析怎么去找相关代码,并修改switch中的可执行文件来调出中文。

同样,本教程和隔壁发的一样。
上期:Galgame汉化中的逆向(三):自定义字库分析

rootfilm_done2.jpg

0x1 Switch分析的准备工作

(1) 文件格式

Meta (.npdm)
GameCard Image (.xci)
Nintendo Content Archive (.nca)
Content Metadata (.cnmt)
Nintendo Software Object (.nso)
Nintendo Relocatable Software Object (.nro)
Kernel Initial Process List (.ini)
Kernel Initial Process (.kip)
Nintendo Application Control Property (.nacp)
ES Ticket (v2 only) (.tik)
PKI Certificate (.cert)  

详见nstool,对于分析游戏我们常用的就是exefs下的main文件了,通常为
nso格式。可以用nx2elf转为elf进行编辑(ARN64汇编),然后elf2nso再转回nso

(2) keys

解密游戏内容或者系统固件等需要各种key,常用key介绍如下:

BIS_key.txt // Built-In Storage, unique for each console to decrypt nand, get from TegraRcmGUI biskeydump
prod.keys //decrypt system files and encrypted > > game files, get from Lockpick_RCM
title.keys //These are only used for games that are not dumped from cartridges, get from Lockpick_RCM  

具体用法可以详见YUZURyujinx

(3) 游戏档案文件系统(pfs)

PartitionFS (pfs), HashedPartitionFS(hfs)   // nsp or xci
| Program nca (the biggest nca in nsp) // nca in xci at /secure path
|RomFS // this is file system of the rom in nca or xci, can be in romfs.bin or directories
|ExeFs // the exeuctable code, the version must be consonance to patch
|Control  nca
|LegalInformation nca
|Meta nca
|.cnmt // metadata file such as the information of each nca  

通常提取游戏文件需要从 nsp -> nca -> exefs/romfsxci -> exefs/romfs,常用的命令行如下:

// NAX0 Reader -> NCA Reader(Program part, the biggest nca) -> RomFS Reader -> Individual Files
hactoolnet -k prod.keys -t pfs0 --outdir %outpath%  %nsppath% // nsp -> nca
hactoolnet -k prod.keys -t nca  --romfsdir %romfspath% %ncapath% // nca -> romfs dir
//if missing nca title key, convert to xci and extract xci, the 
// hactool -k prod.keys -t nca --basefake --romfsdir %outpath% %ncapath%
hactoolnet -k prod.keys -t xci --romfsdir %outpath% %xcipath% //xci -> romfs dir

hactoolnet -k prod.keys -t nca  --exefsdir %exefspath% %ncapath% //extract exe code

进行汉化或mod将修改的档案文件放入/atmosphere/content/[title id]/romfs,修改的可执行文件放入/atmosphere/content/[title id]/exefs注意可执行文件版本必须和游戏版本相同,否则报错。

(4) 相关工具

  • nx2elf, elf2nso
  • hactoolnet
  • SwitchIDAProLoader, reswitched loaders
  • AssetStudio, UABE
  • Il2CdumpppDumper
  • dnSpy
  • ida pro 7.0

0x2 观察

解包后此游戏是unity引擎的特征很明显,用AssetStudio或者UABE来提取资源。一般unity引擎的文本大多在TextAsset或者MonoBehaviour(存储unity的序列化对象)里。  

提取后发现此游戏文本与脚本在TextAsset里面,且游戏脚本为lua,根据id来定位数据库的文本,如_talk(16),不同语言调用不同的数据库来实现多国语言。(lua脚本__talk后面的日文文本是注释,只是为了表明是那句话,并不是直接加载)


rootfilm_lua.png

我们还发现游戏虽然只有日文,但是资源里却包含中文和韩文的文本,猜测是通过某个变量来确定语言。

rootfilm_jp.png

rootfilm_ko.png

rootfilm_chs.png

经过搜查,发现各lua脚本中没有明显的和语言相关的内容,因此可以确定是在unity里面设置了,我们需要去分析unity代码了。看到资源里没有c# 的dll,但是有\Managed\Metadata\global-metadata.dat,可以肯定用了il2cpp后端,也就是说所有的逻辑代码都在main文件里了。分析il2cpp的原生代码,这比mono后端的直接逆向成c#代码要难,但是由于可以得到函数名称和成员变量偏移,比分析纯native code 要容易多了。  

当然还有另一种方法,直接把日文文本文件替换成中文文本文件,但是由于此游戏有1w+个小文件,并且不同语言文件都是哈希值后缀,不容易区分,这种方法非常麻烦,因此不考虑。


rootfilm_textasset.png

0x3 il2cpp与ida结合分析

和一般的unity il2cpp分析方法类似,用Il2CdumpppDumper根据mainglobal-metadata.dat来得到Assembly-CSharp.dll,虽然没有逻辑代码但是可以在里面看到类的声明。再根据RVAOffset可以在ida里面定位了。  (可以用ida跑ida.py脚本,然后输入生成的script.json自动添加函数名)

dnspy打开Assembly-CSharp.dll,搜索language可以看到相关的结构,在GameCore类中有gameLanguage的枚举结构。


rootfilm_gamelanguage.png

顺藤摸瓜,找到了gameLanguage get函数,看到总是返回日语,这句是无法得到其他语言的罪魁祸首。修改也很简单,我们将返回值设定为1即为中文(由上面enum的值得知jp=0, ch=1, ko=2)。由于arm64是4字节定长指令,返回值是X0,所以可以把 LDR W0, [X8, #0X14] 改为 LDR W0, 1


rootfilm_getlanguage.png

这么改完理论上是可以挑出来汉语了,但是实际测试发现只有图标是汉语,文本还是日语。我们看到这句LDR W0, [X8, #0X14],发现游戏不一定全是通过get language来获得语言版本的,可能通过某个偏移为0x14的变量。我们继续在c#代码里看,然后发现确实有个gameLanguage的成员函数,offset是0x14


rootfilm_gameLanguage_0x14.png

然后继续在ida里面找发现了 set_language函数,结合f5伪代码可以看到修改位置如红框,需要把0x14偏移的变量赋值为1。这里有个麻烦事,STR WZR, [X8, #0x14],其中WZR为零寄存器,相当于赋值为0。直接改mov [x8, #0x14], 1是错误的,arm64没这种用法,但是程序有很紧凑,没地code cave。好在上面有 mov w20, #1w20也没再变过,直接就改成了STR W20, [X8, #0x14]


rootfilm_ida_setlanguage.png

0x4 修改main.elf

上面分析完了现在该落实到文件上了,用ida keypatch插件可以看到要改的地方。


rootfilms_patchedbytes.png

然而这时候却发现apply patch失败,貌似ida对switch的可执行文件兼容不好,初步分析可能是地址不一致导致的。


rootfilm_ida_diffaddr.png

那只能手动去改了,搜索若干个字节作为标志字节串,直到结果唯一。然后再手动修改需要patch的字节。注意不能直接修改main因为nso是压缩格式,未必能找到相关字节,需要转换成main.elf再patch。之后再转回nso格式的main,送入机器测试即可。看着没什么问题,中文出来了,搞定!


rootfilm_done1.jpg

0x5 总结

本节教程以一个简单的例子谈谈如何上手非pc游戏的分析,并且介绍了一下Switch平台的特点以及如何修改可执行文件。相对于pc平台galgame的汉化,主机平台门槛更高,难度更大,也更加冷门。psp时代之后相关的教程更是少之又少,于是想着来聊聊主机平台的游戏,和大家交流一下。  

另外由于这个游戏是这两天发售的,刚搞完印象很深刻,例子不难又很典型,特别适合作为主机汉化的开篇教程,于是就先写这篇了。 Galgame汉化中的逆向(四)关于动态生成shellcode与寻找密钥 将下次再更新了。

免费评分

参与人数 14威望 +1 吾爱币 +31 热心值 +13 收起 理由
xiong_online + 1 + 1 用心讨论,共获提升!
Razuri + 1 + 1 谢谢@Thanks!
FFF全部成为F + 1 可惜没有C语言的基础难受
Hmily + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
lvyy + 1 + 1 我很赞同!
Mr_Guan + 1 + 1 我很赞同!
uebian + 1 谢谢@Thanks!
笙若 + 1 + 1 谢谢@Thanks!
bolipapadu + 1 + 1 谢谢@Thanks!
gulu2840 + 1 太强了吧
伟大的泽尔 + 1 + 1 用心讨论,共获提升!
风绕柳絮轻敲雪 + 2 我很赞同!
kof888 + 1 + 1 我很赞同!
skyward + 1 + 1 我很赞同!

查看全部评分

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

netspirit 发表于 2020-8-2 04:20
本帖最后由 netspirit 于 2020-8-2 04:21 编辑

楼主的id让我想起了这个图片....................

18EAE63F716579F1947AF00C87E266CE.jpg
 楼主| 小木曾雪菜 发表于 2020-8-3 16:35
gunxsword 发表于 2020-8-3 15:24
像这种自带中文只是不让你选择的,多吗?这个方法通用性如何?

首先不是ns游戏都用unity开发,而是ns有unity开发的游戏。这种方法不是通用的,不同游戏的逻辑也各不相同,这个例子比较简单,特别适合作为上手教程来写。
那棵大树疯了 发表于 2020-8-2 07:49
youxiwater 发表于 2020-8-2 09:40
学习学习了。
芽衣 发表于 2020-8-2 09:50
冬马小三这教程不错
Gaho2002 发表于 2020-8-2 09:53
417788939 发表于 2020-8-2 09:50
冬马小三这教程不错

你是在搞颜色
只要再慢一点 发表于 2020-8-2 10:17
秋各位绅士推荐一下ios玩gal的模拟器
muririn 发表于 2020-8-2 10:38
支持一下
许仙呀 发表于 2020-8-2 12:24
学习一下
幼星羽 发表于 2020-8-2 13:22
谢谢大佬的分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-12-24 04:10

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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