Android混淆——混淆代码总结

转自http://blog.csdn.net/lovexjyong/article/details/24652085

       http://blog.csdn.net/catoop/article/details/47208833



混淆的概念:

对编译好的class文件进行混淆处理。

ProGuard是一个混淆代码的开源项目。它的主要作用就是混淆,当然它还能对字节码进行缩减体积、优化等

混淆的原理

Java 是一种跨平台的、解释型语言,Java 源代码编译成中间”字节码”存储于 class 文件中。由于跨平台的需要,Java 字节码中包括了很多源代码信息,如变量名、方法名,并且通过这些名称来访问变量和方法,这些符号带有许多语义信息,很容易被反编译成 Java 源代码。为了防止这种现象,我们可以使用 Java 混淆器对 Java 字节码进行混淆。

混淆就是对发布出去的程序进行重新组织和处理,使得处理后的代码与处理前代码完成相同的功能,而混淆后的代码很难被反编译,即使反编译成功也很难得出程序的真正语义。被混淆过的程序代码,仍然遵照原来的档案格式和指令集,执行结果也与混淆前一样,只是混淆器将代码中的所有变量、函数、类的名称变为简短的英文字母代号,在缺乏相应的函数名和程序注释的况下,即使被反编译,也将难以阅读。同时混淆是不可逆的,在混淆的过程中一些不影响正常运行的信息将永久丢失,这些信息的丢失使程序变得更加难以理解。

混淆器的作用不仅仅是保护代码,它也有精简编译后程序大小的作用。由于以上介绍的缩短变量和函数名以及丢失部分信息的原因, 编译后 jar 文件体积大约能减少25% ,这对当前费用较贵的无线网络传输是有一定意义的。

混淆的语法:

<span style="font-size:12px;">
    -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}    保护指定类的成员,如果此类受到保护他们会保护的更好  
    -keepclasseswithmembers {class_specification}    保护指定的类和类的成员,但条件是所有指定的类和类成员是要存在。   
    -keepnames {class_specification}    保护指定的类和类的成员的名称(如果他们不会压缩步骤中删除)   
    -keepclassmembernames {class_specification}    保护指定的类的成员的名称(如果他们不会压缩步骤中删除)   
    -keepclasseswithmembernames {class_specification}    保护指定的类和类的成员的名称,如果所有指定的类成员出席(在压缩步骤之后)   
    -printseeds {filename}    列出类和类的成员-keep选项的清单,标准输出到给定的文件 </span><strong>  
       
    </strong>压缩   
    -dontshrink    不压缩输入的类文件   
    -printusage {filename}   
    -dontwarn   如果有警告也不终止  
    -whyareyoukeeping {class_specification}       
       
    优化   
    -dontoptimize    不优化输入的类文件   
    -assumenosideeffects {class_specification}    优化时假设指定的方法,没有任何副作用   
    -allowaccessmodification    优化时允许访问并修改有修饰符的类和类的成员   
       
    混淆   
    -dontobfuscate    不混淆输入的类文件   
    -printmapping {filename}   
    -applymapping {filename}    重用映射增加混淆   
    -obfuscationdictionary {filename}    使用给定文件中的关键字作为要混淆方法的名称   
    -overloadaggressively    混淆时应用侵入式重载   
    -useuniqueclassmembernames    确定统一的混淆类的成员名称来增加混淆   
    -flattenpackagehierarchy {package_name}    重新包装所有重命名的包并放在给定的单一包中   
    -repackageclass {package_name}    重新包装所有重命名的类文件中放在给定的单一包中   
    -dontusemixedcaseclassnames    混淆时不会产生形形色色的类名   
    -keepattributes {attribute_name,...}    保护给定的可选属性,例如LineNumberTable, LocalVariableTable, SourceFile, Deprecated, Synthetic, Signature, and   
       
    InnerClasses.   
    -renamesourcefileattribute {string}    设置源文件中给定的字符串常量  




混淆的步骤

1. 新建一个工程会看到项目下边有这样proguard-project.txt一个文件,这个对混淆代码很重要,不小心删掉了可以从其他地方拷贝一个过来

