Android逆向之旅—利用icodetools工具快速定位App破解中关键点方法

Android技术篇 尼古拉斯.赵四 17287℃ 0评论

一、前言

在前面已经介绍了icodetools工具的实现原理和具体使用规则,关于这部分的知识点还不了解的同学可以去下面两篇文章详细查看:Android中注入代码工具icodetools原理篇Android中注入代码工具icodetools完善篇。同时这个工具已经放到github上了,感兴趣的同学可以下载尝试各种app的代码注入功能。那么有了这两篇文章之后,现在我得实际操作了,要动手操作一下这个工具,看看他到底有没有使用价值,下面就来看两个例子,第一个例子是如何快速找到我们想要Hook的方法点,第二个例子是如何快速定位到应用的二次签名方法。

 

二、利用工具快速定位Hook方法

第一、收集日志信息

这个例子咋们就直接用之前弄过的一个案例,微信摇塞子作弊器,不清楚的同学可以先去看看这篇文章:Android中微信摇塞子猜拳作弊器实现原理。当时如果有操作的同学会发现我们为了找到那个Hook点,废了好多力气才搞定的,但是现在如果有了这个工具,我们就好办了。

首先咋们继续使用微信6.3.9版本,有的同学说为什么不直接使用最新版,因为本案例是为了对比之前那种方式获取hook点的,之前用了6.3.9版本,这次一样得用这个版本作比较呢。咋们弄到这个版本apk之后,放到icodetools工具目录下,默认需要把apk名称改成src.apk,如果不想修改修改还得去修改脚本中的文件名,这里方便就直接改成src.apk就得了。

然后咋们运行icodetools_1.0.bat脚本文件。目录下有两个版本的脚本文件,是为了兼容更多的apk注入功能,默认首先采用1.0版本进行操作的。顺利注入代码之后,直接安装apk。下面就要开始观察日志信息了。因为默认情况下日志是关闭的,而且日志的tag是jw。所以如果想开日志,咋们还得自己手动打开日志开关。进入/data/local/tmp目录下,使用echo “-s 1” >log.txt命令写入开关值即可。

但是在微信启动的时候不建议开启,因为之前的文章中说到了,微信app非常庞大,我们给每个类的每个方法都注入日志代码了,所以如果你开始就开了日志,会发现微信可能打不开,会出现ANR,打印日志太多了。所以建议开始的时候关闭日志,等到了我们想要寻找hook点的地方在打开日志,在触发hook点逻辑,查看日志信息。

我们想要找到摇塞子和猜拳的逻辑,所以咋们得先到聊天界面,然后打开发送摇塞子的界面,这时候咋们可以打开日志了。但是这里又有一个地方需要思考,就是还是要先猜想一下,这个摇塞子和猜拳都是随机,所以应该会有一个随机数产生的方法,那么这个方法的返回值应该是一个int值,当然这个是个猜想。那么这里为了验证这个猜想,也是为了防止打印过多的方法日志,咋们再一次做一个过滤,就是限制打印日志的方法的返回值是int类型的

这个在之前介绍过了,咋们现在是支持这种过滤规则的,所以咋们需要设置的规则为:echo “-s 1 -r int” >log.txt。这个命令是在/data/local/tmp目录下运行的。其中-s 1就是代表打开日志,-r int表示只打印方法返回值是int的日志信息。有了这个规则之后,咋们就开始点击屏幕的摇塞子,这时候会发现日志还是很多的。所以为了收集更多的日志,咋们得把日志输出到一个文件中,后面就可以慢慢分析了,可以使用命令:adb logcat -s jw > D:\loginfo.txt,这样咋们就可以在我们点击摇塞子的瞬间把日志都收集到loginfo.txt文件中了。当发现塞子出现的时候,说明程序已经结束了我们想要的hook方法逻辑,这时候为了不让微信继续ANR,咋们得立马关闭日志,命令很简单:echo “-s 0” >log.txt。

第二、分析日志信息

下面咋们就要来分析一下上面收集的日志信息了loginfo.txt:

我们会发现就在刚刚点击了一下摇塞子的逻辑,结果日志就有了几M,所以可以看到微信的工程得多庞大。下面就要来借助一定经验值来做过滤分析了,比如上面的方法,明显是v4包中,肯定不是我们想要的,所以直接过滤。继续往下看,这个过程中可能一个方法会被打印多次,但是一定要有耐心,慢慢分析:

