本帖最后由 jazk2004 于 2017-11-6 14:37 编辑
这是我发的第二个分享破解内购的帖子了,【第一个是:https://www.52pojie.cn/thread-658136-1-1.html】
-----------------------开始--------------------------------------------
游戏:【元气骑士】https://www.taptap.com/app/34751
环境:【手机端】
工具:【MT管理器2】
过程:
第一步【获取相关提示信息】:下载游戏安装之后,过了教程,然后在“售货机”那里可以购买宝石,1元=800宝石,点击购买后,跳转到爱贝支付,然后选择取消支付,提示支付失败;
第二步【按提示信息搜索】:打开MT管理器2,找到游戏安装包,点击后以“查看”方式打开,选择classes.dex文件 -->Dex编辑器++, 这里我一般选择搜索“失败”,得到下图页面
从上往下看,第一个IAppPayOrderChecker里面没有pay相关的方法,第二个MainActivity$3$1里面看到一个OnPayResult方法,应该是这个了,打开看看,在里面搜索"fail",看到有onPayFail,那说明应该也有onPaySuccess,往下找就可以找到,具体修改方法如下,
[Java] 纯文本查看 复制代码 goto_46
:pswitch_46 #记住这个编号,下面要修改
invoke-static {}, Lcom/chillyroomsdk/sdkbridge/config/SdkConfig;->getInstance()Lcom/chillyroomsdk/sdkbridge/config/SdkConfig;
move-result-object v1
const-string v2, "publicKey"
invoke-virtual {v1, v2}, Lcom/chillyroomsdk/sdkbridge/config/SdkConfig;->getAppParam(Ljava/lang/String;)Ljava/lang/String;
move-result-object v1
invoke-static {p2, v1}, Lcom/iapppay/sdk/main/IAppPayOrderUtils;->checkPayResult(Ljava/lang/String;Ljava/lang/String;)Z
move-result v0
const-string v0,"true" #这里是一个容易忽略的地方,因为checkPayResult方法返回值赋值给v0,所以使v0=true
.line 101
.local v0, "payState":Z
const-string v0, "true"
.line 102
iget-object v1, p0, Lcom/chillyroomsdk/iapppay/MainActivity$3$1;->this$1:Lcom/chillyroomsdk/iapppay/MainActivity$3;
iget-object v1, v1, Lcom/chillyroomsdk/iapppay/MainActivity$3;->this$0:Lcom/chillyroomsdk/iapppay/MainActivity;
const-string v2, "支付成功"
invoke-static {v1, v2, v3}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object v1
invoke-virtual {v1}, Landroid/widget/Toast;->show()V
.line 103
iget-object v1, p0, Lcom/chillyroomsdk/iapppay/MainActivity$3$1;->this$1:Lcom/chillyroomsdk/iapppay/MainActivity$3;
iget-object v2, p0, Lcom/chillyroomsdk/iapppay/MainActivity$3$1;->val$orderId:Ljava/lang/String;
iget-object v3, p0, Lcom/chillyroomsdk/iapppay/MainActivity$3$1;->val$productId:Ljava/lang/String;
iget-object v4, p0, Lcom/chillyroomsdk/iapppay/MainActivity$3$1;->val$extra:Ljava/lang/String;
invoke-virtual {v1, v2, v3, v4}, Lcom/chillyroomsdk/iapppay/MainActivity$3;->onPaySuccess(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
return-void
goto :goto_19
然后继续往下,找到结尾,采用修改pswitch语句,达到不管什么条件,都跳转到成功的pswitch那里:
[Java] 纯文本查看 复制代码 .line 96
:pswitch_data_88
.packed-switch 0x0
:pswitch_46 #改成成功对应pswitch
:pswitch_46 #改成成功对应pswitch
:pswitch_46 #改成成功对应pswitch
.end packed-switch
.end method
到这里,购买成功的修改就完成了,但是进入游戏支付还是不成功,提示“此订单没有进行支付,如有疑问请咨询客服”,这也是这个游戏的一个特点,订单验证,那咋们继续根据提示信息搜索【此订单】这几个字,就会找到一个文件IAppOrderRestore的文件,打开后,找到onPostExecute这个方法(有两个同名,找(Ljava/lang/String;)这个),打开后,再搜索【此订单】,定位到如下的位置:
[Java] 纯文本查看 复制代码 :try_start_1f8
move-object/from16 v0, p0
iget-object v2, v0, Lcom/chillyroomsdk/iapppay/IAppPayOrderRestorer;->m_activity:Landroid/app/Activity;
const-string v3, "此订单没有进行支付,如有疑问请咨询客服"
const/4 v4, 0x1
invoke-static {v2, v3, v4}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object v2
invoke-virtual {v2}, Landroid/widget/Toast;->show()V
.line 163
move-object/from16 v0, p0
iget-object v2, v0, Lcom/chillyroomsdk/iapppay/IAppPayOrderRestorer;->m_orderId:Ljava/lang/String;
invoke-static {v2}, Lcom/chillyroomsdk/sdkbridge/order/OrderManager;->RemoveOrderFromPending(Ljava/lang/String;)V
:try_end_20d
.catch Lorg/json/JSONException; {:try_start_1f8 .. :try_end_20d} :catch_20e
.catchall {:try_start_1f8 .. :try_end_20d} :catchall_258
goto :goto_1be
既然这里是验证失败,那找找前面的相关代码是否有验证成功等信息,找过之后没有,只有“恢复订单”,那可以猜一下代码的逻辑呢:恢复订单之后应该就是验证成功并支付,如果失败就返回不成功的信息,最后定位到2个if判断,
[Java] 纯文本查看 复制代码 :goto_1be
move-object/from16 v0, p0
iget-boolean v2, v0, Lcom/chillyroomsdk/iapppay/IAppPayOrderRestorer;->m_restoreAll:Z
if-eqz v2, :cond_23a #判断v2如果等于0,跳转到cond_23a,通过下面的分析,这里要注释掉
sget-object v2, Lcom/chillyroomsdk/sdkbridge/order/OrderManager;->pendingOrders:Ljava/util/ArrayList;
invoke-virtual {v2}, Ljava/util/ArrayList;->size()I
move-result v2
if-lez v2, :cond_23a #判断v2如果小于等于0,跳转到cond_23a ,通过下面的分析,这里要注释掉
.line 169
然后看 :cond_23a处的代码如下:
[Java] 纯文本查看 复制代码 :cond_23a
move-object/from16 v0, p0
iget-object v2, v0, Lcom/chillyroomsdk/iapppay/IAppPayOrderRestorer;->m_dialog:Landroid/app/ProgressDialog; #使v2=m_dialog;
if-eqz v2, :cond_b3 #判断v2如果等于0,跳转到cond_b3
.line 172
move-object/from16 v0, p0
iget-object v2, v0, Lcom/chillyroomsdk/iapppay/IAppPayOrderRestorer;->m_dialog:Landroid/app/ProgressDialog;
invoke-virtual {v2}, Landroid/app/ProgressDialog;->dismiss()V
goto/16 :goto_b3 #跳转到cond_b3
#也就是说,上面v2不管是小于等于0,还是等于0,总要调到:cond_b3的
再看:cond_b3的代码:
[Java] 纯文本查看 复制代码 .line 189
:cond_b3
:goto_b3
return-void #这里返回空值了,并且是该方法结束了,就是支付失败
所以那两个if处需要注释掉。
第三步【解除签名验证】:到这里还不算完,因为这个游戏是有签名验证的,需要弄掉签名验证(关闭网络进游戏会闪退,判断是本地签名验证),搜索signatures,这里需要注意修改"索搜类型"=代码,定位到UnityExtendActivity的GetKeyHash方法,
[Java] 纯文本查看 复制代码 .method public static GetKeyHash()Ljava/lang/String;
.registers 7
.prologue
return-void #直接插入该代码,返回空值
const/4 v3, 0x0
到此结束了,进游戏可以购买宝石,也可以购买角色了,购买宝石需要返回一下主页(刚进游戏的那个页面)让订单验证成功才行。
作为新手,以上分享难免有错误和不足,希望各位发现后,下手轻点,希望与各位一起学习成长。
|