您的位置:首页 > 移动开发 > Android开发

Android 混淆 (不定期完善第三方混淆规则)

2017-02-11 16:38 302 查看

开启混淆

在AS中,借助于SDK中自带的Proguard工具,开启混淆只需要在release闭包中添加如下两行代码:

release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}


其中
minifyEnabled
表示是否开启混淆,开启后打包出的apk就是混淆过的了。

有些代码如果被混淆了就会报错,因此需要混淆规则来定义那些不能混淆的代码。

proguard-android.txt
是默认的混淆规则,该文件位于
fake-path—sdk\tools\proguard
目录下,它对本机上所有项目的混淆都生效,所以一般不改动这个文件。

proguard-rules.pro
默认在每个项目的app模块中,我们可以在这个文件中编写适用于当前项目的混淆规则。

默认情况下,这样的写法会使两个文件中的混淆规则同时生效。

混淆语法

keep关键字

proguard中一共有三组六个keep关键字,区别如下:

关键字描述
keep保留类和类中的成员,防止它们被混淆或移除。
keepnames保留类和类中的成员,防止它们被混淆,但当成员没有被引用时会被移除。
keepclassmembers只保留类中的成员,防止它们被混淆或移除。
keepclassmembernames只保留类中的成员,防止它们被混淆,但当成员没有被引用时会被移除。
keepclasseswithmembers保留类和类中的成员,防止它们被混淆或移除,前提是指名的类中的成员必须存在,如果不存在则还是会混淆。
keepclasseswithmembernames保留类和类中的成员,防止它们被混淆,但当成员没有被引用时会被移除,前提是指名的类中的成员必须存在,如果不存在则还是会混淆。

通配符

通配符描述
<field>
匹配类中的所有字段
<method>
匹配类中的所有方法
<init>
匹配类中的所有构造函数
*匹配任意长度字符,但不含包名分隔符(.)。但如果你不写任何其它内容,只有一个*,那就表示匹配所有的东西。
**匹配任意长度字符,并且包含包名分隔符(.),包括任意长度的子包。
***
匹配任意参数类型。比如void set*()就能匹配任意传入的参数类型, get*()就能匹配任意返回值的类型。
匹配任意长度的任意类型参数。比如void test(…)就能匹配任意void test(String a)或者是void test(int a, String b)这些方法。

默认混淆规则

下面是
proguard-android.txt
文件中的内容(手动加了注释):

# This is a configuration file for ProGuard.
# http://proguard.sourceforge.net/index.html#manual/usage.html 
#混淆时不使用大小写混合类名。
-dontusemixedcaseclassnames

#不跳过library中的非public的类。
-dontskipnonpubliclibraryclasses

#混淆后产生映射文件
#包含有类名->混淆后类名的映射关系
-verbose

# Optimization is turned off by default. Dex does not like code run
# through the ProGuard optimize and preverify steps (and performs some
# of these optimizations on its own).

#不进行优化,建议使用此选项,因为根据proguard-android-optimize.txt中的描述,优化可能会造成一些潜在风险,不能保证在所有版本的Dalvik上都正常运行。
-dontoptimize

#不进行预校验。这个预校验是作用在Java平台上的,Android平台上不需要这项功能,去掉之后还可以加快混淆速度。
-dontpreverify

# Note that if you want to enable optimization, you cannot just
# include optimization flags in your own project configuration file;
# instead you will need to point to the
# "proguard-android-optimize.txt" file instead of this one from your
# project.properties file.

#对注解中的参数进行保留。
-keepattributes *Annotation*

#不混淆声明的这两个类,这两个类我们基本也用不上,是接入Google原生的一些服务时使用的。
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService

# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native 
#不混淆任何包含native方法的类的类名以及native方法名,但当成员没有被引用时会被移除
-keepclasseswithmembernames class * {
native <methods>;
}

# keep setters in Views so that animations can still work.
# see http://proguard.sourceforge.net/manual/examples.html#beans 
#不混淆任何一个View中的setXxx()和getXxx()方法,因为属性动画需要有相应的setter和getter的方法实现,混淆了就无法工作了。
-keepclassmembers public class * extends android.view.View {
void set*(***);
*** get*();
}

