原理篇dvmDexFileOpenPartial这是函数是关键,据说在这下 断点就可以了,看名字就是虚拟机去打开Dexfile的意思,应该那时已经解壳完成了吧
函数原型:
int dvmDexFileOpenPartial(const void* addr, int len, DvmDex** ppDvmDex);
第一个参数就是dex内存起始地址,第二个参数就是dex大小。所以在这个函数下断点可以直接dump出明文dex.
为了深入学习我们去看看安卓源码,这个参考底部有个大神的
http://androidxref.com/4.4_r1/xref/dalvik/dexopt/OptMain.cpp
这个应该是优化dex的,odex相关的东西,小白我不懂的
这里分别对三种不同类型的文件做不同的处理,传进去的参数是--dex就走中间那一步了,我们跟进去
根据log信息,我们知道,显示初始化VM虚拟机(应该是dalvik虚拟机吧)
跟着就执行优化,我们看看那个优化
可以看到上面的英文注释:重写文件,字节重排,结构重排,类验证,字节优化都在那个rewriteDex函数中,优化成功下面才去调用我们的dvmDexFileOpenPartial
可以看到第三个参数为NULL
既然这样,我们继续跟进
可以看到里面调用了dexFileParse,就是解析dex文件的了,既然都开始解析dex文件了,那么壳肯定已经对dex解密完成了,不然也无法解析啊
顺手简单看看是如何解析的,不懂啊 ,只看这两个看着有点眼熟的,因为学过PE文件的格式
可以看到这里也有一些可选头,通过可选头可以读取一些信息,什么长度啊,偏移什么的, 中间有个解析Data的函数,这里是学习脱壳啊,不是看安卓源码,都跑哪去了
接下来还会作一些校验和的检测
好了,我们开始学习脱壳吧
开始我们的脱壳之路一开始来个apk,你不能说一来就脱壳啊,没壳的你脱毛啊
用压缩软件打开我们的学习用的apk,跟着将那个dex拖出来,其实不拖出来也是可以的,因为下面用的软件支持直接拖apk进去
转化成jar(这个软件还是比较好用的,支持文件拖拽)
跟着自动就帮你打开JD-GUI了
全部函数都放到so文件中了,load了一个库mobisec
看到这,就是要脱壳了,就像我们平时win逆向的时候,打开ida,发现只有一个函数
那我们接下来就开始吧
ida的动态调试可以百度哦 ,或者很多安卓安全的书都有了,想得起的话我去写个记录
首先安装,看看,熟悉一下整个应用,应该是输入正确的url,跟着出flag,key啊什么的
对了,还没知道包名,上apktool,解包
看看包名
在手机上运行server
作一下端口转发(应该是本地的端口,转发到adb那边的23946端口吧),当然如果利用局域网调试就不用这一步了
跟着一条是调试模式打开应用的首页
那接着就上ida咯
ok后可以看到我们那个进程了,附加上去
跟着看看模块吧
跟着查找libdvm,这个看名字就知道跟Dalvik虚拟机有个,dvm嘛,优化dex的应该也在里面,我对自己是这么想的
双击点过去,继续查找dvmDexFileOpenPartial
再点过去
F9运行!!!!!
接下来jdb命令动态调试Apk
先打开ddms,可以看到调试端口,还有哪个红虫
JDB是基于文本和命令行的调试工具(例如Sun JDB);虽然现在有一些很好的调试工具,然而 Java 调试器 (JDB) 提供了一些优点。最重要的是 JDB 可以免费获取并且是平台独立的。其缺点是它只有命令行格式,一些开发人员认为这很原始,而且难以使用。一些 IDE 已经将 GUI 界面构建到 JDB 调试 API(如 Jikes)。JDB 是 JDK 安装的一部分。它在 Java 2 平台中得到了增强。
使用jdb命令进行调试时,一般选择8700端口,因为8700是默认的调试端口 都一样的了,没什么特殊,我们可以看到使用的包中有个jdi,这也满足我们的预想
跟着ida就出现这个,取消就好
继续
跟着程序就断下来了
R0是传过来的第一个参数,R1是第二个参数,根据这个函数的原型,所以如下
跟着就用脚本把它dump出来吧
一开始应该就是相当于我们C语言的声明变量,看来那些寄存器我们直接写名字就可以访问了
算了,直接给代码吧
[size=1em][size=1em]?
[size=1em]1
[size=1em]2
[size=1em]3
[size=1em]4
[size=1em]5
| [size=1em][size=1em]auto fp, dex_addr, end_addr;
[size=1em] fp = fopen("C:\\dump.dex", "wb");
[size=1em] end_addr = r0 + r1;
[size=1em] for(dex_addr = r0; dex_addr < end_addr; dex_addr++)
[size=1em] fputc(Byte(dex_addr), fp);
|
点击run
稍等片刻,马上就好
结果发现只有安卓的库(不要急,我就入坑了,这个dex2jar不能用于dump出来的应该,我把上面的步骤至少重复了5遍)
再看看那个地址,确实是个dex文件啊
直接上JEB神器,终于看到了