美文网首页2022
Android代码混淆

Android代码混淆

作者: Thor_果冻 | 来源:发表于2018-12-31 13:00 被阅读0次

    代码混淆

    如有错误可以QQ邮箱联系,745661590@qq.com
    github不支持脚注

    代码混淆概念[1]

    代码混淆(Obfuscated code)亦称花指令,是将计算机程序的代码,转换成一种功能上等价,但是难于阅读和理解的形式的行为。代码混淆可以用于程序源代码,也可以用于程序编译而成的中间代码。执行代码混淆的程序被称作代码混淆器。目前已经存在许多种功能各异的代码混淆器。

    混淆配置

    我们一般直接在app的build.gradle文件中设置minifyEnabled true即可;
    我们一般也加上shrinkResources true,打开资源压缩。用shrinkResources true开启资源压缩后,所有未被使用的资源默认被移除。

    android {
        buildTypes {
            release {
                minifyEnabled true//是否启动混淆true:打开;false:关闭
                shrinkResources true//打开资源压缩。
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    }
    

    设置白名单

    白名单也就是proguard-rules.pro中我们自定义哪些不添加混淆。

    关键字[2]

    关键字 描述
    dontwarn dontwarn是一个和keep可以说是形影不离,尤其是处理引入的library时.
    keep 保留类和类中的成员,防止被混淆或移除
    keepnames 保留类和类中的成员,防止被混淆,成员没有被引用会被移除
    keepclassmembers 只保留类中的成员,防止被混淆或移除
    keepclassmembernames 只保留类中的成员,防止被混淆,成员没有引用会被移除
    keepclasseswithmembers 保留类和类中的成员,防止被混淆或移除,保留指明的成员
    keepclasseswithmembernames 保留类和类中的成员,防止被混淆,保留指明的成员,成员没有引用会被移除
    [保持命令] [类] {
        [成员] 
    }
    

    通配符

    去除反斜杠,markDown中我不知道怎么去除

    通配符 描述
    * 匹配任意长度字符,不包含包名分隔符(.)
    ** 匹配任意长度字符,包含包名分隔符(.)
    *** 匹配任意参数类型
    $ 内部类
    <\init> 匹配类中所有的构造函数
    <\fields> 匹配类中的所有字段
    <\method> 匹配类中所有的方法
    匹配任意长度的任意类型参数。比如void test(…)就能匹配任意 void test(String a) 或者是 void test(int a, String b) 这些方法。
    extends 即可以指定类的基类
    implement 匹配实现了某接口的类

    规则使用

    • 不混淆某个类

      -keep public class com.dongdongwu.thor.entry.Test { *; }
      
    • 不混淆某个包所有的类

      -keep class com.dongdongwu.thor.entry.** { *; }
      
    • 不混淆某个类的子类

      -keep public class * extends com.dongdongwu.thor.entry.Test { *; }
      
    • 不混淆所有类名中包含了“model”的类及其成员

      -keep public class **.*model*.** { *; }
      
    • 不混淆某个接口的实现

      -keep class * implements com.dongdongwu.thor.entry.Test { *; }
      
    • 不混淆某个类的构造方法

      -keepclassmembers class com.dongdongwu.thor.entry.Test {
          public <init>(); 
      }
      
    • 不混淆某个类的特定的方法

      -keepclassmembers class com.dongdongwu.thor.entry.Test {
          public void test(java.lang.String); 
      }
      
    • 不混淆某个类的内部类

      -keep class com.dongdongwu.thor.entry.Test$* {
          *; 
      }
      

    我总结的

    最新的proguard-android.txt中添加了很多下面已经有的,再添加的时候看看是不是已经有了

    
    #######################-----app中-----############################
    #如果使用了Gson之类的工具要使被它解析的JavaBean类即实体类不被混淆
    
    #######################-----第三方-----############################
    
    #######################-----WebView(项目中没有可以忽略)-----############################
    #webView需要进行特殊处理
    -keepclassmembers class fqcn.of.javascript.interface.for.Webview {
       public *;
    }
    -keepclassmembers class * extends android.webkit.WebViewClient {
        public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
        public boolean *(android.webkit.WebView, java.lang.String);
    }
    -keepclassmembers class * extends android.webkit.WebViewClient {
        public void *(android.webkit.WebView, jav.lang.String);
    }
    #在app中与HTML5的JavaScript的交互进行特殊处理
    #我们需要确保这些js要调用的原生方法不能够被混淆,于是我们需要做如下处理:
    -keepclassmembers class com.ljd.example.JSInterface {
        <methods>;
    }
    
    
    #######################-----其他-----############################
    # 删除代码中Log相关的代码
    -assumenosideeffects class android.util.Log {
        public static boolean isLoggable(java.lang.String, int);
        public static int v(...);
        public static int i(...);
        public static int w(...);
        public static int d(...);
        public static int e(...);
    }
    
    # 保持测试相关的代码
    -dontnote junit.framework.**
    -dontnote junit.runner.**
    -dontwarn android.test.**
    -dontwarn android.support.test.**
    -dontwarn org.junit.**
    
    #######################-----基本-----############################
    #指定代码的压缩级别 0 - 7(指定代码进行迭代优化的次数,在Android里面默认是5,这条指令也只有在可以优化时起作用。)
    -optimizationpasses 5
    
    #混淆时不会产生形形色色的类名(混淆时不使用大小写混合类名,混淆后类名都为小写)
    -dontusemixedcaseclassnames
    
    #指定不去忽略非公共的库的类
    #默认跳过,有些情况下编写的代码与类库中的类在同一个包下,并且持有包中内容的引用,此时就需要加入此条声明
    -dontskipnonpubliclibraryclasses
    #指定不去忽略非公共的库的类的成员
    -dontskipnonpubliclibraryclassmembers
    
    #Optimization is turned off by default. Dex does not like code run
    #hrough the ProGuard optimize and preverify steps (and performs some
    #of these optimizations on its own).
    #不进行优化,建议使用此选项,不优化输入的类文件(原因见上边的原英文注释)
    -dontoptimize
    #不做预检验,preverify是proguard的四个步骤之一
    #Android不需要preverify,去掉这一步可以加快混淆速度
    -dontpreverify
    
    #屏蔽警告
    -ignorewarnings
    
    #指定混淆是采用的算法,后面的参数是一个过滤器
    #这个过滤器是谷歌推荐的算法,一般不做更改
    -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
    
    #避免混淆Annotation、内部类、泛型、匿名类
    -keepattributes *Annotation*,InnerClasses,Signature,EnclosingMethod
    
    #表示不混淆声明的两个类,这两个类我们基本也用不上,是接入Google原生的一些服务时使用的
    -keep public class com.google.vending.licensing.ILicensingService
    -keep public class com.android.vending.licensing.ILicensingService
    
    #抛出异常时保留代码行号
    -keepattributes SourceFile,LineNumberTable
    #重命名抛出异常时的文件名称,点击鼠标可以到达错误文件位置
    -renamesourcefileattribute SourceFile
    
    #混淆时是否记录日志
    -verbose
    
    #不混淆R文件中的所有静态字段,以保证正确找到每个资源的id
    -keepclassmembers class **.R$* {
        public static <fields>;
    }
     
    #保留四大组件,自定义的Application等这些类不被混淆
    -keep public class * extends android.app.Activity
    -keep public class * extends android.app.Fragment
    -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.view.View
    
    #处理support包
    -keep class android.support.** {*;}
    -dontnote android.support.**
    -dontwarn android.support.**
    
    #保留继承的
    -keep public class * extends android.support.v4.**
    -keep public class * extends android.support.v7.**
    -keep public class * extends android.support.annotation.**
    
    #保留本地native方法不被混淆
    -keepclasseswithmembernames class * {
        native <methods>;
    }
    
    #保留枚举类不被混淆
    -keepclassmembers enum * {
        public static **[] values();
        public static ** valueOf(java.lang.String);
    }
    
    #保持 Serializable 不被混淆并且enum 类也不被混淆
    -keepclassmembers class * implements java.io.Serializable {
        static final long serialVersionUID;
        private static final java.io.ObjectStreamField[] serialPersistentFields;
        !static !transient <fields>;
        !private <fields>;
        !private <methods>;
        private void writeObject(java.io.ObjectOutputStream);
        private void readObject(java.io.ObjectInputStream);
        java.lang.Object writeReplace();
        java.lang.Object readResolve();
    }
    
    #保留Parcelable序列化类不被混淆
    -keep class * implements android.os.Parcelable {
        public static final android.os.Parcelable$Creator *;
    }
    
    #see http://proguard.sourceforge.net/manual/examples.html#beans
    #不混淆View中的setXxx()和getXxx()方法,以保证属性动画正常工作
    -keep public class * extends android.view.View{
        *** get*();
        void set*(***);
        public <init>(android.content.Context);
        public <init>(android.content.Context, android.util.AttributeSet);
        public <init>(android.content.Context, android.util.AttributeSet, int);
    }
    
    #不混淆Activity中参数是View的方法,例如,一个控件通过android:onClick="clickMethodName"绑定点击事件,混淆后会导致点击事件失效
    -keepclassmembers class * extends android.app.Activity {
       public void *(android.view.View);
    }
    
    #保留Keep注解的类名和方法(最新的proguard-android.txt中包括了这个)
    -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>(...);
    }
    
    #第三方jar包不被混淆
    -keep class com.github.** {*;}
    

    参考文档


    1. 摘抄自百度百科-代码混淆

    2. 摘抄自Android混淆的关键字描述

    相关文章

      网友评论

        本文标题:Android代码混淆

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