2.在proguard-project.txt添加混淆的申明:

    a. 把所有你的jar包都申明进来,例如:

     

  -libraryjars libs/apns_1.0.6.jar
  -libraryjars libs/armeabi/libBaiduMapSDK_v2_3_1.so
  -libraryjars libs/armeabi/liblocSDK4.so
  -libraryjars libs/baidumapapi_v2_3_1.jar

  b. 将你不需要混淆的部分申明进来,因为有些类经过混淆会导致程序编译不通过,如下:

  
   -keep public class * extends android.app.Fragment  
   -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 * extends android.support.v4.**
   -keep public class com.android.vending.licensing.ILicensingService

--以上都是API里边的类,最好都要避免混淆


  c.保证native方法不被混淆

-keepclasseswithmembernames class * {  
    native <methods>;  
}  


d.保证制定规则的方法不混淆

-keepclassmembers class * extends android.app.Activity {   
    public void *(android.view.View); #保持指定规则的方法不被混淆(Android layout 布局文件中为控件配置的onClick方法不能混淆)  
}


e.保证自定义的控件类不混淆

<pre name="code" class="java">-keepclasseswithmembers class * {  
    public <init>(android.content.Context, android.util.AttributeSet);  #保持自定义控件类不被混淆,指定格式的构造方法不去混淆  
}  
  -keepclasseswithmembers class * {  
    public <init>(android.content.Context, android.util.AttributeSet, int);  
}
-keepclasseswithmembers class * {  
    public <init>(android.content.Context);  
}
-keepclasseswithmembers class * {  
    public <init>();  
}

 

f.保证自定义控件类指定规则的方法不被混淆

-keep public class * extends android.view.View {  #保持自定义控件指定规则的方法不被混淆  
    public <init>(android.content.Context);  
    public <init>(android.content.Context, android.util.AttributeSet);  
    public <init>(android.content.Context, android.util.AttributeSet, int);  
    public void set*(...);  
} 

g.保证枚举类不混淆

-keepclassmembers enum * {  #保持枚举 enum 不被混淆  
    public static **[] values();  
    public static ** valueOf(java.lang.String);  
} 

h.保持 Parcelable 不被混淆(aidl文件不能去混淆)

-keep class * implements android.os.Parcelable {  #保持 Parcelable 不被混淆(aidl文件不能去混淆)  
    public static final android.os.Parcelable$Creator *;  
}  


i.需要序列化和反序列化的类不能被混淆(注:Java反射用到的类也不能被混淆)

-keepnames class * implements java.io.Serializable 


j.保护实现接口Serializable的类中,指定规则的类成员不被混淆

-keepclassmembers class * implements java.io.Serializable { #保护实现接口Serializable的类中,指定规则的类成员不被混淆  
    static final long serialVersionUID;  
    private static final java.io.ObjectStreamField[] serialPersistentFields;  
    !static !transient <fields>;  
    private void writeObject(java.io.ObjectOutputStream);  
    private void readObject(java.io.ObjectInputStream);  
    java.lang.Object writeReplace();  
    java.lang.Object readResolve();  
}  


k.过滤泛型(不写可能会出现类型转换错误,一般情况把这个加上就是了)

-keepattributes Signature  #过滤泛型(不写可能会出现类型转换错误,一般情况把这个加上就是了) 

l.假如项目中有用到注解,应加入这行配置

keepattributes *Annotation*


m.保持R文件不被混淆,否则,你的反射是获取不到资源id的 

-keep class **.R$* { *; }  #保持R文件不被混淆,否则,你的反射是获取不到资源id的


下面都是项目中引入的第三方 jar 包。第三方 jar 包中的代码不是我们的目标和关心的对象,故而对此我们全部忽略不进行混淆。

-libraryjars  libs/android-support-v4.jar  
-dontwarn android.support.v4.**  
-keep class android.support.v4.** { *; }    
-keep interface android.support.v4.** { *; }  
-keep public class * extends android.support.v4.**   
-keep public class * extends android.app.Fragment  
  
-libraryjars libs/gson-2.3.1-sources.jar  
-libraryjars libs/gson-2.3.1.jar  
-dontwarn com.google.gson.**      
-keep class sun.misc.Unsafe { *; }  
-keep class com.google.gson.** { *; }  
  
-libraryjars libs/alipaySDK-20150602.jar  
-dontwarn com.alipay.**      
-dontwarn com.ta.utdid2.**      
-dontwarn com.ut.device.**      
-keep class com.alipay.** { *; }  
-keep class com.ta.utdid2.** { *; }  
-keep class com.ut.device.** { *; }  
  
