前人栽树,后人乘凉,第一次安卓逆向在翻看了无数的教程之后,选择一款不算是国内大厂制作发行并且版本较老的apk《饥饿鲨》,版权属于育碧手游(UBSOFT),在签名、验证等环节可能就省去了不少步骤,下面就是比葫芦画瓢+思考环节 :| 。

一次安卓逆向之「饥饿鲨」内购破解

准备

发现

打开apk后发现,首先是发现加载页有个电信的爱游戏平台,可以得到一些对应关键字的信息,如:paySuccesspayCancelpayFailed等,对于特定的游戏内购平台,关键字不大相同又如出一辙;

一次安卓逆向之「饥饿鲨」内购破解

主页面点击购买金币和钻石,可能是由于游戏版本较老还是平台验证什么原因,在真机和模拟器上一直无法购买成功,等下我们就在这里做文章,跳过这个支付验证 :mrgreen: ;

一次安卓逆向之「饥饿鲨」内购破解

反编译

将游戏拖入IDE打开,生成游戏应用目录,实际上apk类似一个压缩文件,通过winnar同样可以看到解压后的文件:

  • AndroidMainifest.xml:以xml结尾的都知道了,类似站点的sitemap,这里也就是安卓的结构目录 ;
  • build:一般存放classes.dex可执行文件以及resources.arsc语音包文件;
  • assets:同样顾名思义,有价值的东西,安卓的“财富”文件夹,放一些图片等文件;
  • lib:安卓的.so文件动态库文件夹;
  • res :资源库目录 一般存放xml布局文件和图标;
  • original:存放META-INF签名文件夹的目录;
  • smail:Dalvil(Google为安卓设计的虚拟机)的内部执行代码;

不同的应用目录位置是大同小异的。在IDE这类专业工具中,有助于更好的分析。

一次安卓逆向之「饥饿鲨」内购破解

像gameloft等这种国外手游大厂都很倾向于Unity3D引擎去制作游戏(小时候玩的有点多)。由于不是手游发烧友,研究一下育碧手游,如何识别?我们点开lib文件夹,可以发现下面有个armeabi-v7a文件夹,看到arm便知道这和多半的内核有关系,其中的.so文件支持arm架构的真机运行,如果修改过后,拿模拟器闪退也就是理所当然的事情了,再打开,发现存在libunity.so文件,到这里基本可以确定这就是一个Unity3D引擎制作的手游。

一次安卓逆向之「饥饿鲨」内购破解

要修改Unity3d游戏,首先就要对其游戏代码存放位置有一个基本的了解。Unity3d生成游戏的游戏主逻辑一般放在三个地方:libil2cpp.so、Assembly-CSharp.dll、lua脚本。

 ————一位伟人说过

分析

既然有可能(很大可能)存在于.dll文件中,那我们找到IDE目录下,找到apk解压目录,将Assembly-CSharp.dllAssembly-CSharp-firstpass.dll拖入dnSpy中,并尝试搜索关键字paySuccess

一次安卓逆向之「饥饿鲨」内购破解

一次安卓逆向之「饥饿鲨」内购破解

编辑器语言为C#,发现上面提到一般爱游戏关键词都失效,既然都如出一辙,那我们换个思路尝试搜索success,看能否大有大有收获:

一次安卓逆向之「饥饿鲨」内购破解

可以看到这是一个私有类,再往下搜索,眼前一亮,我们找到了公共类OnPurchaseSuccessfull(拼写是啥玩意 :P ),由于暂时只考虑破除内购,其他大类咱先不看:

一次安卓逆向之「饥饿鲨」内购破解

同理,以PurchaseFail为关键词,看看他们各自都是如何返回执行的,看到有一个if判断语句,如果支付失败,支付取消,返回失败:

一次安卓逆向之「饥饿鲨」内购破解

这就显而易见了,如果支付失败让他也直接返回Success,即把OnPurchaseSuccessfull的执行代码拷贝到OnPurchaseFailed方法下面,我们在对应代码右键→编辑方法,替换后编译:

Debug.Log("OnPurchaseSuccessfull in GUIManager");
		GUIBuyingProcess[] componentsInChildren = base.GetComponentsInChildren();
		for (int i = 0; i < componentsInChildren.Length; i++)
		{
			if (componentsInChildren[i].Type == GUIBuyingProcess.BuyingType.Currency || componentsInChildren[i].Type == GUIBuyingProcess.BuyingType.CoinMultiplier)
			{
				componentsInChildren[i].State = GUIBuyingProcess.BuyState.ePurchaseConfirmed;
			}
			else
			{
				Debug.Log("Unrecognised buying type: " + componentsInChildren[i].Type);
			}
		}
		FGOLAnalytics.ReportBankPurchaseResult("Success"); 

一次安卓逆向之「饥饿鲨」内购破解
Assembly-CSharp.dllAssembly-CSharp-firstpass.dll都进行如此操作,然后保存到对应原ApkIDE\Work\com.fgol\assets\bin\Data\Managed目录当中,保存模块:

一次安卓逆向之「饥饿鲨」内购破解

返回IDE,刷新目录,编译签名apk,耐心等待:

一次安卓逆向之「饥饿鲨」内购破解

在模拟器打开一下,看看效果(记录器抽风 :evil: ):

一次安卓逆向之「饥饿鲨」内购破解

其他

对于安卓逆向,AndroidKiller、ApkIDE、GDA这几个工具都可以,看个人习惯以及电脑的环境配置来操作,AndroidKiller基于apktool反编译,且需要配置java JDK,版本号不兼容经常编译失败,推荐后两者。

下载: Download

参考教程(部分):


電光石火 正面突破。 日進月歩 百花繚乱。 順風満帆 天真爛漫。