序言

正所谓授人以鱼,不如授人以渔。前段时间一直研究在android代码混淆的相关内容,同时写了两个工具:方法合并工具、混淆工具。这方面的内容网上资料非常少,但入门门槛其实并不高,因此希望通过这系列的文章,让更多人能够了解到这方面的技术。

谁能从中获益?

对于android开发者来说,能更好的保护自己的软件。

对于学生或技术爱好者来说,能学到一门虽冷门但却有意思的技术,开拓视野。

对于安全从业者来说,能够针对性地做出更好的防护系统。

对于骇客来说…技术无国界嘛^_^

需要什么基础?

1) Java基础是必不可少的。

2) 最好对Android开发有一定了解。

3) 了解NDK开发(非必须)。

4) 了解C语言(非必须)。

能学到的基础知识

学任何东西,基础总是最重要的,因此我首先会先介绍代码混淆所需要了解的基础知识点、用到的工具以及相关库。

基础知识:bytecode、dalvik bytecode及其对比。

用到的工具:dex2jar、apktool、aapt、zipalign、ndk、javap、bytecode插件等等。

相关库:asm、asmdex、smali/baksmali

能学到的技术方案

1) 相似度识别方案:

这里所说的相似度,是指两个apk文件的相似度比较。一般情况下,同一款软件的不同版本,相似度是非常高的。

相似度识别方案包括基于代码流的相似度识别、基于API序列的相似度识别以及基于变量计数的相似度识别。

2) 代码混淆方案:

这里的代码混淆泛指对代码进行处理,至于怎么处理就要看各个方案了。

这里提供了一些代码混淆的思路:

a) 正常属性调用或正常方法调用改为反射调用。

b) 对常量字符串进行加密

c) 对指令进行等价替换、增加花指令

d) 打乱代码

e) 把一部分代码抽取成一个方法(重构)

f) 把多个方法合并成一个方法

g) 转换为本地代码(JNI)

h) 隐藏代码并动态加载

应该怎么学习

这方面的内容需要自己多想想,多动手实践,这样才能更好地理解。

另外,这一系列的文章很多基础知识网上都有很详细的介绍,而我又不打算为了凑字数而进行复制粘贴,因此这里有些内容会比较精简,完全是根据经验拿比较重要的点进行说明,所以建议大家多利用搜索引擎,结合网上的资料来看。

一些故事

最初Leader提出来让bob(dex2jar的作者)去做一个方法合并的工具,从而突破android 65536方法数量的限制。后来bob带了我们入门(非常感谢bob),然后把方法合并的一些思路教给了我们后就离职了。之后我Leader跟我说了一下做完方法合并工具后的路,并问我能不能做下去,我说应该能,其实那时我才刚开始入门,感觉很没底,但又觉得这个非常有意思,所以想去研究玩玩,之后就一直研究到现在。

在做完代码合并工具之后,Leader提出我们的目标是每次混淆后反编译出来的东西都不同,加大看代码难度。然后基于这目标,做了个混淆的工具,当然也可以结合proguard或dexguard来进行混淆,加大破解难度。

做这块的资料非常少,因此找Bug非常难,但其实知识点并不难的,我会在之后的系列文章中介绍这些知识与技巧。

关于方法数限制

android2.3或之前版本有两个限制,一是65536个方法数量的限制,二是5M的线性内存(LinearAlloc buffer)的限制。

做方法合并工具的时候,Android官方的分Dex方案还没出,解决方法数限制的方案主要有几种:

1) 使用proguard去掉一些没用的方法

2) 写代码时注意控制方法的量

3) 人为地分成多个Dex并动态加载(例如做成插件化的方式)

4) 通过动态patch技术改大LinearAlloc buffer。

而方法合并工具是为了提供多一种可选择的方案。

总结

学好本系列的文章,相信大家也会有能力做像proguard、dexguard之类的工具。

关于上面提到的两个工具,源码会在陆续提交github上,源码地址:

https://github.com/noverguo/jdtools