[原创]记某app内购破解 – 安卓逆向菜鸟的初体验

转载 2018年04月17日 10:14:29

前言

  因为某个机缘,我拿到一个赛车app,玩了一会想买个装备,居然要我掏钱包,作为一名cracker,我觉得我的尊严受到了严重的蔑视(无奈钱包空空),我觉得要捍卫我那脆弱的玻璃心(钱包),所以,开干吧。我搜索了网上相关的帖子,发现这个apk的破解都是讲了关键点都在哪里,没有具体的关键点查找思路,所以我重新自己破解了一次,中间多次误入歧途,我把自己的详细思路发在这里,与所有的菜鸟共勉。

工具

   Android killer v1.3.1.0  -- 用于搜索字符串和重打包,下文使用缩写AK

   Apktool Box v1.6.4 – 用于获取调试启动命令,下文使用缩写AB

   小米5 MIUI9.5.1.0 android7.0 – 用于运行apk

   Android Studio 2.3.3(安装 smalidea-0.0.5插件) – 用于调试smali源码,下文使用缩写AS

   Jadx-gui 0.7.1 – 用于查看smali反编译源码,其实AK也有反编译功能,但是AK的反编译有的地方没有jadx好看,我发现switchcase结构AK总是翻译成ifelse结构。

搭建调试环境

  重打包生成可调式APK

  使用AS调试smali需要apk设置调试标识(不然AS会显示错误:Unable to open debugger port (localhost:7800): java.net.SocketException "connection reset"),用AK打开apk,从工程管理器栏打开文件androidmanifest.xml,在application项添加如下代码:

1
android:debuggable="true"

  如下图:

    

  然后选择菜单android->编译,重打包APK。并安装到米5里面。

  调试启动apk

  使用AB打开apk,点击启动命令按钮生成调试启动命令,

       

  将上图中下面的命令拷贝到cmd中,启动apk,手机中apk会停在调试启动界面。然后查看apk的进程PID,


  然后使用adb命令转发调试到tcp端口8700,如下:


  接下来,使用AS建立smali源码的工程,并配置调试端口,这部分内容网上有现成的教程,这里就不多说了,建立完了之后,点击调试按钮,AS下面显示日志如下表示启动调试成功:


到此,调试环境搭建成功,下面开始破解。

破解过程

  思路一:错误信息提示

老思路,先是试用一下。点击游戏的购买,会弹出一个购买的框,需要输入手机号和验证码,这里随便输入一个手机号和验证码,点击确认支付,不出意外会失败,并弹出一个提示框,


好了,这是我的第一个第一个失败点。我的思路是,既然它给了这个错误提示,那么显示这个错误的地方肯定有支付成功和失败的逻辑,那么我修改了这个逻辑,就可以了。OK,下面就是如何找到这个判断的逻辑。没错,字符串查找,最传统的方法,在android里面搜字符串,不能直接搜汉字,需要将它转为unicode码,然后将“短信验证码验证失败”转换为unicode码,则为“\u77ed\u4fe1\u9a8c\u8bc1\u7801\u9a8c\u8bc1\u5931\u8d25 ”,结果没有找到,好吧,是不是字符串拼接出来的呢,短一点,搜“短信验证码”,然后有了搜索结果,


不好意思,我是小菜看不懂smali,将其转换为java源代码,


  原函数太大了,这里只贴了一部分,看着逻辑真不像,那么到底是不是这个逻辑呢?验证的办法很简单,在这里下个断点,然后,没有断下来。那么在函数入口下个断点,还是没有来。好吧,这个思路以失败告终。后来跟踪代码我才知道这个支付框是从so里面弹出来的。呜呜。。

   思路二:网络帖子借鉴

     之前搜过类似的帖子,帖子说是搜字符串“支付成功”,所以我将字符串转化为unicode码,到AK里面去搜索,然后搜索到三个结果:


同样,验证这里是不是判断是否支付成功的逻辑代码,在每个字符串所在的函数头部设置断点,这里没有在字符串所在的位置设置断点是因为我是不会掏钱包的,所有的操作都是支付失败的操作,支付成功的代码逻辑肯定是不会来的,所以在函数头部设置断点,然后,点击确认支付没有断下来,但是当我点击关闭按钮时,却成功的断在了第一个函数中。这是意外的惊喜。然后使用jadx查看这个函数的逻辑:


代码的逻辑很清晰,检查参数resultCode的值,然后判断是否支付成功,所以这里很有可能就是我要的关键代码逻辑。验证一下,把所有的switch结构都改成到case1分支。Smali代码的语法是把所有的case放到一块,如下


上面代码的意思是将switch里面的值与1比较,结果为0则跳转到pswitch_0标号,结果为1则跳转到pswitch_1执行,所以这里把所有的标号都改为pwtich_0,并在下面添加一行,这样默认情况也会跳转到pswtich_0,即三种不管resultCode为何值,都会跳转到成功的分支,如下:


最后,编译重打包,安装测试,成功,OK。至此,成功破解了这个app的内功功能。

其实,当初我并没有按下支付框的关闭按钮,所以我走的是另一条思路,如果看到这里你还有耐心,可以看下我的弯路,哈哈。

  思路三:我的弯路

当在三个“支付成功”字符串所在的函数设置断点,点击手机上确认支付按钮时,三个断点都没有来。然后我换了搜所的字符串为“支付失败”,然后搜到6个结果


我在6个结果的字符串所在的函数头部设置断点,点击确认支付按钮,结果所有的断点都没有来。后来我就去网上搜帖子,见到有帖子说“支付失败”所在的一个函数checkPayResultTest的调用者在用户点击购买时被调用。所以我转变了思路,放弃了直接查找判断是否支付成功的代码,而是查找能在支付过程中会被执行到的函数,然后我可以从这个函数跟踪到判断支付的代码。使用jadx打开apk,定位到函数checkPayResultTest,右键find usage,


然后查看其调用函数,

 

在此函数的头部设置断点,当我点击购买时,程序断在了这里。这是个喜讯。此时,我发现手机上的支付框还没有弹出来,所以我想,我可以从这里跟踪下去知道支付框弹出,然后找到确认支付按钮的回调。于是我一路F7单步步入跟进去,当调试跟踪到下图中的红线标识部分时我跟不进去了:


通过查资料我才知道,这是jni调用,我这才知道了,为什么我之前设置的失败断点都没有来,原因最后掉用到so库里了。那怎么办,难道我要算调试so文件么?然后我仔细观察了这个函数调用,发现这里有个回调,于是我找到回调定义的地方,


哈哈,是不是很眼熟,在回调里面设置断点,然后这次我鬼使神差的点击了支付框的关闭按钮,然后断下来了。哈哈。再然后的操作就如同上个思路一样了。这就是我的弯路了。

  思路四:程序的“漏洞”

  这里怎么说呢,其实也不算是程序的漏洞,而是程序员的一种编程习惯。我称之为“漏洞”,通过这个“漏洞”可以定位到支付功能必须执行的某些代码。思路是这样的,我发现在程序的代码中有很多调试日志输出,我如果能修改程序输出日志,那么当我使用支付功能的时候,相关代码会输出相关调试信息,然后我搜索输出的字符串,不就可以定位到支付功能一定会调用的代码吗!

  首先,随便找一段代码,看看它是如何输出的,


从上图可以看出,调试信息的输出是通过一个叫LogUil.iT函数实现的,找到这个函数:


这里会看到,代码中有个DEBUG标志,如果此标志为真则输出调试信息,然后找到这个标志赋值的位置:

 

本来以为这个标志是会在构造里面赋值的,没想到居然是判断sdcard路径下有没有alg,哈哈,那就更简单了,我在手机的sdcard下面放了一个alg文件,

 

然后打开DDMS,启动程序,点击购买,DDMS日志视图里面发现如下信息:


到AK里面去搜索字符串“支付接口被游戏调用”,哈哈,有一条结果:


转到java源代码:


在AS中对应位置下断点,程序成功断下来啦。哈哈。

总结

