[转]很重要的方法论 Android逆向之旅---静态分析技术来破解Apk

分类:
 
 

1、前言

从这篇文章开始咱们开始咱们的破解之路,以前的几篇文章中咱们是如何讲解怎么加固咱们的Apk,防止被别人破解,那么如今咱们要开始破解咱们的Apk,针对于以前的加密方式采用相对应的破解技术,Android中的破解其实大致上能够分为静态分析和动态分析,对于这两种方式又能够细分为Java层(smail和dex)和native层(so)。因此咱们今天主要来说解如何经过静态分析来破解咱们的apk,这篇文章咱们会经过破解Java层和native层的例子来说解。android

 

2、准备工做

在开始今天的文章以前,咱们须要准备点东西,程序员

第1、首先是基本知识:算法

一、了解android中的Apk文件的结构。shell

二、了解Smail语法和dex文件格式安全

三、apk的签名机制微信

关于这三个知识点,这里就不作详细介绍了,不理解的同窗能够自行网上学习,有不少资料讲解的。数据结构

第2、再者就是几个重要的工具微信开发

一、apktool:反编译的利器

二、dex2jar:将dex转化成jar

三、jd-gui:很好的查看jar文件的工具

四、IDA:收费的最全破解利器(分析dex和so均可以)

下载地址:http://pan.baidu.com/s/1hqBC7Es

额外:上面四个工具是最基本的,可是如今网上也有一些更好的工具:JEB,GDA等。可是这些工具就是丰富了上面四个工具,因此说咱们只要上面的四个工具就足够了。IDA工具我专门给了一个下载地址,其余的工具在咱们提供的案例中。

 

3、技术原理

准备工做完了,下面就来看一下今天的破解方式介绍:

Android中的破解的静态分析说重要,也不重要,为何这么说呢?

由于咱们到后面会介绍动态分析,那时候咱们在破解一个Apk的时候,发现静态分析的方式几乎毫无用途,由于如今的程序加固的愈来愈高级,静态分析几乎失效,因此动态分析是必须的,可是要是说静态分析没有用,那么也错了,由于咱们在有些场景下,只有静态分析可以开始破解之门,没有静态分析以后的结果,动态分析是没法开展的。这个下面会举例说明。因此说在破解的过程当中,静态分析和动态分析必定会结合在一块儿的,只有这样咱们才会一往无前。下面就来看看咱们如何经过静态分析来破解apk.

第1、静态分析的流程

一、使用apktool来反编译apk

在这个过程当中,咱们会发现有些apk很轻易的被反编译了,可是有些apk每次反编译都会报各类错误,这个也是正常的,由于加固了吗。如今网上有不少对apk加密的方式,直接让反编译就通不过,好比Androidmanifest文件,dex文件等,由于apktool他须要解析这些重要的资源,一旦这些文件加密了那么就会终止,因此这里咱们暂且都认为apk都能反编译的,由于咱们今天是主要介绍怎么经过静态分析来破解,关于这里的反编译失败的问题,我后面会在用一篇文章详细介绍,到时候会列举一些反编译错误的例子。

 

二、获得程序的smail源码和AndroidManifest.xml文件

咱们知道一个Android的程序入口信息都会在AndroidManifest.xml中,好比Application和入口Activity,因此咱们确定会先来分析这个文件,找到咱们想要的信息,固然这里还有一个经常使用的命令须要记住:

adb shell dumpsys activity top

可以获取到当前程序的Activity信息

而后咱们会分析smail代码,进行代码逻辑的修改

 

三、直接解压apk文件获得classes.dex文件,而后用dex2jar工具获得jar,用jd-gui工具查看

这里咱们主要很容易的查看代码,由于咱们在第二步中获得了smail源码,就能够分析程序了,可是咱们知道虽然smail语法不是很复杂,至少比汇编简单,可是怎么看着都是不方便的,仍是看java代码比较方便,因此咱们借助jd-gui工具查看代码逻辑,而后在smail代码中进行修改便可,上面说到的JEB工具,就增强了jd-gui工具的功能,它能够直接将smail源码翻译成java代码,这样咱们就不须要先用jd-gui工具查看,再去smail源码中修改了,借助JEB便可。

四、若是程序中有涉及到native层的话,咱们能够用IDA打开指定的so文件。咱们仍是须要先看java代码,找到指定的so文件,在用IDA来静态分析so文件。

 

第2、用到的技术

