Android 混淆配置
一、proguard 原理
Java代码编译成二进制class 文件,这个class 文件也可以反编译成源代码 。除了注释外,原来的code 基本都可以看到。
为了防止重要code 被泄露,我们往往需要混淆(Obfuscation code ), 也就是把方法,字段,包和类这些java 元素的名称改成无意义的名称,这样代码结构没有变化,还可以运行,但是想弄懂代码的架构却很难。 proguard 就是这样的混淆工具,它可以分析一组class 的结构,根据用户的配置,然后把这些class 文件的可以混淆java 元素名混淆掉。在分析class 的,同时他还有其他两个功能,删除无效代码(Shrinking 收缩),和代码进行优化 (Optimization Options)。
缺省情况下,proguard 会混淆所有代码,但是下面几种情况是不能改变java 元素的名称,否则就会这样就会导致程序出错。
一, 我们用到反射的地方。
二, 我们代码依赖于系统的接口,比如被系统代码调用的回调方法,这种情况最复杂。
三, 是我们的java 元素名称是在配置文件中配置好的。
所以使用proguard时,我们需要有个配置文件告诉proguard 哪些java 元素是不能混淆的。
二、proguard 配置
Proguard.cfg文件是用来描述混淆配置的描述文件。
自Android 2.3 SDK发布后,Google便在Android SDK Tools里加入了proguard,proguard是一个可以对.java文件进行一定程度上的代码混淆,使用proguard是一件极方便工作,在你项目中没有其他外部Jar包的情况下,在“project.properties”文件里,添加一行:
fig=proguard.cfg代码即可,然后通过Android Tools(右击项目名)里导出APK即可。如果项目所使用的的SDK版本低于2.3,只需要进行%android_dir%/tools/lib目录,复制proguard.cfg文件到项目的根目录下导出APK即可。
(2.3之前版本可以拷贝proguard.cfg文件到项目工程下)
这里我们重点看看proguard.cfg文件是如何配置的?Google默认的proguard.cfg文件内容如下:
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
<!--指定类和类成员作为入口保留-->
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * t.BroadcastReceiver
-keep public class * t.ContentProvider
<!---指定特定类做入口->
-keep public class com.android.vending.licensing.ILicensingService
<!--指定的类和类成员被保留->
-keepclasseswithmembernames class * {
    native <methods>;
}
-keepclasseswithmembernames class * {
    public <init>(t.Context, android.util.AttributeSet);
}
-keepclasseswithmembernames class * {
    public <init>(t.Context, android.util.AttributeSet, int);
}
<!--指定的类成员被保留-->
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}
混淆中保留了继承自Activity、Service、Application、BroadcastReceiver、ContentProvider等基本组件以及com.android.vending.licensing.ILicensingService,
并保留了所有的Native变量名及类名,所有类中部分以设定了固定参数格式的构造函数,枚举等等。
最常用的配置选项:
-dontwarn 缺省proguard 会检查每一个引用是否正确,但是第三方库里面往往有些不会用到的类,没有正确引用。如果不配置的话,系统就会报错。
-keep 指定的类和类成员被保留作为入口
-keepclassmembers 指定的类成员被保留。
-keepclasseswithmembers 指定的类和类成员被保留,假如指定的类成员存在的话。
三、proguard 问题和风险
代码混淆后虽然有混淆优化的好处,但是它往往也会带来如下的几点问题:
1,混淆错误,用到第三方库的时候,必须告诉 proguard 不要检查,否则proguard 会报错。
2,运行错误,当code 不能混淆的时候,我们必须要正确配置,否则程序会运行出错,这种情况问题最多。
3,调试苦难,出错了,错误堆栈是混淆后的代码 ,自己也看不懂。
四、解决方案
为了防止混淆出问题,你需要熟悉你所有的code ,系统的架构 ,以及系统和你code的集成的接口,并细心分析。 同时你必须需要一轮全面的测试。 所以混淆也还是有一定风险的。 为了避免风险,你可以只是混淆部分关键的代码,但是这样你的混淆的效果也会有所降低。
常见的不能混淆的androidCode
(1)Android 程序 ,下面这样代码混淆的时候要注意保留。
(2)Android系统组件,系统组件有固定的方法被系统调用。
(3) 被Android Resource 文件引用到的。名字已经固定,也不能混淆,比如自定义的View 。
(4)Android Parcelable ,需要使用android 序列化的。
其他Anroid 官方建议不混淆的,如
(5) android.app.backup.BackupAgentHelper
(6) android.preference.Preference
(7) com.android.vending.licensing.ILicensingService
java混淆工具
8 Java序列化方法,系统序列化需要固定的方法。
(9) 枚举 ,系统需要处理枚举的固定方法。
(10)native 本地方法,不能修改本地方法名
(11)annotations 注释
(12)数据库驱动
(13)有些resource 文件
(14)用到反射的地方,比如调用aidl
如何实施?
(1)保留系统默认混淆设置。
默认系统的混淆配置会保留: Android系统组件
自定义View
Android Parcelable
Android R 文件
Android Parcelable
枚举
各个开发人员必须检查自己的code 是否用到反射,和其他不能混淆的地方。告诉我来修改配置文件(已经保留的就不需要了)
目前系统不检查的第三方库为:
-dontwarn android.support.**
-t.**
-dontwarn org.dom4j.**
-dontwarn org.slf4j.**
-dontwarn org.http.mutipart.**
-dontwarn org.apache.**
-dontwarn org.apache.log4j.**
-dontwarn org.apachemons.logging.**
-dontwarn dec.binary.**
-dontwarn weibo4android.**
proguard 参数:
-include {filename}    从给定的文件中读取配置参数
-basedirectory {directoryname}    指定基础目录为以后相对的档案名称
-injars {class_path}    指定要处理的应用程序jar,war,ear和目录
-outjars {class_path}    指定处理完后要输出的jar,war,ear和目录的名称
-libraryjars {classpath}    指定要处理的应用程序jar,war,ear和目录所需要的程序库文件
-dontskipnonpubliclibraryclasses    指定不去忽略非公共的库类。
-dontskipnonpubliclibraryclassmembers    指定不去忽略包可见的库类的成员。
保留选项:
-keep {Modifier} {class_specification}    保护指定的类文件和类的成员
-keepclassmembers {modifier} {class_specification}    保护指定类的成员,如果此类受到保护他们会保护的更好

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。