本帖最后由 王旭东 于 2015-1-8 11:15 编辑
图片在10楼和11楼。现在弄的太吃力。 所以把完整word文档上传到附件。有需要的就去下载吧、 对不起大家了。 一直忙于工作。 请见谅 下载好的附件,把part1加压出来。1和2放在一个文件夹。之后解压出来的word文档就是了
word文档密码:wangxudong或者是大写的:WANGXUDONG
对于一个新手,这道题目怎么解吧,甚至连ARM汇编都不需要掌握,只要了解一些APK和调试的基础知识就行了。程序下载附在最后
需要的工具呢,android sdk全套是必须的。因为这apk一装进我手机里面就各种崩溃,所以需要一个Android4.0以上的虚拟机,配套的DDMS,Java环境等,就不多说了。然后IDA,需要一些Android调试的知识,知道ARM中函数调用的概念和形式,OK,可以开工了。
1. 拿到APK的第一件事,习惯性地解压缩,看看里面的文件:
注意到classes.dex文件大小只有1KB,就应该猜到关键点不是Java代码了,那就肯定是在lib里面实现了动态加载。
2. 动态跑一下程序,发现界面很普通,就是输入一个密码,然后点登陆。打开monitor(sdk/tools/monitor<.bat>)会发现有很多debug信息(放水?)
发现整个流程已经写得非常明白了。抓住其中的一些重点例如:
3. 现在,打开IDA,设置Android调试环境,Attach到com.ali.encryption进程上面去,在libmobisec.so加载时断下来(如果不会的话,请参照http://bbs.pediy.com/showthread.php?t=178659),然后在Hex View里面按g,输入前面看到的0xaa3c9008,敲回车,看到了什么?
dex.035,标准的dex文件头有木有,这时候相信很多人都会选择把dex dump出来吧。文件起始位置找到了,大小在文件头里面有
长度是0x19cf4。接下来按shift+F2,写一段dump脚本
点击Run,dump.dex到手。
4. 当然,如果这个这么简单也就没有写这些的必要了。用baksmali反编译,会出现一堆错误信息
到此就卡住了。让我们回过头来仔细看看上面这些应该如何分析的。
5. 回到最初的logcat信息,我们仔细来分(xia)析(cai)一下解密流程:
第一步是这些。根据log可以看出,关键函数式parse_dex,第一次dex magic是乱码,之后有一些解密和解压信息,第二次的dex magic就是正常的dex035了。由此可以确定,如果在magic正常之后,进行内存dump,就能获得一个dex文件。过程就不多说了,会点调试的人,配合IDA神奇的F5功能,查找字符串,然后查找引用,或者直接从导出表里面找到parse_dex函数,进行分析。应该就能dump出dex文件来,但是该dump文件反编译之后,发现没有任何有用的代码,所有代码都是RuntimeException的形式。
声明:本图盗自万抽抽的<ALICTF2014 evilAPK400完整脱壳分析>译文,链接:http://bbs.pediy.com/showthread.php?t=192836,个人懒得再做一遍了,如果侵权,请作者联系我删除。:)
6. 然后继续看logcat的输出
这里看到一个dex_juicer_patch的函数,pacth啊,一看到这个单词,就知道,肯定是关键了。然后动态调试dex_juicer_patch函数,发现0xAA3C9008是parse_dex里面存放解密后dex的内存首地址,dex_juicer_patch的内容就是对dex内存空间做了系(x)列(x)操(o)作(o)。过程如果不是对ARM很熟的童鞋,估计看到就头大。在这里就不细说了。
7. 继续看logcat,发现之后的操作,就是一些替换app,加载新dex的操作了,没有什么值得注意的。
8. 到此,应该发现dex_juicer_patch函数是重点中的重点,但是看不懂ARM汇编,该怎么办呢?其实前面说了,dex_juicer_patch是对内存0xAA3C9008的操作,那么等dex_juicer_patch执行完了,0xAA3C9008处的内存是不是就是修复后的dex文件呢?
话不多说,在dex_juicer_patch运行结束,返回前执行之前dump脚本,把内存dump出来。然后用baksmali反编译看看。
然后。。。。。。就回到了第4步的结论,反编译各种错误。不过相比于都是RuntimeException有进步。
9. 大结局
其实做为一个新手,做到这一步就差不多了,后续内容,要么有很强的实力,要么有很强的运气。都没有的话会比较蛋疼,例如me。
过程就不啰嗦了,结论就是,分析dex文件,可以发现里面很多指针指向了文件末尾以外。那么就可以猜测出来,dex文件头的文件长度并不是patch之后真正的文件长度,那么只要扩大这个值,把完整的dex文件dump出来就行了。
个人的方法呢,就是从0xAA3C9008 + 0x19CF4处开始往下找,找到下一段全是0的内存区,然后从0xAA3C9008到全是0的内存区dump出来。因为全0一般表示分割,可以用来大概区分数据段,如果一次不行的话,就继续往后找下一段。
最后贡献一下dump代码:
反编译的结果:
最后的dex破解,就不关我的事了,有兴趣的童鞋可以自己尝试一下,如果还有难点,欢迎联系我。提示以上都在虚拟机下运行。
10. 总结
总之一句话:大盗不操戈。很多看似很困难的事情,只是因为我们没有想到更优雅的解决办法。
|