上面介绍了静态分析的流程,下面来看一下静态分析的几个技术,咱们在静态分析破解Apk的时候,首先须要找到突破点,找到关键的类和方法,固然这里就须要经验了,不是有方法可循的。可是咱们会借助一些技术来加快破解。

一、全局查找关键字符串和日志信息

这个技术彻底靠眼,咱们在运行程序以后,会看到程序中出现的字符串,好比文本框,按钮上的文本,toast显示的信息等,均可能是重要信息,而后咱们能够在jd-gui工具中全局搜索这个字符串,这样就会很快的定位到咱们想要找的逻辑地方:


固然咱们还有一个重要点就是Android中的Log信息,由于在一个大的项目中,会有多人开发,因此每一个模块每一个人开发,每一个人都会调试信息,因此就会添加一些log信息,可是不是全部的人都会记得在项目发布的时候关闭项目中的全部log信息,这个也是咱们在项目开发的过程当中很差的习惯。这时候咱们就能够经过程序运行起来以后,会打印一些log信息,那么咱们能够经过这些信息获取突破点,Android中的log能够根据一个应用来进行过滤的,或者咱们能够经过log信息中的字符串在jd-gui中进行全局搜索也是能够的。

 

二、代码的注入技术

在第一种方式中咱们经过全局搜索一些关键的字符串来找突破点,可是这招有时候很差使,因此这时候咱们须要加一些代码了来观察信息了,这里有一个通用的方法就是加入咱们本身的log代码,来追踪代码的执行逻辑,由于这里讲的是静态分析技术,因此就用代码注入技术来跟踪执行逻辑,后面介绍了动态分析技术以后,那就简单了,咱们能够随意的打断点来进行调试。这里的添加代码,就是修改smail代码,添加咱们的日志信息便可,在下面咱们会用例子来进行讲解,这个也是咱们最经常使用的一种技术。

 

三、使用系统的Hook技术,注入破解程序进程,获取关键方法的执行逻辑

关于Android中的进程注入和Hook技术,这里就不作详细介绍了,不了解这些技术的同窗能够转战:

注入技术:http://blog.csdn.net/jiangwei0910410003/article/details/39292117

Hook技术:http://blog.csdn.net/jiangwei0910410003/article/details/41941393

这两篇文章介绍了这两项技术,可是咱们在实际操做过程当中不用这两篇文章中用到的方式,由于这两篇文章只是介绍原理,技术还不是很成熟,关于这两个技术,网上有两个框架很成熟,也很实用,就是人们熟知的:Cydia和Xposed,关于这两个框架的话,网上的资料太多了,并且用起来也很容易,这里就不作太多的详细介绍了。

咱们在实际的破解的过程当中,这种方式用的有点少,由于这种方式效率有点低,因此只有在特定的场景下会使用。

 

四、使用IDA来静态分析so文件

这里终于用到了IDA工具了,本人是感受这个工具太强大了,他能够查看so中的代码逻辑,咱们看到的的多是汇编指令,因此这里就有一个问题了,破解so的时候,咱们还必须掌握一项技能,就是能看懂汇编指令,否则用IDA来破解程序,会很费经的,关于汇编指令,大学的时候,咱们接触过了,可是咱们当时感受这东西又难,并且用的地方也不多,因此就没太在乎,其实否则呀,真正懂汇编的人才是好的程序员:


看到些汇编指令,头立马就大了,不过这个用多了,破解多了,仍是能够的。咱们能够看到左边栏中有咱们的函数,咱们能够找到指定函数的定义的地方进行查看便可。其实IDA最强大的地方是在于他动态调试so文件,下一篇文章会介绍怎么动态调试so文件。固然IDA可也是能够直接查看apk文件的:


能够查看apk文件中的全部文件,咱们能够选择classes.dex文件:


可是这里咱们可能会遇到一个问题,就是若是应用程序太大的话,这个打开的过程当中会很慢的,有可能IDA中止工做,因此要慢慢等啦:


打开以后,咱们能够看到咱们的类和方法名,这里还能够支持搜索类名和方法名Ctrl+F,也能够查看字符串内容(Shirt+F12):


咱们发现IDA也是一个分析Java代码的好手,因此说这个工具太强大了啦啦~~

 

4、案例分析

上面讲解了静态分析的破解技术,那么下面就开始使用一个例子来看看静态分析的技术。

第1、静态分析Java(smail)代码

首先咱们拿到咱们须要破解的Apk,使用apktool.jar工具来反编译:

java -jar apktool.jar d xxx.apk


