Android逆向之旅---动态方式破解apk终极篇(加固apk破解方式)

本文详述了如何动态破解加固的Android apk,通过分析案例,展示了如何利用动态调试找到源apk的藏身之处,以及如何通过dump内存中的dex文件,并进一步分析内容。文中涉及的技术包括ida调试、内存dump、dex2jar和smali源码分析,揭示了Android安全防护的破解之道。
摘要由CSDN通过智能技术生成

一、前言

今天总算迎来了破解系列的最后一篇文章了,之前的两篇文章分别为:

第一篇:如何使用Eclipse动态调试smali源码 

第二篇:如何使用IDA动态调试SO文件

现在要说的就是最后一篇了,如何应对Android中一些加固apk安全防护,在之前的两篇破解文章中,我们可以看到一个是针对于Java层的破解,一个是针对于native层的破解,还没有涉及到apk的加固,那么今天就要来介绍一下如何应对现在市场中一些加固的apk的破解之道,现在市场中加固apk的方式一般就是两种:一种是对源apk整体做一个加固,放到指定位置,运行的时候在解密动态加载,还有一种是对so进行加固,在so加载内存的时候进行解密释放。我们今天主要看第一种加固方式,就是对apk整体进行加固。


二、案例分析

按照国际惯例,咋们还是得用一个案例来分析讲解,这次依然采用的是阿里的CTF比赛的第三题:


题目是:要求输入一个网页的url,然后会跳转到这个页面,但是必须要求弹出指定内容的Toast提示,这个内容是:祥龙!

了解到题目,我们就来简单分析一下,这里大致的逻辑应该是,输入的url会传递给一个WebView控件,进行展示网页,如果按照题目的逻辑的话,应该是网页中的Js会调用本地的一个Java方法,然后弹出相应的提示,那么这里我们就来开始操作了。

按照我们之前的破解步骤:

第一步:肯定是先用解压软件搞出来他的classes.dex文件,然后使用dex2jar+jd-gui进行查看java代码


擦,这里我们看到这里只有一个Application类,从这里我们可以看到,这个apk可能被加固了,为什么这么说呢?因为我们知道一个apk加固,外面肯定得套一个壳,这个壳必须是自定义的Application类,因为他需要做一些初始化操作,那么一般现在加固的apk的壳的Application类都喜欢叫StubApplication。而且,这里我们可以看到,除了一个Application类,没有其他任何类了,包括我们的如可Activity类都没有了,那么这时候会发现,很蛋疼,无处下手了。


第二步:我们会使用apktool工具进行apk的反编译,得到apk的AndroidManifest.xml和资源内容



反编译之后,看到程序会有一个入口的Activity就是MainActivity类,我们记住一点就是,不管最后的apk如何加固,即使我们看不到代码中的四大组件的定义,但是肯定会在AndroidManifest.xml中声明的,因为如果不声明的话,运行是会报错的。那么这里我们也分析完了该分析的内容,还是没发现我们的入口Activity类,而且我们知道他肯定是放在本地的一个地方,因为需要解密动态加载,所以不可能是放在网上的,肯定是本地,所以这里就有一些技巧了:

当我们发现apk中主要的类都没有了,肯定是apk被加固了,加固的源程序肯定是在本地,一般会有这么几个地方需要注意的:

1、应用程序的asset目录,我们知道这个目录是不参与apk的资源编译过程的,所以很多加固的应用喜欢把加密之后的源apk放到这里

2、把源apk加密放到壳的dex文件的尾部,这个肯定不是我们这里的案例,但是也有这样的加固方式,这种加固方式会发现使用dex2jar工具解析dex是失败的,我们这时候就知道了,肯定对dex做了手脚

3、把源apk加密放到so文件中,这个就比较难了,一般都是把源apk进行拆分,存到so文件中,分析难度会加大的。

一般都是这三个地方,其实我们知道记住一点:就是不管源apk被拆分,被加密了,被放到哪了,只要是在本地,我们都有办法得到他的。

好了,按照这上面的三个思路我们来分析一下,这个apk中加固的源apk放在哪了?

通过刚刚的dex文件分析,发现第二种方式肯定不可能了,那么会放在asset目录中吗?我们查看asset目录:


看到asset目录中的确有两个jar文件,而且我们第一反应是使用jd-gui来查看jar,可惜的是打开失败,所以猜想这个jar是经过处理了,应该是加密,所以这里很有可能是存放源apk的地方。但是我们上面也说了还有第三种方式,我们去看看libs目录中的so文件:


擦,这里有三个so文件,而我们上面的Application中加载的只有一个so文件:libmobisec.so,那么其他的两个so文件很有可能是拆分的apk文件的藏身之处。

通过上面的分析之后,我们大致知道了两个地方很有可能是源apk的藏身地方,一个是asset目录,一个是libs目录,那么分析完了之后,我们发现现在面临两个问题:

第一个问题:asset目录中的jar文件被处理了,打不开,也不知道处理逻辑

第二个问题:libs目录中的三个so文件,唯一加载了libmobisec.so文件了

那么这里现在的唯一入口就是这个libmobisec.so文件了,因为上层的代码没有,没法分析,下面来看一下so文件:


擦,发现蛋疼的是,这里没有特殊的方法,比如Java_开头的什么,所以猜测这里应该是自己注册了native方法,混淆了native方法名称,那么到这里,我们会发现我们遇到的问题用现阶段的技术是没法解决了。


三、获取正确的dex内容

