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.学习破解,或者其他东西,坚持很重要~
吾爱T阿杰 发表于 2015-9-19 13:34
我只想玩玩成品...
@风男子 @吾爱T阿杰 @jcm245
建议练习下,比较简单!{:1_918:} 大神,太厉害了 顶下楼主,支持楼主原创 这什么东西啊? 越来越神了,呵呵 这个游戏我也蛮喜欢~ 楼主666666 radiant 发表于 2015-9-19 12:53
这个游戏我也蛮喜欢~
技能不够华丽~
角色不够多~ 我只想玩玩成品... 哥们成品呢