ProGuard详解

作者: walker113 | 来源:发表于2016-07-26 14:58 被阅读3699次

    Android分享:代码混淆那些事
    Android代码混淆之混淆规则
    Android-Dev-Favorites

    Android 混淆代码总结

    简介

    ProGuard是一个开源的Java代码混淆器。它可以混淆Android项目里面的java代码,对的,你没看错,仅仅是java代码。它是无法混淆Native代码,资源文件drawable、xml等。

    ProGuard作用

    • 压缩: 移除无效的类、属性、方法等
    • 优化: 优化字节码,并删除未使用的结构
    • 混淆: 将类名、属性名、方法名混淆为难以读懂的字母,比如a,b,c;

    混淆注意事项

    1. 不能混淆

    • 在AndroidManifest中配置的类,比如四大组件
    • JNI调用的方法
    • 反射用到的类
    • WebView中JavaScript调用的方法
    • Layout文件引用到的自定义View
    • 一些引入的第三方库(一般都会有混淆说明的)
      推荐两个开源项目,里面收集了一些第三方库的混淆规则
      android-proguard-snippets
      android-proguard-cn

    2. Crash信息处理

    代码混淆的时候记得加上在混淆文件里面记得加上这句:

    # keep住源文件以及行号
    -keepattributes SourceFile,LineNumberTable
    

    否则你看到的崩溃信息就会变成这样子:(图片来自bugly)


    4HQAG}@A%VHYAELV1BA}DFG.png

    这里推荐bugly的一篇文章: http://bugly.qq.com/bbs/forum.php?mod=viewthread&tid=26&extra=page%3D1

    ProGuard使用

    1. 常用语法

    // 从给定的文件中读取配置参数
    -include {filename} 
    // 指定基础目录为以后相对的档案名称
    -basedirectory {directoryname}
    // 指定要处理的应用程序jar,war,ear和目录   
    -injars {class_path} 
    // 指定处理完后要输出的jar,war,ear和目录的名称 
    -outjars {class_path} 
    // 指定要处理的应用程序jar,war,ear和目录所需要的程序库文件   
    -libraryjars {classpath} 
    // 指定不去忽略非公共的库类。
    -dontskipnonpubliclibraryclasses
    //  指定不去忽略包可见的库类的成员。
    -dontskipnonpubliclibraryclassmembers    
    
    保留
    // 保护指定的类文件和类的成员
    -keep {Modifier} {class_specification} 
    // 保护指定类的成员,如果此类受到保护他们会保护的更好
    -keepclassmembers {modifier} {class_specification} 
    // 保护指定的类和类的成员,但条件是所有指定的类和类成员是要存在。
    -keepclasseswithmembers {class_specification} 
    // 保护指定的类和类的成员的名称(如果他们不会压缩步骤中删除)
    -keepnames {class_specification} 
    // 保护指定的类的成员的名称(如果他们不会压缩步骤中删除)
    -keepclassmembernames {class_specification} 
    // 保护指定的类和类的成员的名称,如果所有指定的类成员出席(在压缩步骤之后)
    -keepclasseswithmembernames {class_specification} 
    // 列出类和类的成员-keep选项的清单,标准输出到给定的文件
    -printseeds {filename} 
    
    压缩
    -dontshrink 不压缩输入的类文件
    -printusage {filename}
    -whyareyoukeeping {class_specification}
    
    优化
    -dontoptimize 不优化输入的类文件
    -assumenosideeffects {class_specification} 优化时假设指定的方法,没有任何副作用
    -allowaccessmodification 优化时允许访问并修改有修饰符的类和类的成员
    
    混淆
    // 不混淆输入的类文件
    -dontobfuscate 
    // 使用给定文件中的关键字作为要混淆方法的名称
    -obfuscationdictionary {filename} 
    // 混淆时应用侵入式重载
    -overloadaggressively 
    // 确定统一的混淆类的成员名称来增加混淆
    -useuniqueclassmembernames 
    // 重新包装所有重命名的包并放在给定的单一包中
    -flattenpackagehierarchy {package_name} 
    // 重新包装所有重命名的类文件中放在给定的单一包中
    -repackageclass {package_name} 
    // 混淆时不会产生形形色色的类名
    -dontusemixedcaseclassnames 
    // 保护给定的可选属性,例如LineNumberTable, LocalVariableTable, SourceFile, Deprecated, Synthetic, Signature, and InnerClasses.
    -keepattributes {attribute_name,…} 
    // 设置源文件中给定的字符串常量
    -renamesourcefileattribute {string} 
    
    通配符匹配规则
    ?      
    匹配单个字符
    
    *
    匹配类名中的任何部分,但不包含额外的包名
    
    **
    匹配类名中的任何部分,并且可以包含额外的包名
    
    %
    匹配任何基础类型的类型名
    
    ***
    匹配任意类型名 ,包含基础类型/非基础类型
    
    ...
    匹配任意数量、任意类型的参数
    
    <init>
    匹配任何构造器
    
    <ifield>
    匹配任何字段名
    
    <imethod>
    匹配任何方法
    
    *(当用在类内部时)
    匹配任何字段和方法
    
    $
    指内部类
    

    更详细的语法请戳:http://proguard.sourceforge.net/manual/usage.html#classspecification

    2. Android Studio中使用方法

    按照上面的语法规则编写proguard-rules.pro后,需要在build.gradle中配置,需要混淆的时候,设置minifyEnabled为true即可

    buildTypes {
        debug {
            minifyEnabled false
        }
        release {
            signingConfig signingConfigs.release
            minifyEnabled true
            proguardFiles 'proguard-rules.pro'
        }
    }
    

    3. Eclipse 中使用方法

    • 1 在工程目录下有个描述文件project.properties, 注意不是proguard-project.txt文件(当时因为这个原因一直失败),添加一句话,启用ProGuard;
    // 原文件内容:
    # proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
    // 修改后内容(其实只是去除注释,并未添加):
    proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
    

    这样,Proguard就可以使用了。当我们正常通过Android Tools导出Application Package时(或者使用ant执行release打包),Proguard就会自动启用,优化混淆你的代码。

    • 2 这一步并不是必要的,第一步中已经添加了sdk目录下的混淆工具,但是为了避免各个项目出现混乱(直接添加导致所有的项目都是使用sdk目录下的ProGard工具);因此往往会将 proguard-android.txt复制到项目的跟目录下,使每个项目各自拥有独立的ProGuard文件;
    // 因此project.properties修改后:
    proguard.config=proguard-android.txt:proguard-project.txt
    // proguard-project.txt表示项目目录下的proguard-project.txt文件
    
    • 3 例子
    ################common###############  
    -keep class **.R$* { *; }
    -keep class com.jph.android.entity.** { *; } #实体类不参与混淆  
    -keep class com.jph.android.view.** { *; } #自定义控件不参与混淆  
    -keepattributes Signature
    -keepattributes *Annotation*
    -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
      
    ################baidu map###############  
    -libraryjars libs/baidumapapi_v3_2_0.jar  
    -libraryjars libs/locSDK_5.0.jar  
    -keep class com.baidu.** { *; }  
    -keep class vi.com.gdi.bgl.android.**{*;}  
    -dontwarn com.baidu.**  
      
      
    ################afinal##################  
    #-libraryjars libs/afinal_0.5_bin.jar  
    #-keep class net.tsz.afinal.** { *; }   
    #-keep public class * extends net.tsz.afinal.**    
    #-keep public interface net.tsz.afinal.** {*;}  
    #-dontwarn net.tsz.afinal.**  
      
    ################xutils##################  
    -libraryjars libs/xUtils-2.6.14.jar  
    -keep class com.lidroid.xutils.** { *; }   
    -keep public class * extends com.lidroid.xutils.**    
    -keepattributes Signature  
    -keepattributes *Annotation*  
    -keep public interface com.lidroid.xutils.** {*;}  
    -dontwarn com.lidroid.xutils.**  
    -keepclasseswithmembers class com.jph.android.entity.** {  
        <fields>;  
        <methods>;  
    }  
      
    ################支付宝##################  
    -libraryjars libs/alipaysecsdk.jar  
    -libraryjars libs/alipayutdid.jar  
    -libraryjars libs/alipaysdk.jar  
    -keep class com.alipay.android.app.IAliPay{*;}  
    -keep class com.alipay.android.app.IAlixPay{*;}  
    -keep class com.alipay.android.app.IRemoteServiceCallback{*;}  
    -keep class com.alipay.android.app.lib.ResourceMap{*;}  
      
    ################gson##################  
    -libraryjars libs/gson-2.2.4.jar  
    -keep class com.google.gson.** {*;}  
    #-keep class com.google.**{*;}  
    -keep class sun.misc.Unsafe { *; }  
    -keep class com.google.gson.stream.** { *; }  
    # 是要确保javaBean的包路径
    # -keep class com.google.gson.examples.android.model.** { *; }   
    -keep class com.mycom.mycomcn.entity.** { *; }
    -keep class com.google.** {  
        <fields>;  
        <methods>;  
    }  
    -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();  
    }  
    -dontwarn com.google.gson.**  
      
      
      
    ################httpmime/httpcore##########  
    -libraryjars libs/httpcore-4.3.2.jar  
    -libraryjars libs/httpmime-4.3.5.jar  
    -keep class org.apache.http.** {*;}  
    -dontwarn org.apache.http.**  
      
    ####################jpush##################  
    -libraryjars libs/jpush-sdk-release1.7.1.jar  
    -keep class cn.jpush.** { *; }  
    -keep public class com.umeng.fb.ui.ThreadView { } #双向反馈功能代码不混淆  
    -dontwarn cn.jpush.**  
    -keepclassmembers class * {  
        public <init>(org.json.JSONObject);  
    }  
     #不混淆R类  
    -keep public class com.jph.android.R$*{   
        public static final int *;  
    }  
    -keepclassmembers enum * {  
        public static **[] values();  
        public static ** valueOf(java.lang.String);  
    }  
      
    ####################umeng##################  
    -libraryjars libs/umeng-analytics-v5.2.4.jar  
    -keep class com.umeng.analytics.** {*;}  
    -dontwarn com.umeng.analytics.**  
      
    #-keep public class * extends com.umeng.**    
    #-keep public class * extends com.umeng.analytics.**    
    #-keep public class * extends com.umeng.common.**    
    #-keep public class * extends com.umeng.newxp.**   
    -keep class com.umeng.** { *; }    
    -keep class com.umeng.analytics.** { *; }    
    -keep class com.umeng.common.** { *; }    
    -keep class com.umeng.newxp.** { *; }   
      
    -keepclassmembers class * {  
       public <init>(org.json.JSONObject);  
    }  
    -keep class com.umeng.**  
      
    -keep public class com.idea.fifaalarmclock.app.R$*{  
        public static final int *;  
    }  
      
    -keep public class com.umeng.fb.ui.ThreadView {  
    }  
      
    -dontwarn com.umeng.**  
      
    -dontwarn org.apache.commons.**  
      
    -keep public class * extends com.umeng.**  
      
    -keep class com.umeng.** {*; }  
      
    ####################universal-image-loader########  
    -libraryjars libs/universal-image-loader-1.9.3.jar  
    -keep class com.nostra13.universalimageloader.** {*;}  
    -dontwarn com.nostra13.universalimageloader.**  
      
      
    ####################zxing#####################  
    -libraryjars libs/zxing.jar  
    -libraryjars libs/zxing_apply.jar  
    -keep class com.google.zxing.** {*;}  
    -dontwarn com.google.zxing.**  
      
    ####################BASE64Decoder##################  
    -libraryjars libs/sun.misc.BASE64Decoder.jar  
      
    ####################support.v4#####################  
    -libraryjars libs/android-support-v4.jar  
    -keep class android.support.v4.** { *; }  
    -dontwarn android.support.v4.**  
      
    ###################other####################  
    # slidingmenu 的混淆  
    -dontwarn com.jeremyfeinstein.slidingmenu.lib.**  
    -keep class com.jeremyfeinstein.slidingmenu.lib.** { *; }  
    # ActionBarSherlock混淆  
    -dontwarn com.actionbarsherlock.**  
    -keep class com.actionbarsherlock.** { *; }  
    -keep interface com.actionbarsherlock.** { *; }  
    -keep class * extends java.lang.annotation.Annotation { *; }  
    -keepclasseswithmembernames class * {  
        native <methods>;  
    }  
      
    -keep class com.jph.android.entity.** {  
        <fields>;  
        <methods>;  
    }  
      
    -dontwarn android.support.**  
    -dontwarn com.slidingmenu.lib.app.SlidingMapActivity  
    -keep class android.support.** { *; }  
    -keep class com.actionbarsherlock.** { *; }  
    -keep interface com.actionbarsherlock.** { *; }  
    -keep class com.slidingmenu.** { *; }  
    -keep interface com.slidingmenu.** { *; }  
    

    4. ProGuard的输出文件说明

    混淆后,会在/build/proguard/目录下输出下面的文件 (Eclipse使用Export Android Application会在项目根目录下产生proguard目录;

    • dump.txt 描述apk文件中所有类文件间的内部结构。
    • mapping.txt 列出了原始的类,方法,和字段名与混淆后代码之间的映射。
    • seeds.txt 列出了未被混淆的类和成员;
    • usage.txt 列出了从apk中删除的代码 ;

    相关文章

      网友评论

      • b0e11dd19c51:您好,能具体说下,proguard的软件安装使用嘛,

        谢谢

      本文标题:ProGuard详解

      本文链接:https://www.haomeiwen.com/subject/hqvnjttx.html