这个apk非常容易就被反编译了,看来并无进行任何的加固。那就好办了,咱们这里来改一下他的AndroidManifest.xml中的信息,改为可调式模式,这个是咱们后面进行动态调试的前提,一个正式的apk,在AndroidManifest.xml中这个值是false的。

咱们看看他的AndroidManifest.xml文件:


咱们把这个值改为true.在回编译,这时候咱们就能够动态调试这个apk了,因此在这点上咱们能够看到,静态分析是动态分析的前提,这个值不修改的话,咱们是办法进行后续的动态调试的。

修改为功以后,咱们进行回编译:

cd C:\Users\jiangwei\Desktop\静态分析\apktool_2.0.0rc4
del debug.sig.apk
java -jar apktool.jar b -d 123 -o debug.apk
java -jar .\sign\signapk.jar .\sign\testkey.x509.pem .\sign\testkey.pk8 debug.apk debug.sig.apk
del debug.apk
adb uninstall com.shuqi.controller
adb install debug.sig.apk
adb shell am start -n com.shuqi.controller/.Loading
pause

这里是为了简单,写了一个批处理,首先进入到目录,而后使用命令进行回编译:

java -jar apktool.jar b -d sq -o debug.apk

sq是以前反编译的目录,debug.apk是回编译以后的文件

这时候,debug.apk是不能安装运行的,由于没有签名,Android中是不容许安装一个没有签名的apk

下面还要继续签名,咱们用系统自带的签名文件便可签名:

java -jar .\sign\signapk.jar .\sign\testkey.x509.pem .\sign\testkey.pk8 debug.apk debug.sig.apk

注:其实咱们在用IDE工具开发android项目的时候,工具就是用这个签名文件进行签名的,只是这个过程IDE帮咱们作了。

后面就是直接安装这个apk,而后运行这个Apk。这个过程当中咱们只须要知道应用的包名和入口Activity名称便可,这个信息咱们在AndroidManifest.xml中也是能够获取到的,固然咱们用:adb shell dumpsys activity top 命令也能够获得:


回编译以后,咱们运行程序,发现有问题,就是点击程序的icon,没反应,运行不起来,咱们在查看log中的异常信息,发现也没有抛出任何异常,那么这时候,咱们就判断,他内部确定作了什么校验工做,这个通常回编译以后的程序运行不起来的话,那就是内部作校验了,通常作校验的话,有两种:

一、对dex作校验,防止修改dex的

二、对apk的签名作校验,防止从新打包

那咱们就须要重新看看他的代码,来看看是否是作了校验:

咱们在分析代码的时候,确定先看看他有没有本身定义Application,若是有定义的话,就须要看他本身的Application类,这里咱们看到他定了本身的Application:com.shuqi.application.ShuqiApplication

咱们解压apk,获得dex,而后dex2jar进行转化,获得jar,再用jd-gui查看这个类:


这里咱们看到他的代码作混淆了,可是一些系统回调方法确定不能混淆的,好比onCreate方法,可是这里咱们通常找的方法是:

一、首先看这个类有没有静态方法和静态代码块,由于这类的代码会在对象初始化以前运行,可能在这里加载so文件,或者是加密校验等操做

二、再看看这个类的构造方法

三、最后再看生命周期方法

咱们这里看到他的核心代码在onCreate中,调用了不少类的方法,猜测这里的某个方法作工做了?

这时候咱们就来注入咱们的代码来跟踪是哪一个方法出现问题了,这里有的同窗有疑问,其实就这几个方法,直接一个一个看不就结了,哎,咱们这篇文章就是要介绍静态分析技术,固然就须要作案例啦。

下面来看看咱们怎么添加咱们的日志信息,其实很简单,就是添加日志,须要修改smail文件,咱们在去查看smail源码:


关于smail语法,本人认为不是很难,因此你们本身网上去搜一些资料学习一下便可,这里咱们能够很清晰的看到调用了这些方法,那么咱们就在每一个方法加上咱们的日志信息,这里加日志有两种方式,一种就是直接在这里调用系统的log方法,可是有两个问题:

一、须要导入包,在smail中修改

二、须要定义一个两个参数,一个是tag,msg,才能正常的打印log出来

明显这个方法有点麻烦,这里咱们就本身定义一个MyLog类,而后反编译,获得MyLog的smail文件,添加到这个ShuqiApplication.smail的root目录下,而后在代码中直接调用便可,至于为什么要放到root目录下,这样在代码中调用就不须要导入包了,好比SuqiApplication.smail中的一些静态方法调用:


编写日志类MyLog,这里就不粘贴代码了,咱们新建一个项目以后,反编译获得MyLog.smail文件,放到目录中:


咱们获得这个文件的时候,必定要注意,把MyLog.smail的包名信息删除,由于咱们放到root目录下的,意味着这个MyLog类是没有任何包名的,这个须要注意,否则最后加的话,也是报错的。

咱们在ShuqiApplication的onCreate方法中插入咱们的日志方法:

invoke-static {}, LMyLog;->print()V


可是咱们在加代码的时候,须要注意的是,要找对地方加,所谓找对地方,就是在上个方法调用完以后添加,好比:

invoke-virtual,invoke-static等,并且这些指令后面不能有:move-result-object,由于这个指令是获取方法的返回值,因此咱们通常是这么加代码的:

一、在invoke-static/invoke-virtual指令他的返回类型是V以后能够加入

二、在invoke-static/invoke-virtual指令返回类型不是V,以后的move-result-object命令以后能够加入

 

加好了咱们的日志代码以后,下面咱们就回编译执行,在这个过程可能会遇到samil语法错误,这个就对应指定的文件修改就能够了,咱们获得回编译的apk以后,能够在反编译一下,看看他的java代码:


咱们看到了,咱们添加的代码,在每一个方法以后打印信息。

下面咱们运行程序,同时开启咱们的log的tag:adb logcat -s JW


看到咱们打印的日志了,咱们发现打印了三个log,这里须要注意的是,这里虽然打印了三个log,可是都是在不一样的进程中,因此说一个进程中的log的话,只打印了一个,因此咱们判断,问题出如今VR.h这个方法

咱们查看这个方法源码:


果真,这个方法作了签名验证,不正确的话,直接退出程序。那么咱们如今要想正常的运行程序的话,很简单了,直接注释这行代码:vr.h(this)

而后回编译,在运行,果真不报错了,这里就不在演示了:


好了,上面就经过注入代码,来跟踪问题,这个方法是很经常使用,也是很实在的。

 

第2、静态分析Native代码

下面继续来介绍一下,如何使用IDA来静态分析native代码,这里必定要熟悉汇编指令,否则看起来很费劲的。

咱们在反编译以后,看到他的onCreate方法中有一个加载so的代码

看看这个代码:

获取密码的方法,是native的,咱们就来看看那个getDbPassword方法,用IDA打开libpsProcess.so文件:


咱们看看这个函数的实现,咱们通常直接看BL/BLX等信息,跳转逻辑,还有就是返回值,咱们在函数的最后部分,发现一个重点,就是:BL __android_log_print  这个是在native层调用log的函数,咱们在往上看,发现:tag是System.out.c

咱们运行程序看起log看看,可是咱们此时也能够在java层添加日志的:咱们全局搜索这个方法,在yi这个类中调用的


咱们修改yi.smail代码:


回编译,在运行程序,开启log:

adb logcat -s JW

adb logcat -s System.out.c


发现,返回的密码java层和native层是同样的。说明咱们静态分析native仍是有效的。

 

好了,到这里咱们今天的内容就介绍完了,固然还有不少静态分析apk的方法,这里只是介绍了本人用到的技术。

 

案例下载:http://download.csdn.net/detail/jiangwei0910410003/9308217

案例中有个说明文件,运行前请阅读~~

 

5、未解决的问题

一、如何搞定apktool工具反编译出错的问题

这个我在开始的时候也说了,这里出错的缘由大部分是apk进行加固了,因此后面我会专门介绍一下如何解决这样的问题

二、如何搞定让一个Apk能够调试

咱们在上面看到一个apk想要能调试的话,须要修改android:debug的值,可是有时候,咱们会遇到修改失败,致使程序不能运行,后面会专门介绍有几种方式来让一个发布后的apk能够调试

 

6、技术总结

这篇文章咱们介绍了如何使用静态方式去破解一个apk,咱们在破解一个apk的时候,其实就是改点代码,而后可以运行起来,达到咱们想要的功能,通常就是:

一、注释特定功能,好比广告展现等

二、获得方法的返回值,好比获取用户的密码

三、添加咱们的代码,好比加入咱们本身的监测代码和广告等

咱们在静态分析代码的时候,须要遵循的大致路线:

一、首先可以反编译,获得AndroidManifest.xml文件,找到程序入口代码

