Android代码混淆

转载请标明出处: 

http://blog.csdn.net/yujun411522/article/details/46773189
本文出自:【yujun411522的博客】



1 代码混淆的作用
Java 是一种跨平台的、解释型语言,Java 源代码编译成 class 文件中。由于跨平台的需要,Java 字节码中包括了很多源代码信息,如变量名、方法名,并且通过这些名称来访问变量和方法,这些符号带有许多语义信息,很容易被反编译成 Java 源代码。为了防止这种现象,我们可以使用 Java 混淆器对 Java 字节码进行混淆。
混淆就是对发布出去的程序进行重新组织和处理,使得处理后的代码与处理前代码完成相同的功能,而混淆后的代码很难被反编译,即使反编译成功也很难得出程序的真正语义。被混淆过的程序代码,仍然遵照原来的档案格式和指令集,执行结果也与混淆前一样,只是混淆器将代码中的所有变量、函数、类的名称变为简短的英文字母代号,在缺乏相应的函数名和程序注释的况下,即使被反编译,也将难以阅读。同时混淆是不可逆的,在混淆的过程中一些不影响正常运行的信息将永久丢失,这些信息的丢失使程序变得更加难以理解。
混淆器的作用不仅仅是保护代码,它也有精简编译后程序大小的作用。由于以上介绍的缩短变量和函数名以及丢失部分信息的原因, 编译后 jar 文件体积大约能减少25% ,这对当前费用较贵的无线网络传输是有一定意义的。
同样,在android开发过程中,代码的安全也很重要,从2.3开始,我们在创建android工程时会自动创建两个文件proguard-project.txt和project.properties文件,其中默认情况下并没有开启代码混淆,如果需要开启,将project.properties文件中的#proguard.config=${sdk.dir}/tools/ proguard/ proguard-android.txt:proguard-project.txt这一行中的#去掉即可,然后编写混淆文件proguard-project.txt.

2 混淆语法说明
-optimizationpasses 5                                                           # 指定代码的压缩级别
-dontusemixedcaseclassnames                                                     # 是否使用大小写混合
-dontskipnonpubliclibraryclasses                                                # 是否混淆第三方jar
-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 * 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              # 保持哪些类不被混淆

-keepclasseswithmembernames class * {                                           # 保持 native 方法不被混淆
    native <methods>;
}

-keepclasseswithmembers class * {                                               # 保持自定义控件类不被混淆
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);     # 保持自定义控件类不被混淆
}

-keepclassmembers class * extends android.app.Activity {                        # 保持自定义控件类不被混淆
   public void *(android.view.View);
}

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

-keep class * implements android.os.Parcelable {                                # 保持 Parcelable 不被混淆
  public static final android.os.Parcelable$Creator *;
}

-keep class MyClass;                                                            # 保持自己定义的类不被混淆


3 混淆实例
介绍几个例子:
# 指定代码的压缩级别
-optimizationpasses 5                                                         
-dontusemixedcaseclassnames   
# 是否混淆第三方jar                                                 
-dontskipnonpubliclibraryclasses                                              
-dontpreverify                                                                 
-keepattributes SourceFile,LineNumberTable                                        
-verbose                                                                       
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*       

-libraryjars libs/httpmime-4.1.3.jar
-libraryjars libs/libammsdk.jar
-libraryjars libs/fastjson-1.1.34.android.jar
-libraryjars libs/commons-lang.jar
-libraryjars libs/weibosdkcore.jar

# webview + js
# keep 使用 webview 的类
-keepclassmembers class com.goldnet.mobile.activity.InfoDetailActivity {
   public *;
}
# keep 使用 webview 的类的所有的内部类
-keepclassmembers   class com.goldnet.mobile.activity.InfoDetailActivity$*{
    *;
}

# 保持哪些类不被混淆
-keep class android.** {*; }
-keep public class * extends android.view 
-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.pm                               
-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            

#ACRA specifics
# we need line numbers in our stack traces otherwise they are pretty useless
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable

# ACRA needs "annotations" so add this...
-keepattributes *Annotation*

# 保持 native 方法不被混淆
-keepclasseswithmembernames class * {                                       
    native <methods>;
}

# 保持自定义控件类不被混淆
-keepclasseswithmembers class * {                                              
    public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);    
}

-keepclasseswithmembers class * {
    void onClick*(...);
}
-keepclasseswithmembers class * {
    *** *Callback(...);
}

# keep setters in Views so that animations can still work.
# see http://proguard.sourceforge.net/manual/examples.html#beans
-keepclassmembers public class * extends android.view.View {
   void set*(***);
   *** get*();
}

# 保持自定义控件类不被混淆
-keepclassmembers class * extends android.app.Activity {                      
   public void *(android.view.View);
}

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

# 保持 Parcelable 不被混淆
-keep class * implements android.os.Parcelable {                            
  public static final android.os.Parcelable$Creator *;
}

-keepclassmembers class **.R$* {
    public static <fields>;
}

# http client
-keep class org.apache.http.** {*; }

