spguangz 发表于 2015-9-19 12:34

U3d游戏『塔々西游』内购破解过程

前言:
《塔々西游》是网易独代的一款策略加轻养成的Q萌3D塔防手机游戏。
又q又萌又3D的,所以下载来玩一下。
玩了几关,过不了,所以就想破解一下。
却发现游戏加固了。(本来放弃了的)

因为不会脱壳,只好尝试别的方法。

static/image/hrline/4.gif


游戏下载地址:爱游戏
用到的工具:Android killer 1.3,.net reflector 8.4,上上签
达成的目标:破解内购

static/image/hrline/4.gif


0x1 试玩游戏
试玩时发现,手机没有sim卡或者飞行模式下,游戏买道具时按确定没反应。
于是连接手机,打开akiller看log。
主要的log如下(飞行模式):

标签:UniSDK Base
消息:getCCTypeByImsi()=CCTYPE_UNKNOW

标签:UniSDK SdkU3d
消息:{"orderErrReason":"pay failed","productCount":1,"orderDesc":"一大箱钻石","orderChannel":"play_telecom","pid":"14","orderCurrency":"","productName":"一大箱钻石","orderEtc":"","orderStatus":3,"productCurrentPrice":30,"sdkOrderId":"201509190810452074864532",
"signature":"","orderId":"201509190810452074864532"}

☆飞行模式下,imsi为空,游戏判定为CCTYPE_UNKNOW,所以直接支付失败了,连通知都没有。


换上sim卡,购买道具,按确定,这下弹出支付提示框了,再按×取消支付。

这时的log(取消支付):

标签:UniSDK Base
消息:getCCTypeByImsi()=CCTYPE_CMCC


标签:UniSDK SdkU3d
消息:{"orderErrReason":"pay cancel","productCount":1,"orderDesc":"一大箱钻石","orderChannel":"play_telecom","pid":"14","orderCurrency":"","productName":"一大箱钻石","orderEtc":"","orderStatus":3,"productCurrentPrice":30,"sdkOrderId":"201509190812428952300806",
"signature":"","orderId":"201509190812428952300806"}



由标签UniSDK SdkU3d猜想游戏内购时会调用untidy3D层的代码,于是接下来反编译untidy3D的dll文件看一下。

static/image/hrline/4.gif


0x2 修改代码
用.net reflector加载\assets\bin\Data\Managed下的Assembly-CSharp.dll,
还好游戏加密的是dex,没有加密dll。
由0x1的支付失败和支付取消信息的共同点,"orderStatus":3,
搜索字符串orderStatus。

双击OnOrderCheck看代码:

private void OnOrderCheck(int code, JsonData jsonOrder)
{
    NtOrderInfo info = NtOrderInfo.FromJsonData(jsonOrder);
    this.log(string.Format("CallbackMessage - OnOrderCheck: code={0} order={1} status={2}", code, info.orderId, info.orderStatus));
    if ((info.orderStatus == OrderStatus.OS_SDK_CHECK_OK) || (info.orderStatus == OrderStatus.OS_SDK_CHECKING))
    {
      this.log("order.orderStatus == OrderStatus.OS_SDK_CHECK_OK");
      if (CGlobleConfig.IsLoginNetEase)
      {
            ISingleton<CNetWorkDataManager>.Instance().CheckOrderId(info);
      }
      else
      {
            Messenger.Broadcast<NtOrderInfo>(ESystemEventType.EN_ORDER_SUCCE, info);
      }
    }
    else if (info.orderStatus == OrderStatus.OS_SDK_CHECK_ERR)
    {
    }
}
明显看粗EN_ORDER_SUCCE是支付成功,而OS_SDK_CHECK_ERR是支付失败。
我们的目标是支付成功,为了简洁,我要把红色方框的部分删除,


接下来我们用Reflexil.Reflector.AIO.dll插件修改代码。
这代码没有dex反编译出来的smali代码好看,
而且发现找不到EN_ORDER_SUCCE和OS_SDK_CHECK_ERR!


没关系,我们点击EN_ORDER_SUCCE,有:
EN_ORDER_SUCCE = 0x628点击OS_SDK_CHECK_ERR,有:
OS_SDK_CHECK_ERR = 3这时再切换到IL代码,就豁然开朗了。


对照着IL代码,删除掉红色方框的代码,保存。
保存后再次载入保存后的dll,看C#代码,以确定没有修改错。

private void OnOrderCheck(int code, JsonData jsonOrder)
{
    NtOrderInfo info = NtOrderInfo.FromJsonData(jsonOrder);
    this.log(string.Format("CallbackMessage - OnOrderCheck: code={0} order={1} status={2}", code, info.orderId, info.orderStatus));
    this.log("order.orderStatus == OrderStatus.OS_SDK_CHECK_OK");
    if (CGlobleConfig.IsLoginNetEase)
    {
      ISingleton<CNetWorkDataManager>.Instance().CheckOrderId(info);
    }
    else
    {
      Messenger.Broadcast<NtOrderInfo>(ESystemEventType.EN_ORDER_SUCCE, info);
    }
}
可以看粗修改后的代码会跳到支付成功了。

接下来把dll拖回原来的位置,再签名,安装运行。

static/image/hrline/4.gif


0x3 测试
运行修改好的游戏,发现取消支付时会提示成功,钻石也增加了。
而飞行模式下则是没支付弹框秒成功。


至此完成该游戏的内购破解。

static/image/hrline/4.gif


0x4 其他
.net reflector下载:爱盘
.net reflector用法:Reflector 之reflexil使用
.net IL 指令:.net IL 指令速查

后话:
1.感觉.NET的代码一旦熟练了,会比smali代码更快更容易修改。
2.学习破解,或者其他东西,坚持很重要~



spguangz 发表于 2015-9-19 21:59

吾爱T阿杰 发表于 2015-9-19 13:34
我只想玩玩成品...

@风男子 @吾爱T阿杰 @jcm245
建议练习下,比较简单!{:1_918:}

asadas111 发表于 2015-9-19 12:42

大神,太厉害了

renfeng 发表于 2015-9-19 12:45

顶下楼主,支持楼主原创

sdf54ds53 发表于 2015-9-19 12:52

这什么东西啊?

常黑屏 发表于 2015-9-19 12:52

越来越神了,呵呵

radiant 发表于 2015-9-19 12:53

这个游戏我也蛮喜欢~

不再丶堕落 发表于 2015-9-19 13:05

楼主666666

spguangz 发表于 2015-9-19 13:08

radiant 发表于 2015-9-19 12:53
这个游戏我也蛮喜欢~

技能不够华丽~
角色不够多~

吾爱T阿杰 发表于 2015-9-19 13:34

我只想玩玩成品...

jcm245 发表于 2015-9-19 14:05

哥们成品呢
页: [1] 2 3
查看完整版本: U3d游戏『塔々西游』内购破解过程