二、找到咱们想要的代码逻辑,通常会结合界面分析,好比咱们想得让用户登陆成功,咱们确定想要获得用户登陆界面Activity,这时候咱们能够用adb shell dumpsys activity top命令获得Activity名称,而后用Eclipse自带的程序当前视图分析工具:获得控件名称,或者是在代码中获取layout布局文件,通常是setContentView方法的调用地方,而后用布局文件结合代码获得用户登陆的逻辑,进行修改

三、在关键的地方经过代码注入技术来跟踪代码执行逻辑

四、注意方法的返回值,条件判断等比较显眼的代码

五、对于有些apk中的源码,可能他有本身的加密算法,这时候咱们须要获取到这个加密方法,若是加密方法比较复杂的话,咱们就须要大批的测试数据来获取这个加密方法的逻辑,通常是输入和输出做为一个测试用例,好比阿里安全第一届比赛的第一题就能够用静态分析的方式破解,它内部就是一个加密算法,咱们须要用测试数据来破解。

六、对于那些System.loadLibrary加载so文件的代码,咱们只须要找到这个so文件,而后用IDA打开进行静态分析,由于有些apk中把加密算法放到了so中了,这时候咱们也能够经过测试数据来获取加密算法。

七、经过上面的例子,咱们能够总结一个方式,就是如今不少apk会作一些校验工做,通常在代码中包含:“signature”字符串信息,因此咱们能够全局搜索一下,也许能够获取一些重要信息。

 

6、总结

这篇文章总算是讲解完了,其实早就想用写破解的文章了,由于破解比加固有意思,至少破解成功了有成就感。这篇文章主要介绍了如何经过静态分析方式破解,介绍了一些工具的时候,破解流程和破解技巧。最经常使用的就是代码注入技术和全局搜索关键字符串等方式,可是咱们能够看到,如今市面上的不少apk,光经过静态分析是没法知足咱们的破解需求了,因此动态分析方式就来了,并且动态方式破解难度会很大,须要掌握的东西也不少,我后面会分几篇文章来一一介绍动态破解的技巧和常见的问题。可是静态方式破解也是很重要的。固然也是动态分析的前提,因此咱们既然玩破解,那么这两种技术都必须很好的掌握。

 

 

PS: 关注微信,最新Android技术实时推送

 

 

 
11
0
 
 
 

 

 
猜你在找
【直播】机器学习&深度学习系统实战(唐宇迪)
【直播】Kaggle 神器:XGBoost 从基础到实战(冒教授)
【直播回放】深度学习基础与TensorFlow实践(王琛)
【直播】计算机视觉原理及实战(屈教授)
【直播】机器学习之凸优化(马博士)
【直播】机器学习之矩阵(黄博士)
【直播】机器学习之几率与统计推断(冒教授)
【直播】机器学习之数学基础
【直播】TensorFlow实战进阶(智亮)
【直播】深度学习30天系统实训(唐宇迪)

 

 

查看评论
9楼 老大鱼头 2016-01-09 18:00发表 [回复]
受教了受教了。博主很是强大,已关注。
我补充一小点,IDA Pro其实还能够再反编译汇编代码,生成C代码,那样能看得更加清楚一点。
反编译单个函数是F5,反编译整个文件是用File -> Produce File -> Create C File.须要安装Hex-Rays Decomplier而且有受权。
8楼 XXOOYC 2015-12-25 23:59发表 [回复]
能不能再顺便往下讲点如何修改so的文章
7楼 jltxgcy 2015-12-10 09:35发表 [回复]
已投票,期待更多关于android破解,防破解,安全方面的文章!
Re: 尼古拉斯_赵四 2015-12-10 09:37发表 [回复]
回复jltxgcy:谢谢。。后续还有呕心之做:动态分析技术破解
Re: jltxgcy 2015-12-12 09:19发表 [回复]
回复尼古拉斯_赵四:哈哈,加油,每日一票。
6楼 苗景磊 2015-12-03 14:58发表 [回复]
很不错,但愿楼主多写一些这类的博客
5楼 boy_nihao 2015-12-01 14:07发表 [回复]
值得收藏
4楼 乡下程序员 2015-11-30 23:25发表 [回复]
屌屌的飞起来~
3楼 傻丫头与科技 2015-11-30 19:24发表 [回复]
感谢楼主的分享,学习了!!
2楼 taanniu1 2015-11-30 14:37发表 [回复]
收藏了
1楼 牛迁迁 2015-11-28 18:56发表 [回复]
高大上的博客,顶。
 
该文章已被禁止评论!
* 以上用户言论只表明其我的观点,不表明CSDN网站的观点或立场
 
 
TOP
相关文章
相关标签/搜索