本文作者:MSTLab-EvilChen

0×00 前言

首先,本来想写NDK的,但是还是先把这个流程过一遍吧,这个流程是必不可少的。
其次,RMB真的是一个好东西。

导航

由于本人为了节省时间,不想贴太多的代码,所以总结了一个导航栏目。并且在栏目中有内容的说明。帮助了解。希望一起进步。
博客系列导航
为了练习方便,顺便把apk进行了一个整理。
练习传送门

内容

1.内购基础

0×01 内购知识

基本知识

什么是内购?

内购就是游戏内部购买。

SDK厂商

1.移动
2.电信
3.联通
4.支付宝
5.微信
6.其他

其他破解

拇指玩
网侠手机站
7723
爱吾
7yw趣游
软天空
西西软件园
葫芦侠三楼

游戏平台

1.某咕游戏

0×02 经验总结

关键点通用总结

通用1

最古老的方法就是搜索关键字:
“成功“
“失败”

绕过通用

switch

(1)覆盖switch失败转为成功。
(2)更改switch跳转
(3)最后一种我最喜欢作用,思路最明确,使用goto进行跳转。跳转到成功即可。

某咕游戏总结

方法 :onResult

移动总结

onbillingfinish()
dobilling()
onresult()

联通总结

payCallback()
PayResult()

电信总结

paySuccess()

支付宝总结

支付失败
9000
ResultStaus

0×03 某咕游戏破解实例

也不能说是因为篇幅问题吧,就是有点犯懒,不想截取一些简单的步骤。所以能简写就简写,这样能多分析几个实例。

实例是我刚找的。

原版apk:练习传送门在这里找,编号:2001

实例分析(1)

暂停:2018年2月12日00:34:05
原因:吵到我爸睡觉了。

开始时间: 2018年2月12日14:58:17

第一步:试玩。

自己玩

第二步:反编译,搜索关键字。

1.搜索“成功”

这里搜索到了三条数据

点进去之后是这样一个方法:

.method public static d()V
    .locals 4     const/4 v3, 0x1     const/4 v2, 0x0     sget v0, Lcom/xy/kom/d/bk;->i:I     invoke-static {v0}, Lcom/xy/kom/g/p;->b(I)Z     sget v0, Lcom/xy/kom/d/bk;->h:I     invoke-static {v0}, Lcom/xy/kom/g/p;->c(I)Z     sget-boolean v0, Lcom/xy/kom/d/bk;->G:Z     if-eqz v0, :cond_4     sget-object v0, Lcom/xy/kom/GameActivity;->A:Lcom/xy/kom/GameActivity;     iget-object v0, v0, Lcom/xy/kom/GameActivity;->m:Lcom/xy/kom/g/p;     invoke-virtual {v0}, Lcom/xy/kom/g/p;->x()Ljava/util/ArrayList;     move-result-object v0     invoke-static {}, Lcom/xy/kom/g/f;->l()Lcom/xy/kom/g/f;     move-result-object v1     invoke-virtual {v0, v1}, Ljava/util/ArrayList;->add(Ljava/lang/Object Z     :goto_0
    sget-object v0, Lcom/xy/kom/GameActivity;->A:Lcom/xy/kom/GameActivity;     iget-object v0, v0, Lcom/xy/kom/GameActivity;->m:Lcom/xy/kom/g/p;     invoke-virtual {v0}, Lcom/xy/kom/g/p;->t()V     sget-object v0, Lcom/xy/kom/GameActivity;->A:Lcom/xy/kom/GameActivity;     iget-object v0, v0, Lcom/xy/kom/GameActivity;->r:Lcom/xy/kom/d/ei;     if-eqz v0, :cond_0     sget-object v0, Lcom/xy/kom/GameActivity;->A:Lcom/xy/kom/GameActivity;     iget-object v0, v0, Lcom/xy/kom/GameActivity;->r:Lcom/xy/kom/d/ei;     invoke-virtual {v0, v2}, Lcom/xy/kom/d/ei;->a(I)V     :cond_0
    sget-object v0, Lcom/xy/kom/GameActivity;->A:Lcom/xy/kom/GameActivity;     const/4 v1, 0x6     invoke-virtual {v0, v1}, Lcom/xy/kom/GameActivity;->a(I)V     invoke-static {}, Lcom/xy/kom/d/bk;->h()V     sget-object v0, Lcom/xy/kom/GameActivity;->A:Lcom/xy/kom/GameActivity;     const-string v1, "\u8d2d\u4e70\u6210\u529f\uff01\u9053\u5177\u5df2\u53d1\u653e"     invoke-static {v0, v1, v2}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;     move-result-object v0     invoke-virtual {v0}, Landroid/widget/Toast;->show()V     sget-object v0, Lcom/xy/kom/GameActivity;->N:Lcom/xy/kom/e/a;     invoke-virtual {v0, v3}, Lcom/xy/kom/e/a;->a(I)V     sput-boolean v3, Lcom/xy/kom/GameActivity;->M:Z     invoke-static {}, Lcom/xy/kom/a/h;->f()I     move-result v0     const/16 v1, 0xd     if-ne v0, v1, :cond_2     sget v0, Lcom/xy/kom/GameActivity;->h:I     const/4 v1, 0x2     if-ne v0, v1, :cond_2     sget-object v0, Lcom/xy/kom/GameActivity;->A:Lcom/xy/kom/GameActivity;     iget-object v0, v0, Lcom/xy/kom/GameActivity;->m:Lcom/xy/kom/g/p;     invoke-virtual {v0}, Lcom/xy/kom/g/p;->w()Ljava/util/ArrayList;     move-result-object v0     invoke-interface {v0}, Ljava/util/List;->size()I     move-result v1     sget-object v2, Lcom/xy/kom/GameActivity;->A:Lcom/xy/kom/GameActivity;     iget-object v2, v2, Lcom/xy/kom/GameActivity;->m:Lcom/xy/kom/g/p;     invoke-virtual {v2}, Lcom/xy/kom/g/p;->l()I     move-result v2     if-ne v1, v2, :cond_1     sget-object v1, Lcom/xy/kom/GameActivity;->A:Lcom/xy/kom/GameActivity;     iget-object v1, v1, Lcom/xy/kom/GameActivity;->r:Lcom/xy/kom/d/ei;     invoke-interface {v0}, Ljava/util/List;->size()I     move-result v2     add-int/lit8 v2, v2, -0x1     invoke-interface {v0, v2}, Ljava/util/List;->get(I)Ljava/lang/Object;     move-result-object v0     check-cast v0, Lcom/xy/kom/g/f;     invoke-virtual {v1, v0}, Lcom/xy/kom/d/ei;->b(Lcom/xy/kom/g/f;)V     :cond_1
    sget-object v0, Lcom/xy/kom/GameActivity;->A:Lcom/xy/kom/GameActivity;     iget-object v0, v0, Lcom/xy/kom/GameActivity;->r:Lcom/xy/kom/d/ei;     sget-object v1, Lcom/xy/kom/d/bk;->d:Lcom/xy/kom/g/f;     invoke-virtual {v0, v1}, Lcom/xy/kom/d/ei;->a(Lcom/xy/kom/g/f;)V     invoke-static {}, Lcom/xy/kom/d/bk;->m()V     :cond_2
    sget-boolean v0, Lcom/xy/kom/d/bk;->G:Z     if-nez v0, :cond_3     const/4 v0, 0x0     sput-object v0, Lcom/xy/kom/d/bk;->d:Lcom/xy/kom/g/f;     :cond_3
    return-void     :cond_4
    sget-object v0, Lcom/xy/kom/GameActivity;->A:Lcom/xy/kom/GameActivity;     iget-object v0, v0, Lcom/xy/kom/GameActivity;->m:Lcom/xy/kom/g/p;     invoke-virtual {v0}, Lcom/xy/kom/g/p;->x()Ljava/util/ArrayList;     move-result-object v0     sget-object v1, Lcom/xy/kom/d/bk;->d:Lcom/xy/kom/g/f;     invoke-virtual {v0, v1}, Ljava/util/ArrayList;->add(Ljava/lang/Object Z     goto/16 :goto_0
.end method

这里找到一个调用成功的方法。我们继续溯源查看。

发现是一个onResult方法。

解决方法:
(1)覆盖switch失败转为成功。
(2)更改switch跳转
(3)最后一种我最喜欢作用,思路最明确,使用goto进行跳转。跳转到成功即可。

恩,改完之后汇编,整个游戏就破解好了。
没什么好说的。

测试成果。

是成功的,懒的玩。不想发图,自己测试吧,有疑问可以找我。

实例分析(2)

之前没有找好,现在去找找。
找练习的APK的时候主要注意三点。
(1)最好是单机
(2)选择大小的时候选小一点的,恩,反编译快。我们的目的是为了练习。
(3)无壳,现阶段可定脱不了壳。

找到了一个什么酷跑什么的游戏。
三步走

第一步 试玩

原版apk:练习传送门在这里找,编号:2002

拿到游戏,首先就要玩一下是不,人家怎么购买的你总要知道吧。说不定会有新的发现。

反编译破解

搜索关键字“成功失败”

点开之后进去,发现,原来还是一个onResult。

.method public onResult(ILjava/lang/String;Ljava/lang/Object;)V
    .locals 3
    .param p1, "paramAnonymousInt"    # I
    .param p2, "paramAnonymousString"    # Ljava/lang/String;
    .param p3, "paramAnonymousObject"    # Ljava/lang/Object;     .prologue
    goto :pswitch_0
    .line 26
    packed-switch p1, :pswitch_data_0     .line 37
    const-string v0, "Unity"     new-instance v1, Ljava/lang/StringBuilder;     const-string v2, "\u8d2d\u4e70\u9053\u5177\uff1a["     invoke-direct {v1, v2}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V     invoke-virtual {v1, p2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;     move-result-object v1     const-string v2, "]\u53d6\u6d88\uff01"     invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;     move-result-object v1     invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;     move-result-object v1     invoke-static {v0, v1}, Landroid/util/Log;->v(Ljava/lang/String;Ljava/lang/String;)I     .line 38
    invoke-static {}, Lcom/huibang/paopao/MainActivity;->access$0()Ljava/lang/String;     move-result-object v0     invoke-static {}, Lcom/huibang/paopao/MainActivity;->access$1()Ljava/lang/String;     move-result-object v1     const-string v2, "cancel"     invoke-static {v0, v1, v2}, Lcom/unity3d/player/UnityPlayer;->UnitySendMessage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V     .line 41
    :goto_0
    return-void     .line 29
    :pswitch_0
    const-string v0, "Unity"     new-instance v1, Ljava/lang/StringBuilder;     const-string v2, "\u8d2d\u4e70\u9053\u5177\uff1a["     invoke-direct {v1, v2}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V     invoke-virtual {v1, p2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;     move-result-object v1     const-string v2, "]  \u6210\u529f\uff01"     invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;     move-result-object v1     invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;     move-result-object v1     invoke-static {v0, v1}, Landroid/util/Log;->v(Ljava/lang/String;Ljava/lang/String;)I     .line 30
    invoke-static {}, Lcom/huibang/paopao/MainActivity;->access$0()Ljava/lang/String;     move-result-object v0     invoke-static {}, Lcom/huibang/paopao/MainActivity;->access$1()Ljava/lang/String;     move-result-object v1     const-string v2, "success"     invoke-static {v0, v1, v2}, Lcom/unity3d/player/UnityPlayer;->UnitySendMessage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V     goto :goto_0     .line 33
    :pswitch_1
    const-string v0, "Unity"     new-instance v1, Ljava/lang/StringBuilder;     const-string v2, "\u8d2d\u4e70\u9053\u5177\uff1a["     invoke-direct {v1, v2}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V     invoke-virtual {v1, p2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;     move-result-object v1     const-string v2, "] \u5931\u8d25\uff01"     invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;     move-result-object v1     invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;     move-result-object v1     invoke-static {v0, v1}, Landroid/util/Log;->v(Ljava/lang/String;Ljava/lang/String;)I     .line 34
    invoke-static {}, Lcom/huibang/paopao/MainActivity;->access$0()Ljava/lang/String;     move-result-object v0     invoke-static {}, Lcom/huibang/paopao/MainActivity;->access$1()Ljava/lang/String;     move-result-object v1     const-string v2, "fail"     invoke-static {v0, v1, v2}, Lcom/unity3d/player/UnityPlayer;->UnitySendMessage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V     goto :goto_0     .line 26
    nop     :pswitch_data_0
    .packed-switch 0x1
        :pswitch_0
        :pswitch_1
    .end packed-switch
.end method

咪咕整个支付流程大概就是这个样子。(我猜的)

原本游戏(隐藏不可见)—咪咕支付接口(可见)——咪咕支付处理(不可见)——返回结果(可见)——回馈给原本游戏(不可见)

我们搞的其实就是在返回结果上动手脚。

测试

测试我做了,但是截图不了,有兴趣的可以自己去做下尝试。

总结

咪咕游戏最明显的一个特征就是 onResult()这个方法,只要改了这个方法,那么就可以轻松搞定了。当然你也可以通过其他手段找到它的特征。不过经验是可以提高效率哒嘛。

0×04 结束语

说明

这些只是对方法的一个总结,在总结的时候,可能没有时间整理实例了,但是在之后有时间或者遇到的话,那么我们就可以从这里找到方法去破解内购等。当然也包括了二次破解等说明。
之后如果需要则进行补充。

Android逆向-Android基础逆向7(内购干货集合)的更多相关文章

  1. Android逆向系列文章— Android基础逆向(6)

    本文作者:HAI_ 0×00 前言 不知所以然,请看 Android逆向-Android基础逆向(1) Android逆向-Android基础逆向(2) Android逆向-Android基础逆向(2 ...

  2. Android逆向-Android基础逆向(5)

    本文作者:i春秋作家——HAI_ 0×00 前言 不知所以然,请看 Android逆向-Android基础逆向(1)Android逆向-Android基础逆向(2)Android逆向-Android基 ...

  3. 瘟疫公司中国版(Android)手动破解内购

    前言 洒家近日下载了个瘟疫公司中国版(安卓版)(com.easymobi.plagueinc.mi ,版本 1.1.2(5)(.mi 小米版)),发现游戏需要内购而且价格不菲. 需求 root权限 文 ...

  4. Android破解——支付宝内购破解方法总结

    支付宝破解三种方式: 想学一下支付宝内购的相关知识,但是搜索了论坛,发现但是没有相关的帖子,于是便是打算自己来写一篇总结 一.9000的十六进制代码修改 搜索9000的十六进制,也就是搜索0x2328 ...

  5. Android应用开发基础篇(3)-----ListView

    一.概述 ListView是一个列表显示控件,它的应用非常广泛,在很多应用程序中都可以看到它的身影,比如来电通,网易新闻等等,特别是QQ.因此非常有必要熟练掌握它. 二.要求 能够利用ListView ...

  6. Android训练课程(Android Training) - NFC基础

    NFC 基础 本文档介绍了在Android上的基本的NFC任务.它说明了如何发送和接收的NDEF消息(NDEF messages)的形式的表单里包含的NFC数据(NFC data),并介绍Androi ...

  7. RE-1 逆向分析基础

    逆向分析基础 0x01-0x0C 本笔记使用汇编指令为x86架构下汇编指令,ARM架构汇编指令不做介绍 0x01. 关于RE 逆向工程(Reverse Engineering RE) 逆向分析方法: ...

  8. Android 的UI基础布局的学习

    一. 今天学习了Android 的UI基础布局的部分,绝大多数的布局都在Androidstudio的这个界面里,如下: 在左边的框里的palette的内部,包含了的大多数的布局所要用的button按钮 ...

  9. Android 触摸手势基础 官方文档概览

    Android 触摸手势基础 官方文档概览 触摸手势检测基础 手势检测一般包含两个阶段: 1.获取touch事件数据 2.解析这些数据,看它们是否满足你的应用所支持的某种手势. 相关API: Moti ...

随机推荐

  1. TYVJ 1940 创世纪

    Description: 上帝手中有着 N 种被称作“世界元素”的东西,现在他要把它们中的一部分投放到一个新的空间中去以建造世界.每 种世界元素都可以限制另外一种世界元素,所以说上帝希望所有被投放的世 ...

  2. Ps中的难点问题分析

    一.布尔运算的运用 1.布尔运算是在图形工具组中使用,快捷键“U” 2.使用方法:都是在同一图层下运算,在进行布尔运算之前,首先用路径选择工具,小黑箭头,快捷键是“A” 选取你要运算的图形. 3.布尔 ...

  3. Mysql 查看表结构的命令

    创建数据库create database abc; 显示数据库 show databases; 使用数据库 use 数据库名; 直接打开数据库 mysql -h localhost -u root - ...

  4. 主成分_CPA

    基本原理:方差最大原理 通过正交变换将原相关性变量转化为不相关的变量 第一主成分:线性组合  方差最大 第二主成分:线性组合,COV(F1,F2)=0 步骤: 原始数据标准化:DataAdjust(m ...

  5. Mybatis传值为空需要配置JdbcType来解决吗?(XML文件不需要配置JdbcType)

    1,解决思路,配置自定义的语言驱动,重写自己的Paramethander package cn.com.servyou.gxdqy.tool.xmlhelper; import org.apache. ...

  6. windows10创意者完整镜像下载

    今天给大家分享一个windwos10创意者的完整镜像. 在官网,我们看到的是直接下载安装,但是在没有网的时候我们就无法了 而且在很多的时候我们在下载安装windows10的时候回遇到很多无法估量的问题 ...

  7. azman使用笔记

    azman.msc 打开 容易冲突,要用lock 效率问题,可用sql azman

  8. 2018.10.02 NOIP模拟 序列维护(线段树+广义欧拉定理)

    传送门 一道比较好的线段树. 考试时线性筛打错了于是弃疗. 60分暴力中有20分的快速幂乘爆了于是最后40分滚粗. 正解并不难想. 每次区间加打懒标记就行了. 区间查询要用到广义欧拉定理. 我们会发现 ...

  9. UVa 12034 Race (递推+组合数学)

    题意:A,B两个人比赛,名次有三种情况(并列第一,AB,BA).输入n,求n个人比赛时最后名次的可能数. 析:本来以为是数学题,排列组合,后来怎么想也不对.原来这是一个递推... 设n个人时答案为f( ...

  10. webuploader php上传视频

    webuploader 上传大视频文件 在网上找了一个,自己重新组合了下,两个主要的文件,再加上官方下载的文件.其中有几个重要的点. 1.上传存放视频目录为了测试 直接777 2.fileupload ...