# 微信
-keep class com.tencent.mm.sdk.openapi.WXMediaMessage {*;}
-keep class com.tencent.mm.sdk.openapi.** implements com.tencent.mm.sdk.openapi.WXMediaMessage$IMediaObject {*;}

# fastjson
-keep class com.alibaba.fastjson.**{*;}
# keep 所有的 javabean
-keep class com.goldnet.mobile.entity.**{*;}  
# keep 泛型
-keepattributes Signature
 
#-keep public class * implements java.io.Serializable { 
#    public *; 
#} 
 
#-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(); 
#}

-keep class org.apache.commons.lang.**{*;}

# 新浪微博
-keep class com.sina.**{*;}

#######
# 其它第三方库
#######
-dontwarn org.bouncycastle.**
-keep class org.bouncycastle.**{*;}

-dontwarn android-async-http-1.4.4.jar.**
-keep class android-async-http-1.4.4.jar.**{*;}

-dontwarn Decoder.**
-keep class Decoder.**{*;}

# volley
-dontwarn com.android.volley.jar.**
-keep class com.android.volley.**{*;}

# actionbarsherlock
-dontwarn com.actionbarsherlock.**
-keep class com.actionbarsherlock.**{*;}

# slidingmenu
-dontwarn com.jeremyfeinstein.slidingmenu.lib.**
-keep class com.jeremyfeinstein.slidingmenu.lib.**{*;}

-dontwarn com.cairh.app.sjkh.**
-keep class com.cairh.app.sjkh.**{*;}


再看一个实例
# To enable ProGuard in your project, edit project.properties
# to define the proguard.config property as described in that file.
#
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

-keepattributes *Annotation*
-keepattributes Signature

-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
-libraryjars libs/core.jar
-libraryjars libs/gesture-imageview.jar
-libraryjars libs/gson-2.0.jar
-libraryjars libs/infogracesound.jar
-libraryjars libs/locSDK_4.0.jar
-libraryjars libs/ormlite-android-4.48.jar
-libraryjars libs/ormlite-core-4.48.jar
-libraryjars libs/universal-image-loader-1.9.0.jar

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

-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

-keep class com.google.gson.stream.** { *; }
-keep class com.google.gson.examples.android.model.** { *; }
-keep class com.uuhelper.Application.** { *; }
-keep class net.sourceforge.zbar.** { *; }
-keep class com.google.android.gms.** { *; }

-keep class com.bank.pingan.model.** { *; }

-keep public class * extends com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper
-keep public class * extends com.j256.ormlite.android.apptools.OpenHelperManager

-keep class com.android.vending.licensing.ILicensingService
-keep class android.support.v4.** { *; } 
-keep class org.apache.commons.net.** { *; } 
-keep class com.tencent.** { *; } 

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

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

-dontwarn android.support.v4.** 
-dontwarn org.apache.commons.net.**
-dontwarn com.tencent.** 

-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);
}

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

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

-keepclasseswithmembers class * {
    public <init>(android.content.Context);
}

-dontshrink
-dontoptimize
-dontwarn com.google.android.maps.**
-dontwarn android.webkit.WebView
-dontwarn com.umeng.**
-dontwarn com.tencent.weibo.sdk.**
-dontwarn com.facebook.**

-keep enum com.facebook.**
-keepattributes Exceptions,InnerClasses,Signature
-keepattributes *Annotation*
-keepattributes SourceFile,LineNumberTable

-keep public interface com.facebook.**
-keep public interface com.tencent.**
-keep public interface com.umeng.socialize.**
-keep public interface com.umeng.socialize.sensor.**
-keep public interface com.umeng.scrshot.**

-keep public class com.umeng.socialize.* {*;}
-keep public class javax.**
-keep public class android.webkit.**

-keep class com.facebook.**
-keep class com.umeng.scrshot.**
-keep public class com.tencent.** {*;}
-keep class com.umeng.socialize.sensor.**

-keep class com.tencent.mm.sdk.openapi.WXMediaMessage {*;}

-keep class com.tencent.mm.sdk.openapi.** implements com.tencent.mm.sdk.openapi.WXMediaMessage$IMediaObject {*;}

-keep class im.yixin.sdk.api.YXMessage {*;}
-keep class im.yixin.sdk.api.** implements im.yixin.sdk.api.YXMessage$YXMessageData{*;}

-keep public class [your_pkg].R$*{
    public static final int *;
}

编写完混淆文件之后,接下来就是生成Apk了。这里需要注意的是,如果你用Eclipse里的Run或Build Project/Build All来生成Apk,是不会混淆代码的!在Eclipse的Package Explorer里选中工程的根结点,在右键菜单里找到Android Tools,如下图所示,其下有两个子菜单项:“Export Signed Application Package...”和“Export Unsigned Application Package...”,一个是带RSA数字签名,一个是不带数字签名,根据需要选一个,然后按照向导操作即可,最终生成的Apk就是混淆过代码的了!查看效果可以用7z等压缩程序(Ubuntu中直接用归档管理器)打开,将其中的classes.dex解压,用dex2jar转成jar格式后,再用Java反编码工具打开,就会看到代码的混淆效果。

你可能感兴趣的:(Android代码混淆)