-libraryjars libs/android-async-http-1.4.6.jar  
-dontwarn com.loopj.android.http.**  
-keep class com.loopj.android.http.** { *; }  
  
-libraryjars libs/baidumapapi_v2_4_1.jar  
-dontwarn com.baidu.**  
-keep class com.baidu.** {*; }  
-keep class assets.** {*; }  
-keep class vi.com.gdi.bgl.** {*; }  
  
-libraryjars libs/libammsdk.jar  
-dontwarn com.tencent.**  
-keep class com.tencent.** { *; }  
  
-libraryjars libs/locSDK_4.1.jar  
-dontwarn com.baidu.location.**  
-keep class com.baidu.location.** { *; }  
  
-libraryjars libs/mframework.jar  
-dontwarn m.framework.**  
-keep class m.framework.** { *; }  
  
-libraryjars libs/mta-sdk-1.6.2.jar  
-dontwarn com.tencent.stat.**  
-keep class com.tencent.stat.** { *; }  
  
-libraryjars libs/nineoldandroids-library-2.4.0.jar  
-dontwarn com.nineoldandroids.**  
-keep class com.nineoldandroids.** { *; }  
  
-libraryjars libs/open_sdk_r4889.jar  
-dontwarn com.tencent.**  
-keep class com.tencent.** { *; }   
  
-libraryjars libs/ShareSDK-Core-2.5.9.jar  
-dontwarn cn.sharesdk.framework.**  
-keep class cn.sharesdk.framework.** { *; }   
  
-libraryjars libs/ShareSDK-ShortMessage-2.5.9.jar  
-dontwarn cn.sharesdk.system.text.**  
-keep class cn.sharesdk.system.text.** { *; }   
  
-libraryjars libs/ShareSDK-SinaWeibo-2.5.9.jar  
-dontwarn cn.sharesdk.sina.weibo.**  
-keep class cn.sharesdk.sina.weibo.** { *; }   
  
-libraryjars libs/ShareSDK-Wechat-2.5.9.jar  
-dontwarn cn.sharesdk.wechat.friends.**  
-keep class cn.sharesdk.wechat.friends.** { *; }   
  
-libraryjars libs/ShareSDK-Wechat-Core-2.5.9.jar  
-dontwarn cn.sharesdk.wechat.utils.**  
-keep class cn.sharesdk.wechat.utils.** { *; }   
  
-libraryjars libs/ShareSDK-Wechat-Favorite-2.5.9.jar  
-dontwarn cn.sharesdk.wechat.favorite.**  
-keep class cn.sharesdk.wechat.favorite.** { *; }   
  
-libraryjars libs/ShareSDK-Wechat-Moments-2.5.9.jar  
-dontwarn cn.sharesdk.wechat.moments.**  
-keep class cn.sharesdk.wechat.moments.** { *; }   
  
-libraryjars libs/universal-image-loader-1.9.2-SNAPSHOT-with-sources.jar  
-dontwarn com.nostra13.universalimageloader.**  
-keep class com.nostra13.universalimageloader.** { *; }   
  
-libraryjars libs/weibosdkcore.jar  
-dontwarn com.sina.weibo.sdk.**  
-keep class com.sina.weibo.sdk.** { *; }  


有些很特殊的,例如百度地图,你需要添加以下申明:

-keep class com.baidu.** { *; }
-keep class vi.com.gdi.bgl.android.**{*;}


友盟的混淆规则

-keep class com.umeng.** { *; }    
-keep class com.umeng.analytics.** { *; }    
-keep class com.umeng.common.** { *; }    
-keep class com.umeng.newxp.** { *; }    


com.j256.ormlite混淆规则
-keep public class * extends com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper  
-keep public class * extends com.j256.ormlite.android.apptools.OpenHelperManager  

-keep class com.j256.ormlite.** { *; }    
-keep class com.j256.ormlite.android.** { *; }    
-keep class com.j256.ormlite.field.** { *; }    
-keep class com.j256.ormlite.stmt.** { *; }  



eventbus混淆规则

-dontwarn de.greenrobot.event.**
-keep class de.greenrobot.event.** { *; }
-keepclassmembers class ** {
	public void onEvent(**);
	void onEvent*(**);
}


 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值