Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android代碼混淆

Android代碼混淆

編輯:關於Android編程

 

 

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

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

-keepclasseswithmembers class * {
    public (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 ;
}

# 保持自定義控件類不被混淆
-keepclasseswithmembers class * {                                              
    public (android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
    public (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 ;
}

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

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

-keepclasseswithmembernames class * {
    public (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 (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反編碼工具打開,就會看到代碼的混淆效果。

 

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved