前置知识
http://www.wjdiankong.cn/android中的apk的加固加壳原理解析和实现/
http://blog.csdn.net/jiangwei0910410003/article/details/48104581
赛题链接
https://github.com/eternalsakura/ctf_pwn/blob/master/android逆向/jscrack.apk
可能是因为赛题是14年的,有点老了,所以在5.0.1上运行失败,用android 4.4.4就可以运行了。
原理
加固方式
现在市场中加固apk的方式一般就是两种:一种是对源apk整体做一个加固,放到指定位置,运行的时候在解密动态加载,还有一种是对so进行加固,在so加载内存的时候进行解密释放。我们今天主要看第一种加固方式,就是对apk整体进行加固。
当我们发现apk中主要的类都没有了,肯定是apk被加固了,加固的源程序肯定是在本地,一般会有这么几个地方需要注意的:
1、应用程序的asset目录,我们知道这个目录是不参与apk的资源编译过程的,所以很多加固的应用喜欢把加密之后的源apk放到这里
2、把源apk加密放到壳的dex文件的尾部,这个肯定不是我们这里的案例,但是也有这样的加固方式,这种加固方式会发现使用dex2jar工具解析dex是失败的,我们这时候就知道了,肯定对dex做了手脚
3、把源apk加密放到so文件中,这个就比较难了,一般都是把源apk进行拆分,存到so文件中,分析难度会加大的。
破解思路
不管上层怎么加固,最终加载到内存的dex肯定不是加固的,所以这个dex就是我们想要的.
为什么在dvmDexFileOpenPartial下断点就能dump出完全加载到内存的dex?
dalvik虚拟机会把dex文件优化为odex文件,而优化的源代码为
1 | /* |
其中fromzip和preopt都会调用processZipFile先将dex文件提取出来,fromDex则直接调用dvmContinueOptimization优化.
1 | /* |
在extractAndProcessZip中处理zip文件并将dex提取出来,随后调用优化函数
1 | /* |
dvmContinueOptimization函数位于/dalvik/vm/analysis/DexPrepare.cpp文件,其中调用了dvmDexFileOpenPartial.
1 | /* |
dvmDexFileOpenPartial调用了dexFileParse,用来解析内存中优化过或未优化过的dex文件,返回dexFile结构.
所以此时dex文件已经被加载进内存,就可以dump出来了.
1 | /* |
赛题分析
jeb打开apk,查看Manifest
反编译查看源代码
存在的问题
asset目录中的jar文件被处理了,打不开,也不知道处理逻辑
libs目录中的三个so文件,唯一加载了libmobisec.so文件了
所以说被加固的源程序可能存在于so文件,也可能存在于asset文件里。
脱壳
得到libdvm.so文件
adb pull /system/lib/libdvm.so
在dvmDexFileOpenPartial下断点
IDA attach并断下
adb shell am start -D -n com.ali.tg.testapp/.MainActivity
dvmDexFileOpenPartial函数的第一个参数就是dex内存起始地址,第二个参数就是dex大小。
R0:0x753EF008
R1:0x000941FC
dump脚本
1 | import idaapi |