2015移动安全挑战赛-第3题
链接:http://msc.pediy.com/timu.htm
平台:Android
类型:CrackMe
利用JEB反编译APK后发现只有一个继承Application类的StubApplication类,该类加载了动态库。很明显,dex加壳了,那么在SO里肯定回解壳的,不过SO有反调试和混淆,分析起来比较困难(好吧,至少我不想分析了)。
我注意到在lib/armeabi目录中的libmobisecy.so实际上是一个zip文件,解压后得到一个classes.dex文件,拖到JEB里:
所有的函数实体都被替换成了throw new RuntimeException();注意到的是除了函数实体,其他地方都是正确的,用010的dex模板解析也没有报错,那么我们只需要将真正的函数实体恢复就可以了,也就是修复codeOff,修复codeOff对应的字节码。(对dex结构不熟悉的童鞋,面壁去吧)
那么问题来了,怎么不通过调试SO就得到codeOff和其对应的字节码呢?O(∩_∩)O比忘了Android是开源的,直接修改源码,从底层那里搞出来!
还有一个问题,什么时候才知道该APK已经解壳了呢?这个就需要了解这种加壳方式的原理了:
戳这里:http://blogs.360.cn/blog/proxydelegate-application/
再戳这里:http://blog.csdn.net/androidsecurity/article/details/8809542
通过上面两篇文章我们可以知道(你不知道我也没办法),最后必定是要通过调用Application.onCreate来启动真正的逻辑的。也就是说当执行Application.onCreate时,codeOff已经修正完毕。好了现在我们开始改源码,在dalvik/vm/interp/Stack.cpp文件的dvmCallMethodV函数(因为这个函数调用了onCreate函数,函数原型:void dvmCallMethodV(Thread self, const Method method, Object obj, bool fromJni, JValue pResult, va_list args)),添加自己的逻辑:
这里面涉及到dalvik源码里的很多结构体,请自行研究。我这里只是打印出了codeOff,接下来dump和修复的工作就不再详述了,关键是思路!(ps:我的办法不是很优雅,应该有更好的思路)
经过上一步骤,得到了修复过好的dex,原以为这样就结束了,结果又遇到一个问题,我们先看jeb反编译出的几个关键代码吧:
将输入作为map的key,得到对应的value:
前两个字符的hashCode等于3618且字符ascii值和为168,这里推出前两个字符为s5:
然后就是读取两个annotation,与后面几位比较,相同则验证成功:
问题就出在最后这个验证,我们之前修复的是codeOff,但是没有修复annotationsOff,怎么办呢?还是改源码,直接让源码帮我们把两个annotation的值打印出来:
在dalvik/vm/reflect/Annotation.cpp的processAnnotationValue函数处添加自己的逻辑:
- 在函数头部打印出className:
ALOGD("***processAnnotationValue*** className: %s", clazz->descriptor);
- 在case kDexAnnotationString处打印出值:
ALOGD("elemObj: %s", dvmCreateCstrFromString((const StringObject *)elemObj));
得到后面的字符为:7e1p
最终密码为:… _____ ____. . ..___ .__.