这里看到了,有一个方法比较可疑,先记录一下,并且在这里我们发现了,那个表情的控件SmileyGrid,是个表格布局,就是我们表情中用到的。所以这个方法非常可疑。继续往下看:

这个方法一样也是比较可疑的,先记录一下。继续往下看:

这个方法也是比较可疑的,记录一下,继续往下看:

这里发现了一个操作数据库的方法,但是这里又要借助经验值了,我们想要的是随机数逻辑,不可能借助数据库还需要从数据库中拿到随机数值,微信没必要这么做吧。所以本次就过滤了,但是有的同学可能发现这个没有那么强的说服力,为了有说服力,咋们也把这个方法记录一下,但是处理的优先级比较低。

第三、分析可疑方法代码

好了到这里我们就大致看完了日志中的数据,虽然好M的信息,但是大部分都是重复方法打印的信息,还有其他边都不碰不到的方法这里也没有在说明了,从上面分析之后,我们有了四个方法需要去查看:

1、com.tencent.mm.model.ah.tv

2、com.tencent.mm.sdk.platformtools.bb.d

3、com.tencent.mm.sdk.platformtools.bb.pu

4、com.tencent.kingkong.DatabaseUtils.getSqlStatementType

下面就来一次查看这四个方法的实现逻辑,咋们还是得借助Jadx工具打开微信apk:

第一个方法:com.tencent.mm.model.ah.tv

从这个方法的实现逻辑和一些应用本身的日志信息,发现这个方法并不是我们想要的,反而和获取微信uin值有很大关系。所以这个方法咋们就可以忽略了。

第二个方法:com.tencent.mm.sdk.platformtools.bb.d

这个方法比较可疑了,从代码逻辑实现上看是转化Integer值,并且还有一个默认值i,所以和我们想要的随机数可能有关系,先记住他。

第三个方法:com.tencent.mm.sdk.platformtools.bb.pu

看到这个方法就会眼前一亮,既然有随机数代码了,心中黯然窃喜呀。不过也不能非常的肯定就是他了。所以这里还是得记住它,后面会进行hook该方法验证正确性。

第四个方法我是真心不想实验了,真的不敢相信要一个随机数还和数据库扯上关系,咋们为了方便直接先使用Xposed框架hook上面那两个方法了,验证结果,如果是的,那就万事大吉了,如果不是再回来看不迟。

第四、hook验证结果

关于如何利用Xposed框架hook应用的方法这里不多解释了,不了解的同学可以去看这篇文章:Xposed框架使用原理解析。咋们直接hook上面提到的两个可以方法:

com.tencent.mm.sdk.platformtools.bb.d和com.tencent.mm.sdk.platformtools.bb.pu。

咋们编写完hook模块之后重启设备生效,然后再次打开微信,触发摇塞子的逻辑。这时候会发现这两个方法都执行了,而且打印的值正是我们摇塞子的值,那么现在有了两个方法,我们该处理哪个呢?这个需要看个人处理了,但是从上面代码来看,显然pu方法靠谱点。因为他内部都有实现随机方法的逻辑了,应该非常准确的。

第五、工具使用经验总结

到这里我们就借助了icodetools工具打印的日志信息来快速定位到我们想要hook的方法,从整个过程来看比我们之前操作那是方便了多了,但是这里还是需要借助一些经验值,比如猜想是不可少的,摇塞子猜拳应该是随机的,而且有这样一个方法返回随机之后的值,一般是int类型的,所以我们就加上日志过滤规则了,减少日志信息量。在得到了日志信息之后,对于有些方法凭借经验值就可以断定没有任何关系的就可以过滤了。对于可以的方法一定要做记录,然后依次在借助Jadx去查看代码实现,从代码实现逻辑在分析是否有关系。没有的话可以进行过滤了。所以从这里可以看到我们凭借着经验值,做了好几次过滤操作:

第一次过滤:猜想摇塞子猜拳应该是借助一个随机方法得到随机值,方法返回值应该是int类型,这样就过滤了大量的日志信息,便于后续分析日志信息了。

第二次过滤:通过查看日志信息中方法的包名和方法名可以断定有些方法肯定和我们想要的没任何关系。

第三次过滤:通过查看具体方法的代码实现,可以断定和我们想要的逻辑没有任何关系。

通过上次的几层过滤之后,我们可能还是有多个方法比较可疑,这时候就可以借助Xposed进行hook了,可以把这些可疑方法全部hook一遍,反正有没有多大难度,然后在通过触发逻辑查看hook之后的信息。在找到匹对的对应方法就好。如果有多个方法都匹对上了,那么这时候就需要看个人了,既然hook正确了,用哪个方法操作没有任何影响了。

 

三、利用工具快速定位应用校验方法

第一、收集日志信息

上面的那个例子中我们借助了icodetools工具快速定位到我们想要的hook方法点了,下面咋们继续看另外一个场景,就是现在有些app为了防止破解,加了一些防护策略,关于Android中应用的防护策略,不了解的同学可以看这篇文章:Android中安全防护策略分析。下面就来分析一款app的签名校验防护功能,首先不多解释,先去搞一个apk,然后放到icodetools目录下,然后改成src.apk,继续运行脚本icodetools_1.0.bat文件。具体操作步骤和上面处理微信一样,但是这里有个不同的地方,因为我们是想找签名校验方法,一般签名校验方法都是在程序启动的时候,如果发现签名不对就立马退出程序了,所以这里开始的时候就需要打开日志开关:echo “-s 1” >log.txt,依然在/data/local/tmp目录下运行即可,然后点击程序,这时候会发现程序起不来的,因为有签名校验逻辑,肯定启动不起来。但是我们已经收集了日志了:adb logcat -s jw >D:\loginfo.txt。

第二、分析日志信息

接下来就开始分析日志信息了:

这个方法比较可以,从命名上可以看到这个BaseApplication类应该是应用的入口Application类的基准类,可能在静态代码块中有校验功能,所以先记录一下这个类。继续往下看:

在上面那个BaseApplication基准类的静态代码块中调用了asz类的方法了,所以这里先记录asz类信息,继续往下看:

这里又有一个ShuqiApplication类,这个应该就是程序的入口Application类了,记录信息,继续往下看:

这里还是ShuqiApplication的attachBaseContext方法,这个时机也是应用启动比较早的。先记录一下,继续往下看:

在ShuqiApplication的onCreate方法,这个时机也是应用启动比较早的,先记录下,继续往下看:

依然是是这些在ShuqiApplication的onCreate方法中的一些其他方法调用。都记录一下。

到这里大致分析完了日志信息,其实有很多其他信息,但是那些和我们想要的结果没有任何关系,比如拆包功能的类信息multidex,定时上报功能等,限于篇幅原因这里也就不多介绍了。

第三、分析可疑方法代码

上面记录了几个方法,其实我们可以看到,主要就三个时机:

第一个时机:应用Application的静态代码块处,那里有几个方法比较可疑:asz.dy方法。

第二个时机:应用Application的attachBaseContext方法。内部暂时没看到可疑方法。

第三个时机:应用Application的onCreate方法,他内部有几个方法比较可疑:avo类的初始化方法,bhw.cv方法等。

所以从这里可以看到,一般应用的签名校验方法大部分可能存在这三个时机的地方。以后如果发现应用有验证操作的话,可以直接看这三个时机地方代码即可。下面咋们就用Jadx打开apk,一次来看这些地方:

第一个:com.shuqi.android.app.BaseApplication

通过查看源码发现,这个类并没有太多的逻辑,可以忽略了。

第二个:com.shuqi.application.ShuqiApplication静态代码

这里也没发现啥校验逻辑,可以忽略了。

第三个:com.shuqi.application.ShuqiApplication的attachBaseContext方法

这里看到只有一些统计上报代码和处理多dex的,唯一有点可疑的是aw.y代码,可以点进去看看:

从代码逻辑来看,应该是处理多dex加载的逻辑,所以被深度混淆了。应该和签名校验没关系。忽略。

第四个:com.shuqi.application.ShuqiApplication的onCreate方法

从上面的日志记录方法信息来看,avo类的初始化,bhw.cv方法等信息,所以这里最可疑了,但是我们会发现在bhw.cv方法之后就没有再多的日志信息了:

从代码来看,理论上应该还有后面awp.tY方法的日志,所以这里很有可能是bhw.cv方法之后直接退出程序了。我们可以进入bhw.cv方法进行查看:

第四、验证结果

查看之后就眼睛一亮,果然这里做了签名校验,签名不对就直接自杀退出程序了。所以咋们就算是找到这个校验方法了,那么下面就简单了,直接把这个方法注释就好了。关于怎么注释这个方法那就简单了,反编译成smali文件,找到ShuqiApplication的onCreate方法中的bhw.cv直接注释即可,然后在回编译就可以正常运行程序了。

第五、经验总结

到这里咋们就利用了icodetools工具找到应用的签名校验方法了,从上面的分析过程其实我们总结了一些处理校验方法的经验,

第一:一般校验时机都比较早,主要是在应用的Application的静态代码块,attachBaseContext方法,onCreate方法。所以可以直接去这三个时机地方查看代码逻辑。

第二:签名校验失败时候程序会退出,也就是程序的方法不会再执行了,我们插入的日志信息就会断了,那么我们可以直接去日志信息看最后几条方法堆栈信息,可以快速定位到签名校验方法,比如本例中的日志信息中最后一个方法就是签名校验方法。

 

四、工具使用经验概况

以上就分析完了两个案例,详细的介绍了如何利用icodetools工具来进行破解工作,从整个流程来看非常方便。但是也是需要借助一些经验才能更好的使用这个工具。下面就通过这两个例子的分析结果总结使用工具进行破解的时候需要哪些经验值:

第一个:在打印日志的时候需要注意的是如果想找到一些app的hook点方法,我们需要在触发这个hook点逻辑之前最好是关闭日志,等要触发这个hook点逻辑时在打开日志。

第二个:对于hook点还是前期要有猜想操作,能够做第一次日志过滤,比如方法的返回类型,参数类型等。

第三个:对于日志信息分析的时候需要仔细观察哪些方法适合我们本次想要的结果有关系的,没有关系的直接忽略。

第四个:在分析日志之后得到一些可疑方法,我们可以直接把这些方法都hook一遍,然后在此运行应用触发hook点,查看我们hook日志信息,如果有多个方法都被触发了,那么此刻就要看个人了,选择任何一个方法都可以进行操作了,但是如果可以借助每个方法的源码逻辑来抉择具体方法那是最好了。

第五个:对于一些应用有应用校验功能(现象一般是重签名之后运行程序失败),我们开始启动程序之前就得打开日志信息,因为我们得收集更早的信息。

第六个:在有校验功能的app中,他们一般都是验证失败就退出程序了,进而后面的程序代码中的方法就不执行日志也就断了,所以我们可以从日志信息的最后几条记录来快速定位关键方法。

特此说明

到这里关于icodetools工具就介绍差不多了,从原理解析,再到完善,最后在实践。相信即使这个工具有人觉得没多大用,但是从原理中或许可以得到一些知识点,当然个人觉得此工具还是很有用的,因为我们现在看到的只是添加日志,其实这里还隐藏一个功能,就是可以随意插入自己想要的代码逻辑,就是在JWUtils类中自己定义方法,然后在脚本中设置方法即可,比如现在想在源apk中指定类的指定方法中加上下载我们自己应用的代码,这里就好办了。首先我们可以通过开关控制指定类名和方法名即可,然后自己写下载apk的逻辑即可。这样是否可以给自己apk导量呢?

后期还会继续优化,通过这几天用户使用者反馈意见,主要优化如下:

1、工具平台兼容,后续得继续兼容Linux和OS X系统。

2、关于脚本命令参数可以简化,没必要那么多参数设置,比如aapt路径等。

3、这个最重要,也是用户反馈的需求,就是如果能够打印方法的参数值就好了,这个后续会通过在JWUtils类中的方法printStackTrace的参数传递需要打印方法的所有参数值。

工具下载地址:https://github.com/fourbrother/icodetools

 

五、总结

我相信每个工具的出现都有它的特定需求,当工具出来了,最重要的就是能够经得起用户的实际测试,遇到一些问题是在所难免的,所以还是那句话,在使用的过程中如果发现一些问题和建议一定记得给我反馈,我会进行问题修复。关于反馈渠道可以通过加我微信或者留言公众号都可以。最后还要说明一下,就是这个工具的源码暂时先不开源,因为现在这个工具个人觉得还不是很稳定,肯定还有很多问题,想通过大家在使用过程中给我的反馈我进行一段时间的修复之后,稳定了我就会开源。谢谢大家的支持,文章写得我精力充沛,但是还是感觉身体感觉被掏空了一样,所以还是得要你们的多多点赞,打赏来给我安慰!!

《Android应用安全防护和逆向分析》

点击立即购买:京东  天猫

更多内容:点击这里

关注微信公众号,最新技术干货实时推送

扫一扫加小编微信
添加时注明:“编码美丽”否则不予通过!

转载请注明:尼古拉斯.赵四 » Android逆向之旅—利用icodetools工具快速定位App破解中关键点方法

喜欢 (19)or分享 (0)
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(1)个小伙伴在吐槽
  1. 挺好的,祝你快乐
    三五营销2016-12-15 15:38 回复