Proguard混淆
Posted
这里仅仅说Android的混淆,其他平台基本相同。
不同的IDE有不同的配置方法。
Android Studio的配置略有差异,可以参考前文
混淆的大致原理就是rename class(所以混淆的过程比较慢),混淆的初衷,并不是为了不让人看源码,毕竟java的虚拟机机制就决定了,源码肯定是可以反编译出来的;其主要目的是让反编译后的代码“难以”看懂。
例如打开一个混淆后输出的mapping文件,可以看到:
(某代码片段,请无视。)
这样一来,反编译后的代码里面,基本就是a.b.c(d.e)这种代码(也许原来只是Util.isNetworkAvailable(context)),大大增加了阅读难度;也就达到了防止反编译的目的。
但经常会误伤,因为是rename,所以对name敏感(依赖name)的方法或者库就会无法正常工作。例如反射,例如JNI的接口class(依赖class name来找context object),例如GSON这些常用工具库。
解决办法就是修改proguard的配置文件,将这些敏感class置为例外。
常用方法如下:
- 排除指定类A
-keepclassmembers class com.xxx.xxx.A { *; }
- 将类A的子类全部排除
-keepclassmembers class * extends com.xxx.xxx.A { *; }
- 将包P内的class全部排除
-keep public class com.xxx.P.* { *; }
- 将包P内的class及subclass全部排除
-keep public class com.xxx.P.** { *; }
注意*
和**
的差别;
注意最后的{ *; }
,用法很多,可以指定仅排除public/protected,如:
{ public protected *;}
当然还可以直接更直接一些:
{ <fields>; <methods>; }
如果是使用Gson的话,还可以直接如下使用方式来避免混淆问题:
@SerializedName("data")
ArrayList<Object> data;
另外可以通过
-printmapping mapping.txt
```来输出mapping,基本这些就够用了。记录一下。
---
其实proguard当然不仅仅可以混淆,[官网](http://proguard.sourceforge.net/)介绍:
>ProGuard is a free Java class file shrinker, optimizer, obfuscator, and preverifier. ***It detects and removes unused classes, fields, methods, and attributes. It optimizes bytecode and removes unused instructions.*** It renames the remaining classes, fields, and methods using short meaningless names. Finally, it preverifies the processed code for Java 6 or higher, or for Java Micro Edition.
---
BTW,既然说到了混淆,那就顺便提一下反编译神器[dex2jar](https://code.google.com/p/dex2jar/)吧,简单好用,方便自测混淆是否成功~