Unity手游分析
1 前期准备
1.1 打包方式
解压apk 看\lib\*.so,判别是mono打包还是il2cpp打包。前者有逆向出C#源码的可能性(仅仅是可能性)。
1.2 logcat
可能会有Unity版本信息。
- 如果通过Android Studio查看,需要启用USB调试。
- apk没开启调试开关?Xposed框架+BDOpener可破。
1.3 有保护
- apk有壳:脱壳器网上一大堆,虽然不一定管用。
- 禁Root:使用Magisk root并隐藏root;如果已经用了SuperSU,需要先清除干净SuperSU,可能会遇到点麻烦。
- 禁Xposed:用VirtualXposed代替。如果感兴趣也可以琢磨下太极Magisk、Magisk上的Riru。
- 禁USB调试:不知道,待补充。
- 禁ida调试:不知道,待补充。
2 逆向
2.1 mono打包
需要adb和USB调试能用:
2.2 il2cpp打包
用perfare佬的il2cppdumper,C#类名、方法名是可以还原出来的(源码看不到,已经被编译成C++了)。IDA(可能需要64位)导入dumper生成的script.py还原符号信息,可以凑合看一下C++代码。
如果这个游戏有mono打包的老版本会好分析些。
2.3 反编译
解密完成的Assembly-CSharp.dll,或者dumper生成的dummy版Assembly-CSharp.dll,可以使用以下软件查看C#代码:
.NET Reflector
dnSpy
ILSpy
2.4 hook与修改
建议先看perfare佬的文章:
- 手游的注入与修改
- 使用VirtualXposed修改手游(示例适用于mono版)
- 使用Riru修改手游(示例适用于il2cpp版)
我参考比较多的是这篇文章:
需要注意的是,VirtualXposed默认注释掉了VirtualApp/lib/src/main/jni/Foundation/IOUniformer.cpp的so hook开关,在该文件的末尾。
但是我迟迟未能解决C++和C#的数据格式转换,换了Frida的native hook重新实现 一套强劲的 Il2cpp Hook 框架这篇文章的函数内存地址动态获取(而不是基于偏移值,毕竟偏移值每次apk更新都会变),等整理好了发出来。
强烈推荐FridaDev ,直接在模板基础上写js部分。
如果不用FridaDev,想自己写可以参考这篇:Frida入门学习笔记-hook native中的函数(1)。
3 通信
3.1 运气好的话
常规使用Burp Fiddler Charles,装对应的SSL证书就能抓包了。
3.2 不走系统代理
怀疑抓包不全可以使用wireshark或tcpdump对比抓包结果。
可能是不走系统代理,有两个解决方案:
强制代理(推荐优先尝试)
按照这篇文章的drony使用教程: 部分APP无法代理抓包的原因及解决方法
透明代理
基本上只有linux/mac上的mitmproxy能用;
windows上的话,WSL因为iptables缺陷用不了,我的解决方案是win10+ virtualbox + ubuntu。详见另一篇:从零开始的mitmproxy
3.3 证书绑定
3.3.1 安卓7.0以上
安卓7.0以上默认不信任用户证书,使用这个magisk模块将用户证书(来自抓包软件)copy为系统证书:
- Magisk + MagiskTrustUserCerts
3.3.2 java层
Hook证书绑定:
Xposed + JustTrustMe,我有遇到把okhttp3的名字改成okhttp的,这种时候需要自行修改、编译JustTrustMe源码。
Xposed+ DroidSSLUnpinning
Xposed + TrustMeAlready
3.3.3 native层
使用Virtualapp/VirtualXposed/Frida hook证书绑定相关的函数,以信任服务器方(实际上是中间人)。
3.3.4 双向证书绑定
需要把客户端里的密钥导入到抓包软件,可能不是一个单独的文件,需要hook去找出来(?)