本文原写于2020/08/03
首先到Google Play下载Terraria的安装包, 链接: https://play.google.com/store/apps/details?id=com.and.games505.TerrariaPaid
可以通过镜像站等方式下载, 具体的就自己来吧.
其流程如下: 先使用jadx或者Bytecode-Viewer或者dex2jar+jd-gui(你喜欢哪个用哪个)找到负责验证的代码并想好怎么修改, 然后使用apktool解包, 修改代码, 再使用apktool打包, 最后用jarsigner签名.
直接安装游戏, 打开后游戏进入一个需要谷歌验证的界面, 由此可知Terraria的正版验证必与谷歌有关.
使用jadx打开apk, 既然与谷歌有关, 那么负责验证的代码所在的包名肯定以com.google开头(如果没混淆), 经过一番乱找, 发现负责验证的代码是com.google.android.vending.licensing.LicenseChecker. 当需要验证时, 这个类的void checkAccess(com.google.android.vending.licensing.LicenseCheckerCallback)方法会被调用, 这个方法里会绑定com.android.vending.licensing.ILicensingService这个服务, 要是绑定成功了就把这个回调放入队列里, 然后调用void runChecks()这个方法, 要是绑定过了就直接放入队列里然后调用runChecks(). 但是这个服务只是一个接口, 我猜测具体服务是由Google Play实现的, 那么在我的手机上是无法获得这个服务的实例的, 所以首先需要把绑定服务那里删掉, 但是就在我删完想打包测试一下时, 它居然能用, emmm… 我猜测是因为无法绑定服务, 没有执行runChecks()方法, 所以跳过了验证, 然后它无法在我的另一部有GMS的三星手机上运行也验证了这一猜想, 不过我还没有详细地读代码, 这只是一个猜想, 但是既然能玩了也没有必要再研究下去了.
有了思路以后, 就可以开始破解啦, 先使用apktool解包
java -jar apktool.jar d <apk路径>
然后修改代码
将com/google/android/vending/licensing/LicenseChecker的public checkAccess(Lcom/google/android/vending/licensing/LicenseCheckerCallback;)V方法中的if-eqz v0, :cond_0去掉或改成nop
最后重新打包并签名
java -jar apktool.jar b <app目录>
(打包好的apk在app目录中的dist目录中)
jarsigner -verbose -keystore terraria.keystore -signedjar Terraria_signed.apk Terraria.apk terraria.keystore
好啦, 装到手机上试试吧~