Android逆向-Android基础逆向7(内购干货集合)
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/ObjectZ :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(内购干货集合)的更多相关文章
- Android逆向系列文章— Android基础逆向(6)
本文作者:HAI_ 0×00 前言 不知所以然,请看 Android逆向-Android基础逆向(1) Android逆向-Android基础逆向(2) Android逆向-Android基础逆向(2 ...
- Android逆向-Android基础逆向(5)
本文作者:i春秋作家——HAI_ 0×00 前言 不知所以然,请看 Android逆向-Android基础逆向(1)Android逆向-Android基础逆向(2)Android逆向-Android基 ...
- 瘟疫公司中国版(Android)手动破解内购
前言 洒家近日下载了个瘟疫公司中国版(安卓版)(com.easymobi.plagueinc.mi ,版本 1.1.2(5)(.mi 小米版)),发现游戏需要内购而且价格不菲. 需求 root权限 文 ...
- Android破解——支付宝内购破解方法总结
支付宝破解三种方式: 想学一下支付宝内购的相关知识,但是搜索了论坛,发现但是没有相关的帖子,于是便是打算自己来写一篇总结 一.9000的十六进制代码修改 搜索9000的十六进制,也就是搜索0x2328 ...
- Android应用开发基础篇(3)-----ListView
一.概述 ListView是一个列表显示控件,它的应用非常广泛,在很多应用程序中都可以看到它的身影,比如来电通,网易新闻等等,特别是QQ.因此非常有必要熟练掌握它. 二.要求 能够利用ListView ...
- Android训练课程(Android Training) - NFC基础
NFC 基础 本文档介绍了在Android上的基本的NFC任务.它说明了如何发送和接收的NDEF消息(NDEF messages)的形式的表单里包含的NFC数据(NFC data),并介绍Androi ...
- RE-1 逆向分析基础
逆向分析基础 0x01-0x0C 本笔记使用汇编指令为x86架构下汇编指令,ARM架构汇编指令不做介绍 0x01. 关于RE 逆向工程(Reverse Engineering RE) 逆向分析方法: ...
- Android 的UI基础布局的学习
一. 今天学习了Android 的UI基础布局的部分,绝大多数的布局都在Androidstudio的这个界面里,如下: 在左边的框里的palette的内部,包含了的大多数的布局所要用的button按钮 ...
- Android 触摸手势基础 官方文档概览
Android 触摸手势基础 官方文档概览 触摸手势检测基础 手势检测一般包含两个阶段: 1.获取touch事件数据 2.解析这些数据,看它们是否满足你的应用所支持的某种手势. 相关API: Moti ...
随机推荐
- cout<<endl 本质探索
C++中,有一种对象叫操控器(manipulators),专门用来操控stream的对象,在C++标准中,预定义好几种操控器,常见的有: flush 刷新output缓冲区,将内容写入输出设备 end ...
- instanceof用法及本质:
import static java.lang.System.*; public class InstanceofTest{ public static void main(String[] args ...
- linux安装json
安装Json库 1.下载JsonCpphttp://sourceforge.net/projects/jsoncpp/files/ 2.下载sconshttp://sourceforge.net/pr ...
- 2018.08.06bzoj1251: 序列终结者(非旋treap)
传送门 平衡树板子题. 直接fhqtreap打区间标记就行了. 代码: #include<bits/stdc++.h> #define N 50005 using namespace st ...
- 2018.07.17 CQOI2017 余数求和(整除分块)
洛谷传送门 bzoj传送门 这道题要用到学习莫比乌斯反演时掌握的整除分块算法,也就是对于一个数n" role="presentation" style="pos ...
- 主机和docker容器拷贝文件
从主机复制到容器sudo docker cp host_path containerID:container_path 从容器复制到主机sudo docker cp containerID:conta ...
- 基于SceneControl的三维GIS开发
在ArcGIS体系中,三维开发包括两种:基于Scene的三维开发和基于Globe的三维开发. 由上图可以看出,两种开发的接口都很相似,掌握了Scene开发会相对容易的过渡到Globe开发中. 正如上图 ...
- OSC和GitHub中项目公钥和管理公钥
对于开源托管网站GitHub大家应该不陌生吧,以前一直设置的是github上面的ssh公钥,一直没有发生什么问题,今天在遇到一个问题:git同时把代码push到两个远程仓库.所以就在github和os ...
- 池建强 博客 Mac使用技巧 第一季
第1天: 今天推送的Mac技巧: 使用OS X,我们可以充分利用系统提供的多个Space,把不同的程序放到不同的Space,让我们的系统更有扩展性.如何增加Space呢?四指上推,在桌面的最上方会出现 ...
- 201521123035-个人作业4——alpha阶段个人总结
个人总结 在alpha 结束之后, 每位同学写一篇个人博客, 总结自己的alpha 过程: 第一部分 类别 具体技能和面试问题 现在的回答(大三) 语言 最拿手的计算机语言是一?,代码量多少?(偏前端 ...