虽然走了很多的弯路,但是也发现了很多有趣的东西。例如通过日志来定位代码,so中弹出对话框是无法在java中找到关键点的,要多试几种别的操作。

其它

附件太大,这里给个链接吧https://pan.baidu.com/s/1P40TZLvJXV727-mlJLNIdA

本帖子如果引起任何其它负面的影响,请版主直接删帖即可。

如果转载,请声明来自看雪。


【安卓逆向】实现内购型app的二次逆向编译破解,实现不用付费app 实践

【安卓逆向】实现内购型app的二次逆向编译破解,实现不用付费app 实践
  • qq_14997169
  • qq_14997169
  • 2016-10-07 23:45:24
  • 1031

Android逆向之旅—Android手机端破解神器MT的内购VIP功能破解教程

一、前言 在破解app的时候,我们现在几乎都是在PC端进行操作,但是之前bin神的MT管理器,可以在手机端直接破解,不过也有很大的局限性,但是对于一些简单的app破解没问题的。这个工具其实原理也...
  • qq_21071977
  • qq_21071977
  • 2017-12-07 10:16:50
  • 1812

Android逆向之旅---Android手机端破解神器MT的内购VIP功能破解教程

一、前言在破解app的时候,我们现在几乎都是在PC端进行操作,但是之前bin神的MT管理器,可以在手机端直接破解,不过也有很大的局限性,但是对于一些简单的app破解没问题的。这个工具其实原理也很简单,...
  • jiangwei0910410003
  • jiangwei0910410003
  • 2017-10-29 14:17:26
  • 3912

记某单机游戏的一次内购破解

材料准备 1)APP下载,本次演示的软件:登山赛车至天朝历险 我们去其官网下载即可,另外在其他市场下载一个低版本的, 这里我另外下载了一个 v1.3.1的,后面会有用。 http://www....
  • xiaoi123
  • xiaoi123
  • 2018-02-02 18:14:34
  • 233

Android逆向破解之Mointor查看目标日志

Android破解游戏内购心得 以上博客中提到了实用Monitor查看的方式目标日志的方式之一,但是程序员是不会重复做同样的事情滴,这次来介绍修改ROM中的boot.img文件来让手机处于User...
  • u010369338
  • u010369338
  • 2016-09-17 10:35:17
  • 543

Mac App Store应用 内购 破解 免费

  • 2013年10月01日 12:55
  • 166KB
  • 下载

Android逆向实例笔记—续力破解三个Android程序

这三个app都不是很难。但是主要的目的就是练练手,然后去理理思路。 破解在于多多练习...
  • qq_24349189
  • qq_24349189
  • 2016-08-24 21:21:24
  • 8365

IAP内购破解原理

今年3月初写过一篇《iO平台游戏安全小议》,到现今已有7个月了。在这段时间内,iOS平台上的安全问题也产生了不小的变化。从作弊方式来说,从以前稍有门槛的手工操作(命令行操作)发展成了傻瓜式的只需要点击...
  • jxgzxh110
  • jxgzxh110
  • 2014-12-08 13:34:19
  • 2396

苹果IOS 软件内购破解(亲自实践)

最爱的IOS游戏浴火银河 GOF2 HD版终于出资料篇瓦尔基里了,狂喜,不过需要内购,30大圆.... 这里说一下破解方法(没办法,没钱...)   1.ipad需要越狱 (如果不越狱,以下内容...
  • bigheadsheep
  • bigheadsheep
  • 2012-07-27 08:17:59
  • 12869

iOS内购(IAP,In App Purchases-在APP内部支付),设置及使用

项目中使用到了中间货币(金币)的形式来进行功能使用,模式是使用RMB换成-金币比如:(1RMB = 10金币),所以会集成第三方的支付平台,使用了微信和支付宝的第三方平台过后,发现审核失败,被苹果拒绝...
  • j_AV_a
  • j_AV_a
  • 2017-07-05 12:22:12
  • 951
收藏助手
不良信息举报
您举报文章:[原创]记某app内购破解 – 安卓逆向菜鸟的初体验
举报原因:
原因补充:

(最多只允许输入30个字)