分析完上面的破解流程之后,发现现在首要的任务是先得到源apk程序,通过分析知道,处理的源apk程序很难找到和分析,所以这里就要引出今天说的内容了,使用动态调试,给libdvm.so中的函数:dvmDexFileOpenPartial 下断点,然后得到dex文件在内存中的起始地址和大小,然后dump处dex数据即可。

那么这里就有几个问题了:

第一个问题:为何要给dvmDexFileOpenPartial 这个函数下断点?

因为我们知道,不管之前的源程序如何加固,放到哪了,最终都是需要被加载到内存中,然后运行的,而且是没有加密的内容,那么我们只要找到这的dex的内存位置,把这部分数据搞出来就可以了,管他之前是如何加固的,我们并不关心。那么问题就变成了,如何获取加载到内存中的dex的地址和大小,这个就要用到这个函数了:dvmDexFileOpenPartial 因为这个函数是最终分析dex文件,加载到内存中的函数:

int dvmDexFileOpenPartial(const void* addr, int len, DvmDex** ppDvmDex);

第一个参数就是dex内存起始地址,第二个参数就是dex大小。

第二个问题:如何使用IDA给这个函数下断点

我们在之前的一篇文章中说到了,在动态调试so,下断点的时候,必须知道一个函数在内存中的绝对地址,而函数的绝对地址是:这个函数在so文件中的相对地址+so文件映射到内存中的基地址,这里我们知道这个函数肯定是存在libdvm.so文件中的,因为一般涉及到dvm有关的函数功能都是存在这个so文件中的,那么我们可以从这个so文件中找到这个函数的相对地址,运行程序之后,在找到libdvm.so的基地址,相加即可,那么我们如何获取到这个libdvm.so文件呢?这个文件是存放在设备的/system/lib目录下的:


那么我们只需要使用adb pull 把这个so文件搞出来就可以了。

  • 10
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
ApkTool』简要介绍 提供1.3.5测试版源码。 此程序在其基础上完善并添加一些功能,此版本号定位2.0 最终版。 定为最终版的原因是支持动态加载最新的内置工具: ..\Bin\*.*目录下的所有工具如果有最新版本的,替换Bin目录内的程序即可应用最新版。 [注意:不要更改目录内的文件名,否则不会被加载。],判断是否使用最新版本的程序, 可以看启动日志中每个文件的路径。日志内容如下: 加载apktool.jar的路径:C:\Users\Owner\Desktop\ApktoolGul\Bin\apktool.jar 加载aapt.exe的路径:C:\Users\Owner\Desktop\ApktoolGul\Bin\aapt.exe 加载signapk.jar的路径:C:\Users\Owner\Desktop\ApktoolGul\Bin\signapk.jar 加载testkey.pk8的路径:C:\Users\Owner\Desktop\ApktoolGul\Bin estkey.pk8 加载testkey.x509.pem的路径:C:\Users\Owner\Desktop\ApktoolGul\Bin estkey.x509.pem 加载baksmali.jar的路径:C:\Users\Owner\Desktop\ApktoolGul\Bin\baksmali.jar 加载smali.jar的路径:C:\Users\Owner\Desktop\ApktoolGul\Bin\smali.jar 加载dex2jar.jar的路径:C:\Users\Owner\Desktop\ApktoolGul\Bin\dex2jar.jar 加载asm-debug-all.jar的路径:C:\Users\Owner\Desktop\ApktoolGul\Bin\asm-debug-all.jar 加载commons-io.jar的路径:C:\Users\Owner\Desktop\ApktoolGul\Bin\commons-io.jar 加载slf4j-simple.jar的路径:C:\Users\Owner\Desktop\ApktoolGul\Bin\slf4j-simple.jar 加载slf4j-api.jar的路径:C:\Users\Owner\Desktop\ApktoolGul\Bin\slf4j-api.jar ============================================================== 华丽的分割线 ============================================================== 使用说明: =========================================================== 使用环境:须安装 java,下载地址:http://www.java.com/zh_CN/ 1、反编译APK 拖拽APK程序到"反编译APK"按钮前的输入区,点击"反编译APK"按钮 2、重建APK 把第一步得到 文件夹 拖拽到"重建APK"按钮前面的输入区,点击"重建APK"按钮, 至此会自动生成已经签名好的"XXOO(已签名).apk" 3、签名 拖拽APK程序到"签名"按钮前的输入区,点击"签名"按钮,自动生成已经签名好的"XXOO(已签名).apk" 4、反编译dex 拖拽dex文件或odex到"反编译dex"按钮前的输入区,点击"反编译dex"按钮, 会在dex文件所在目录外生成一个与dex文件名相同的目录 5、重建dex 拖拽要重建的目录到"重建dex"按钮前的输入区,点击"重建dex"按钮,会生成与目录名相同的dex文件 6、dex转jar 拖拽dex文件或odex到"6、dex转jar"按钮前的输入区,点击"6、dex转jar"按钮, test.dex 会生成 test.dex.dex2jar.jar 文件 7、jar,class转java 拖拽保护class的目录,或.class文件或 jar文件到"jar,class转java"按钮前的输入区,点击"jar,class转java"按钮, 会生成相应的 java文件。 ========================== 内置软件版本: | apktool 1.4.3 | aapt r04 | baksmali 1.3.2 | smali 1.3.2 | dex2jar 0.0.7.9 | asm-debug-all 3.2 | commons-io 2.0 | slf4j 1.5.6 | jad 1.5.8e2 | ========================== ^_^ Enjoy! 2012.3.16 By:漏网之鱼 QQ:530747686
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值