# We want to keep methods in Activity that could be used in the XML attribute onClick

#不混淆Activity中参数是View的方法,因为有这样一种用法,在XML中配置android:onClick=”buttonClick”属性,当用户点击该按钮时就会调用Activity中的buttonClick(View view)方法,如果这个方法被混淆的话就找不到了。
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}

# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations 
#不混淆枚举中的values()和valueOf()方法
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}

#不混淆Parcelable实现类中的CREATOR字段,毫无疑问,CREATOR字段是绝对不能改变的,包括大小写都不能变,不然整个Parcelable工作机制都会失败。
-keepclassmembers class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator CREATOR;
}

#不混淆R文件中的所有静态字段,我们都知道R文件是通过字段来记录每个资源的id的,字段名要是被混淆了,id也就找不着了。
-keepclassmembers class **.R$* {
public static <fields>;
}

# The support library contains references to newer platform versions.
# Don't warn about those in case this app is linking against an older
# platform version.  We know about them, and they are safe.

#对android.support包下的代码不警告,因为兼容库的中代码是安全的
-dontwarn android.support.**

# Understand the @Keep support annotation.

#不混淆keep注解
-keep class android.support.annotation.Keep

-keep @android.support.annotation.Keep class * {*;}

-keepclasseswithmembers class * {
@android.support.annotation.Keep <methods>;
}

-keepclasseswithmembers class * {
@android.support.annotation.Keep <fields>;
}

-keepclasseswithmembers class * {
@android.support.annotation.Keep <init>(...);
}


自定义混淆规则

我们可以在当前项目的
proguard-rules.pro
中定义如下混淆规则,其中第三方混淆规则将不定期更新、完善:

##---------------Begin: proguard configuration common for all Android apps ----------
#代码混淆压缩比,在0~7之间,默认为5,一般不做修改
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-dontpreverify
-verbose
-dump class_files.txt
-printseeds seeds.txt
-printusage unused.txt
-printmapping mapping.txt
#指定混淆采用的算法,后面的参数是一个过滤器
#这个过滤器是谷歌推荐的算法,一般不做更改
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

-allowaccessmodification
-keepattributes *Annotation*
-renamesourcefileattribute SourceFile
#抛出异常时保留代码行号
-keepattributes SourceFile,LineNumberTable
-repackageclasses ''

#保留我们使用的四大组件,自定义的Application等这些子类不被混淆
#因为这些子类都有可能被外部调用
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-dontnote com.android.vending.licensing.ILicensingService

# Explicitly preserve all serialization members. The Serializable interface
# is only a marker interface, so it wouldn't save them.
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}

# Preserve all native method names and the names of their classes.
-keepclasseswithmembernames class * {
native <methods>;
}

-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}

# Preserve static fields of inner classes of R classes that might be accessed
# through introspection.
-keepclassmembers class **.R$* {
public static <fields>;
}

# Preserve the special static methods that are required in all enumeration classes.
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}

-keep public class * {
public protected *;
}

-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}

#实体类
-keep class com.bean.** { *; }
##---------------End: proguard configuration common for all Android apps ----------

#Gson
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
#避免混淆泛型
-keepattributes Signature
# Gson specific classes
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }
-keep class sun.misc.Unsafe.** { *; }
-keep class sun.misc.Unsafe.**
-keep class com.google.** { *; }

#org apache
-keep class org.apache.** { *; }
#baidumap
-keep class com.baidu.** { *; }
-keep class com.baidu.**
-keep class  vi.com.gdi.bgl.android.**{*;}
-keep class  vi.com.gdi.bgl.android.**
-keep class com.baidu.** {*;}
-keep class vi.com.** {*;}
-dontwarn com.baidu.**
#chartengine
-keep class org.achartengine.** { *; }
-keep class org.achartengine.**
#youmeng
-keep class com.umeng.analytics.**{*;}
-keep class com.umeng.analytics.**
-keep class u.aly.** {*;}
-keep class u.aly.**
#alipay
-keep class com.alipay.** { *; }
-keep class com.alipay.**
-keep class com.ta.utdid2.** { *; }
-keep class com.ta.utdid2.**
-keep class com.ut.device.** { *; }
-keep class com.ut.device.**
-keep class org.json.alipay.** { *; }
-keep class org.json.alipay.**
#pinyin4j
-keep class com.hp.hpl.sparta..** { *; }
-keep class com.hp.hpl.sparta..**
-keep class demo..** { *; }
-keep class demo..**
-keep class net.sourceforge.pinyin4j..** { *; }
-keep class net.sourceforge.pinyin4j..**
#http legacy
#webkit
-keepclassmembers class * extends android.webkit.WebChromeClient{
public void openFileChooser(...);
}
#open-sdk mta-sdk libammsdk
-keep class com.tencent..** { *; }
-keep class com.tencent..**
#zxing
-keep class com.google.zxing.** { *; }
-keep class com.google.zxing.**

-dontwarn java.lang.invoke**
-dontwarn org.apache.lang.**
-dontwarn org.apache.commons.**
-dontwarn com.com.nostra13.**
-dontwarn com.github.**
-dontwarn com.squareup.**

#retrofit
# Platform calls Class.forName on types which do not exist on Android to determine platform.
-dontnote retrofit2.Platform
# Platform used when running on RoboVM on iOS. Will not be used at runtime.
-dontnote retrofit2.Platform$IOS$MainThreadExecutor
# Platform used when running on Java 8 VMs. Will not be used at runtime.
-dontwarn retrofit2.Platform$Java8
# Retain generic type information for use by reflection by converters and adapters.
-keepattributes Signature
# Retain declared checked exceptions for use by a Proxy instance.
-keepattributes Exceptions
-keep class com.life.me.entity.postentity{*;}
-keep class com.life.me.entity.resultentity{*;}
-dontwarn retrofit.
-keep class retrofit. { *; }
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }

#butterknife
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; }
-keepclasseswithmembernames class * {
@butterknife.* <fields>;
}
-keepclasseswithmembernames class * {
@butterknife.* <methods>;
}

#阿里百川hotfix
-keep class * extends java.lang.annotation.Annotation
-keepclasseswithmembernames class * {
native <methods>;
}
-keep class com.alipay.euler.andfix.**{
*;
}
-keep class com.taobao.hotfix.aidl.**{*;}
-keep class com.ta.utdid2.device.**{*;}
-keep class com.taobao.hotfix.HotFixManager{
public *;
}
#如果是打修复包,需要在当前模块中放有对应版本的mapping.txt文件
#再添加下面一行配置,保证修复前后两个APK的混淆结果一致
-applymapping mapping.txt

#rx
-dontwarn sun.misc.**
-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {
long producerIndex;
long consumerIndex;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {
rx.internal.util.atomic.LinkedQueueNode producerNode;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {
rx.internal.util.atomic.LinkedQueueNode consumerNode;
}

#okhttp
-dontwarn com.squareup.okhttp3.**
-keep class com.squareup.okhttp3.** { *;}
-dontwarn okhttp3.logging.**
-keep class okhttp3.internal.**{*;}
-dontwarn okio.**

#极光推送
-dontoptimize
-dontpreverify

-dontwarn cn.jpush.**
-keep class cn.jpush.** { *; }

-dontwarn cn.jiguang.**
-keep class cn.jiguang.** { *; }
#LitePal
-keep class org.litepal.** {
*;
}
-keep class * extends org.litepal.crud.DataSupport {
*;
}

#扫码
-keepclassmembers class net.sourceforge.zbar.ImageScanner { *; }
-keepclassmembers class net.sourceforge.zbar.Image { *; }
-keepclassmembers class net.sourceforge.zbar.Symbol { *; }
-keepclassmembers class net.sourceforge.zbar.SymbolSet { *; }

#联迪pos
-dontwarn com.landicorp.**

#新大陆pos
-dontwarn com.newland.**
-keep class com.newland.payment.trans.bean.** { *; }

#画板
-dontwarn  me.panavtec.drawableview.**


DexGuard

对于更高的安全需求,Proguard可能有些力不从心了。而DexGuard就能提供更安全的保护,关于它的资料可以点这里

参考资料:http://blog.csdn.net/guolin_blog/article/details/50451259
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: