android混淆_android混淆打包 - CSDN
精华内容
参与话题
  • Android添加混淆

    千次阅读 2018-05-30 15:54:57
    1.为何要混淆 今天谈起混淆,是因为觉得有些项目必须进行混淆,因为保密性比较高,有些东西被反编译后看到不太好,所以作为一个有责任感的工程师,重要的项目一定要进行混淆,平时我都太懒了,想想很多项目就这样...

    1.为何要混淆

      今天谈起混淆,是因为觉得有些项目必须进行混淆,因为保密性比较高,有些东西被反编译后看到不太好,所以作为一个有责任感的工程师,重要的项目一定要进行混淆,平时我都太懒了,想想很多项目就这样下水了,有点愧疚,网上关于混淆的文章很多,但是呢,将知识总结的简单易懂是不是更受人欢迎呢!

    混淆之后的类,方法,字段,将会重新命名,所以看起来没有原来的易懂,当然混淆只是一般的防护,建议app打包好之后进行加固一下,市场上已经有很多加固软件可以防止反编译,二次打包,都很好,我平时会用360加固助手 ,,可以签名,加固,加固发布的应用,还可以在服务的页面看到应用的奔溃信息。


    2.Android 开启混淆配置

    buildTypes {

    release {

    minifyEnabled true//true开启混淆配置,false关闭

    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

    signingConfig signingConfigs.duqian_android_keystore

    }

    debug{//省略 debug调试的apk是没有混淆的,所以无论你怎么反编译,都看到的是源码,你要检验release包是否混淆。}

    }

    3.Android 混淆的通用规则

    (1)系统混淆配置

    -dontusemixedcaseclassnames #混淆时不使用大小写混合类名

    -dontskipnonpubliclibraryclasses #不跳过library中的非public的类

    -verbose #打印混淆的详细信息

    -dontoptimize #不进行优化,建议使用此选项,

    -dontpreverify #不进行预校验,Android不需要,可加快混淆速度。

    -ignorewarnings #忽略警告

    #-optimizationpasses 5 #指定代码的压缩级别


    (2)常用的一些混淆配置

    -keepattributes Signature #范型
    #native方法不混淆
    -keepclasseswithmembernames class * {
        native <methods>;
    }
    #v4包不混淆
    -keep class android.support.v4.app.** { *; }
    -keep interface android.support.v4.app.** { *; }
    #Gson混淆配置
    -keep class sun.misc.Unsafe { *; }
    -keep class com.idea.fifaalarmclock.entity.***
    -keep class com.google.gson.** { *; }
    #JavaBean
    -keepclassmembers public class cn.net.duqian.bean.** {
       void set*(***);
       *** get*();
    }
    -keep class com.xx.duqian_cloud.JavaScriptInterface { *; }#webview js
    
    #忽略 libiary 混淆
    -keep class io.vov.vitamio.** { *; }
    
    #butterknife不混淆
    -keep class butterknife.** { *; }
    -dontwarn butterknife.internal.**
    -keep class **$$ViewBinder { *; }
    -keepclasseswithmembernames class * {
        @butterknife.* <fields>;
    }
    -keepclasseswithmembernames class * {
        @butterknife.* <methods>;
    }
       (3)第三方框架不混淆,也要看具体情况,不是所有的lib都不能混淆。用了反射的肯定不能混淆。

    -keepclassmembers class * {
       public <init> (org.json.JSONObject);
    }
    #okhttp
    -dontwarn okhttp3.**
    -keep class okhttp3.**{*;}
    -keep interface okhttp3.**{*;}
    
    #okio
    -dontwarn okio.**
    -keep class okio.**{*;}
    -keep interface okio.**{*;}
    
    -dontwarn retrofit2.**
    -keep class retrofit2.** { *; }
    -keepattributes Signature
    -keepattributes Exceptions
    
    -dontwarn rx.**
    -keep class rx.**{*;}

    4.Android的混淆方法和通配符对照表




             5.总结

    Java的反射,为什么不能混淆呢?因为代码混淆,类名、方法名、属性名都改变了,而反射它还是按照原来的名字去反射,结果只射出一个程序崩溃,Crash,一脸的懵逼。

    注解用了反射,所以不能混淆。 不混淆任何包含native方法的类的类名以及native方法名,否则找不到本地方法

    Activity更不能混淆,因为AndroidManifest.xml文件中是完整的名字,混淆后怎么找?

    自定义view也是带了包名写在xml布局中,给我换成a,怎么破? R文件混淆了,id没了,界面崩溃那时自然咯。

    本文没有指定混淆某个类中的某个方法。










    展开全文
  • Android 混淆其实很简单

    千次阅读 2018-08-05 20:07:12
    Android 打出正式的 APK 安装包时,通常为了增加别人反编译后阅读源代码的难度,需要做一些混淆工作。在 Android Studio 中配合 Gradle 很容易完成这个操作。 Proguard 作用 压缩 Shrinking : 默认是开启的...

    简介

    在 Android 打出正式的 APK 安装包时,通常为了增加别人反编译后阅读源代码的难度,需要做一些混淆工作。在 Android Studio 中配合 Gradle 很容易完成这个操作。

    Proguard 作用

    • 压缩 Shrinking : 默认是开启的,移除未被使用的类和成员,并且在 优化Optimization **工作执行后还会再次执行。
    • 优化 Optimization : 默认是开启的,在字节码级别执行优化,让应用运行的更快。
    • 混淆 Obfuscation : 默认是开启的,增大反编译的难度,除了被 keep 保持的类和类成员都会被随机命名。

    它们都是可以在配置文件 proguard-rules.pro 中进行关闭的,比如:

    -dontshrink       # 关闭压缩
    -dontoptimize     # 关闭优化
    -dontobfuscate    # 关闭混淆

    Android 开启混淆

    Android 开启混淆只需在 build.gradle 中配置 minifyEnabled true ,然后在 proguard-rules.pro 加入混淆规则即可。

    android {
        ........
        buildTypes {
            release {
                minifyEnabled true
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    }

    开启混淆后,在打出 release 版包时,会在 build/outputs/mapping/ 目录下生成 mapping.txt 文件,该文件是原始代码和混淆后的代码的一种对应转换关系,我们推导出原始代码名称。

    混淆对应关系

    基本规则

    • 星号 *
    -keep class com.xing.weijian.*
    -keep class com.xing.weijian.**

    (1) 一个 * 号表示只保持该包下的类名不被混淆,而子包下的类名还是会被混淆的。

    一个星号

    (2) 两个 * 号表示该包和所含子包,子包包含的多级子包下的类名都保持不被混淆。

    这里写图片描述

    注意:上面这配置只保持了类名没有被混淆,但是其中的方法和成员变量的名称还是被混淆改变了,如果既想保持类名,又想保持方法和成员变量不被混淆,需要使用以下方式:

    -keep class com.xing.weijian.* {*;}

    保持类名和成员

    同时也能够使用类似 java 的 extends ,implements 等规则进行配置:

    # 保持继承了BaseActivity的public修饰的类名不被混淆
    -keep public class * extends com.xing.weijian.base.BaseActivity 
    
    # 内部类使用 $ 号,保持 TabFragment 中 内部类 OnFragmentData的所有 public 修饰的都不被混淆掉
    -keepclassmembers class com.xing.weijian.TabFragment$OnFragmentData{
        public *;
    }
    • 特定匹配
    <init>   # 匹配所有构造函数
    <fields>  # 匹配所有成员变量
    <methods> # 匹配所有的方法

    可以在它们前面添加 private ,public 进行进一步更精细的限制范围,比如保持 User 类中 所有 public 方法不被混淆:

    -keep class com.xing.weijian.bean.User {
        public <methods>;
    }

    也可以在方法中加入参数进行限定:比如 保持 User 类的 public 修饰,参数是 String 类型的方法不被混淆:

    -keep class com.xing.weijian.bean.User {
        public <methods>(String);
    }
    • keep 与 keepclassmembers , keepclasseswithmembers
    防止被移出或重命名 防止被重命名 保持范围
    -keep -keepnames 类和类成员
    -keepclassmembers -keepclassmembernames 仅类成员
    -keepclasseswithmembers -keepclasseswithmembernames 如果存在某成员,保留该成员和类

    不能设置混淆的方法或成员

    • jni 方法不能混淆,因为这个方法需要和 native 方法保持一致
    -keepclasseswithmembernames class * { # 保持native方法不被混淆    
        native <methods>;
    }
    • 反射用到的类不能混淆
    • Androidmanifest.xml 中的类不能混淆,所以四大组件和 Application子类,Framework 层下所有的类默认是不会进行混淆的。
    • 自定义的 View 默认不会被混淆
    • 与服务端交互解析成的实体对象不能设置混淆,否则不能解析出正确的对象。
    • 引用第三方 SDK 时,需要根据它的文档加入对应的混淆规则。
    • Parceable 子类和 Creator 静态成员变量不能混淆,否则产生异常。

    通用混淆规则

    #--------基本不用动区域--------------------------------------------
    #---------------------------------基本指令区----------------------------------
    -optimizationpasses 5
    -dontskipnonpubliclibraryclassmembers
    -printmapping proguardMapping.txt
    -optimizations !code/simplification/cast,!field/*,!class/merging/*
    -keepattributes *Annotation*,InnerClasses
    -keepattributes Signature
    -keepattributes SourceFile,LineNumberTable
    #----------------------------------------------------------------------------
    
    #---------------------------------默认保留区---------------------------------
    #继承activity,application,service,broadcastReceiver,contentprovider....不进行混淆
    -keep public class * extends android.app.Activity
    -keep public class * extends android.app.Application
    -keep public class * extends android.support.multidex.MultiDexApplication
    -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
    -keep public class com.android.vending.licensing.ILicensingService
    -keep class android.support.** {*;}
    
    -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);
    }
    -keepclasseswithmembers class * {
        public <init>(android.content.Context, android.util.AttributeSet);
        public <init>(android.content.Context, android.util.AttributeSet, int);
    }
    #这个主要是在layout 中写的onclick方法android:onclick="onClick",不进行混淆
    -keepclassmembers class * extends android.app.Activity {
       public void *(android.view.View);
    }
    
    -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 **.R$* {
     *;
    }
    
    -keepclassmembers class * {
        void *(*Event);
    }
    
    -keepclassmembers enum * {
        public static **[] values();
        public static ** valueOf(java.lang.String);
    }
    -keep class * implements android.os.Parcelable {
      public static final android.os.Parcelable$Creator *;
    }
    #// natvie 方法不混淆
    -keepclasseswithmembernames class * {
        native <methods>;
    }
    
    #保持 Parcelable 不被混淆
    -keep class * implements android.os.Parcelable {
      public static final android.os.Parcelable$Creator *;
    }
    #----------------------------------------------------------------------------
    
    #---------------------------------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);
    }
    #----------------------------------------------------------------------------
    #---------------------------------------------------------------------------------------------------
    #---------------------------------实体类---------------------------------
    # 修改成你对应的包名
    -keep class [your_pkg].** { *; }
    .....................
    
    展开全文
  • 混淆的文章其实网上也很多,介绍的都很好,但是关于多个module的混淆规则就不是这么详细,有的也是错误的,经过了2天的多次实践以及查阅资料(多次打包和反编译看源码,很费时间啊),终于达到了我的目的。...

    上一篇博客我们详细介绍了反编译工具jadx的使用方法以及对混淆和加固的对比

    博客中我们提到了混淆。混淆的文章其实网上也很多,介绍的都很好,但是关于多个module的混淆规则就不是这么详细,有的也是错误的,经过了2天的多次实践以及查阅资料(多次打包和反编译看源码,很费时间啊),终于达到了我的目的。下面来总结一下。也希望能帮到需要的同学。

    Android Studio本身集成了ProGuard混淆工具,我们可以通过编辑build.gradle文件来开启混淆并且对代码进行压缩,对资源进行优化等。如下图

    这里写图片描述

    下面是代码,可以直接复制

        buildTypes {
            release {
                minifyEnabled true   //开启混淆
                zipAlignEnabled true  //压缩优化
                shrinkResources true  //移出无用资源
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' //默认的混淆文件以及我们指定的混淆文件
            
            }
    
        }
    

    开启了混淆别忘去proguard-rules.pro文件编辑混淆规则,混淆规则网上也有很多,自行百度即可。

    这里写图片描述

    如果你的项目只有一个app module,那么这样配置混淆就可以了。但是如果你的项目有好几个module,module之间还是相互依赖的,那么该怎么混淆呢?

    混淆方法

    1)在app module中统一配置混淆规则
    我们可以直接在app module中build.gradle文件配置所有module需要混淆的规则。这样,其他module中就无需开启混淆。但是并不推荐使用这种方法,当我们取消依赖某些module的时候,这样很容易造成混淆规则冗余,我们还需要删除掉该module相关的混淆配置,很麻烦。

    2)各个module单独配置混淆规则(推荐)
    我们也可以单独为module配置混淆规则,比较推荐这种做法。每个module管理自己的混淆文件,当我们不依赖该module的时候,就不会发生第一种方法出现的问题了。

    我们把app module称作为主模块,其依赖的其他module称作为子模块

    如图所示。我的app模块是依赖了其他模块的,其他模块也有相互依赖的地方。

    这里写图片描述

    网上很多关于子module的混淆配置是错误的,经过我的多次实践得出,主模块的混淆开关配置会直接影响到子模块,也就是说如果你的主模块开启的混淆,就算你的子模块关闭混淆开关,最终子模块还是会被混淆的。
    其次
    子模块混淆文件的指定是通过consumerProguardFiles这个属性来指定的,并不是proguardFiles 属性,而且我们无需配置其他的选项,只需要配置consumerProguardFiles属性就可以。该属性表示在打包的时候会自动寻找该module下我们指定的混淆文件对代码进行混淆。

    如果我们发布出一些开源库去给别人用,想要对库代码进行混淆的话,也可以通过配置该属性来达到目的

    这里写图片描述

    关于多模块混淆的小技巧

    一般来说,在组件化开发的情况下,app module的代码是很少的,依赖的第三方库也是很少的。我们可以把通用的混淆规则放到app module中。 这样子module就无需配置通用混淆规则,只需要配置一些该module所需要的混淆规则即可。大大减少了混淆代码。

    app module下的混淆规则
    这里给出一个也是从网上找的基本的混淆模板。关于自己项目的实体类和依赖的第三方sdk需要自己添加混淆规则,一般开源库都会给出混淆规则,没有的话就要自己百度了

    #
    #-------------------------------------------基本不用动区域----------------------------------------------
    #
    #
    # -----------------------------基本 -----------------------------
    #
    
    # 指定代码的压缩级别 0 - 7(指定代码进行迭代优化的次数,在Android里面默认是5,这条指令也只有在可以优化时起作用。)
    -optimizationpasses 5
    # 混淆时不会产生形形色色的类名(混淆时不使用大小写混合类名)
    -dontusemixedcaseclassnames
    # 指定不去忽略非公共的库类(不跳过library中的非public的类)
    -dontskipnonpubliclibraryclasses
    # 指定不去忽略包可见的库类的成员
    -dontskipnonpubliclibraryclassmembers
    #不进行优化,建议使用此选项,
    -dontoptimize
     # 不进行预校验,Android不需要,可加快混淆速度。
    -dontpreverify
    
    
    # 屏蔽警告
    -ignorewarnings
    # 指定混淆是采用的算法,后面的参数是一个过滤器
    # 这个过滤器是谷歌推荐的算法,一般不做更改
    -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
    # 保护代码中的Annotation不被混淆
    -keepattributes *Annotation*
    # 避免混淆泛型, 这在JSON实体映射时非常重要
    -keepattributes Signature
    # 抛出异常时保留代码行号
    -keepattributes SourceFile,LineNumberTable
     #优化时允许访问并修改有修饰符的类和类的成员,这可以提高优化步骤的结果。
    # 比如,当内联一个公共的getter方法时,这也可能需要外地公共访问。
    # 虽然java二进制规范不需要这个,要不然有的虚拟机处理这些代码会有问题。当有优化和使用-repackageclasses时才适用。
    #指示语:不能用这个指令处理库中的代码,因为有的类和类成员没有设计成public ,而在api中可能变成public
    -allowaccessmodification
    #当有优化和使用-repackageclasses时才适用。
    #-repackageclasses com.test
    
     # 混淆时记录日志(打印混淆的详细信息)
     # 这句话能够使我们的项目混淆后产生映射文件
     # 包含有类名->混淆后类名的映射关系
    -verbose
    
    #
    # ----------------------------- 默认保留 -----------------------------
    #
    #----------------------------------------------------
    # 保持哪些类不被混淆
    #继承activity,application,service,broadcastReceiver,contentprovider....不进行混淆
    -keep public class * extends android.app.Activity
    -keep public class * extends android.app.Application
    -keep public class * extends android.support.multidex.MultiDexApplication
    -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
    -keep class android.support.** {*;}## 保留support下的所有类及其内部类
    
    -keep public class com.google.vending.licensing.ILicensingService
    -keep public class com.android.vending.licensing.ILicensingService
    #表示不混淆上面声明的类,最后这两个类我们基本也用不上,是接入Google原生的一些服务时使用的。
    #----------------------------------------------------
    
    # 保留继承的
    -keep public class * extends android.support.v4.**
    -keep public class * extends android.support.v7.**
    -keep public class * extends android.support.annotation.**
    
    
    #表示不混淆任何包含native方法的类的类名以及native方法名,这个和我们刚才验证的结果是一致
    -keepclasseswithmembernames class * {
        native <methods>;
    }
    
    
    #这个主要是在layout 中写的onclick方法android:onclick="onClick",不进行混淆
    #表示不混淆Activity中参数是View的方法,因为有这样一种用法,在XML中配置android:onClick=”buttonClick”属性,
    #当用户点击该按钮时就会调用Activity中的buttonClick(View view)方法,如果这个方法被混淆的话就找不到了
    -keepclassmembers class * extends android.app.Activity{
        public void *(android.view.View);
    }
    
    #表示不混淆枚举中的values()和valueOf()方法,枚举我用的非常少,这个就不评论了
    -keepclassmembers enum * {
        public static **[] values();
        public static ** valueOf(java.lang.String);
    }
    
    #表示不混淆任何一个View中的setXxx()和getXxx()方法,
    #因为属性动画需要有相应的setter和getter的方法实现,混淆了就无法工作了。
    -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);
    }
    -keepclasseswithmembers class * {
        public <init>(android.content.Context, android.util.AttributeSet);
        public <init>(android.content.Context, android.util.AttributeSet, int);
    }
    
    #表示不混淆Parcelable实现类中的CREATOR字段,
    #毫无疑问,CREATOR字段是绝对不能改变的,包括大小写都不能变,不然整个Parcelable工作机制都会失败。
    -keep class * implements android.os.Parcelable {
      public static final android.os.Parcelable$Creator *;
    }
    # 这指定了继承Serizalizable的类的如下成员不被移除混淆
    -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();
    }
    # 保留R下面的资源
    -keep class **.R$* {
     *;
    }
    #不混淆资源类下static的
    -keepclassmembers class **.R$* {
        public static <fields>;
    }
    
    
    
    # 对于带有回调函数的onXXEvent、**On*Listener的,不能被混淆
    -keepclassmembers class * {
        void *(**On*Event);
        void *(**On*Listener);
    }
    
    # 保留我们自定义控件(继承自View)不被混淆
    -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);
    }
    
    #
    #----------------------------- 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 *** v(...);
       public static *** d(...);
       public static *** i(...);
       public static *** w(...);
     }
    
    
    
    

    子module下的混淆配置 示例

    只需要配置改module需要的混淆规则即可,注意我这里只是个示例,具体的混淆规则根据你的module来定。

    这里写图片描述

    这样一来,我们就优雅的完成了多module下的混淆配置。

    好了,就这些,希望能帮到你。觉得还行的话点个赞呦。


    如果你觉得本文对你有帮助,麻烦动动手指顶一下,算是对本文的一个认可,如果文中有什么错误的地方,还望指正,转载请注明转自喻志强的博客 ,谢谢!

    展开全文
  • Android混淆总结篇(一)

    万次阅读 2018-03-28 18:46:21
    上个月跟朋友讨论了这么一问题:“项目上线之后由于代码被混淆的缘故,导致收集到的异常信息看着很困难”,刚好最近在复习混淆方面的知识,在总结混淆的知识点的同时,顺便探讨总结下这问题。项目上线肯定避免不了的...

    前言

    这阵子自己的心又长草了,静不下来~又挺迷茫的!在这个纷纷跳槽的季节,感觉还是应该让自己静下心来多学习学习。还是写写博客,总结总结~梳理下心里的野草。

    上个月跟朋友讨论了这么一问题:“项目上线之后由于代码被混淆的缘故,导致收集到的异常信息看着很困难”,刚好最近在复习混淆方面的知识,在总结混淆的知识点的同时,顺便探讨总结下这问题。项目上线肯定避免不了的是对项目进行混淆、打包、签名和发布,可能还有APK加固等等,其实这流程并不复杂,都有一套明确的流程,所以整起来也不是很困难。而上面提到的“混淆导致上线后的异常信息查看起来挺困难”这问题,这几天也大概探讨完,打算记录在下篇文章~~那么这篇文章先开始扯淡吧!


    Ⅰ.简述

    混淆的概念:将Android项目进行打包之时,可以将项目里的包名、类名、变量名进行更改,使得代码不容易泄露,类似于对其apk中的文件加密.

    混淆的作用

    • 1.增加Apk反编译之后代码泄露的困难性
    • 2.生成的apk体积会缩小

    什么是混淆?

    Android SDK 本身就提供混淆的功能,将混淆开关进行开启后,开发者需要做的是对Android Studio工程项目中的proguard-rules.pro文件进行混淆白名单的配置.

    那么什么是混淆白名单呢?其实就是指定一些包名、类名、变量等不可以被混淆。假设没指定白名单就进行混淆打包,而某某类的类名被混淆了(假设变成了a),那么可能其他引用或使用该类的类就找不到该类,说不定应用就会因此崩溃或是导致相应的功能无法使用.

    那么所谓的混淆也就是配置混淆白名单,那么下面看看混淆之后的apk的内部结构.可以看到红圈圈出来的部分都是进行混淆的,而有部分是没有进行混淆的,比如黑圈圈出来的属性动画兼容库nineoldandroids,其包名类名就没有变成abc这样的代替符

    这里写图片描述

    上面我是用apk逆向助手对apk进行反编译,市场上的反编译工具有很多种,可以自行Google搜索。

    补充

    本篇文章记录的混淆知识点主要基于Android Studio开发工具。


    Ⅱ.开始混淆

    1.开启混淆开关

    混淆的开关在项目/app/build.gradle文件里,看下面的截图,将minifyEnabled设置为true就是开启混淆,关于下面的配置代码可以直接写在build.gradle文件的android节点下

    这里写图片描述

    代码混淆一般是在上线前的apk打包才会去配置混淆开启,要是忘记配置的代码,那怎么办呢?直接进去Project Structrue,然后根据下面截图所标识的进行设置,如此这般,只要打release包就是开启混淆进行打包的.

    这里写图片描述

    2.设置混淆白名单

    基于Android Studio创建的项目里有一文件名称为”proguard-rules.pro”的文件,路径是”项目/app/proguard-rules.pro”,没经过编辑之前,里面只有一些注释的代码,如下图

    这里写图片描述

    那么设置的混淆白名单又该怎么写呢?Google搜索的话会有很多博客上的模板可以复制进行套用.如下图,那么就可以进行参考,下面第三部分将常用的混淆指令和对应的注释都列举出来,基本常用的都有,有疏漏的那就自行搜索下.

    这里写图片描述


    Ⅲ.实际混淆指令

    在应用中,大多数的混淆指令是已经确定的了,比如下面的基本指令部分,基本不用修改的。而其他的混淆指令,比如第三方的SDK/框架的混淆指令一般在其官方文档都可以找到,所以相对来说还是比较方便的,下面将这几天归类的混淆指令总结下.

    基本指令:

        # 设置混淆的压缩比率 0 ~ 7
        -optimizationpasses 5
        # 混淆后类名都为小写   Aa aA
        -dontusemixedcaseclassnames
        # 指定不去忽略非公共库的类
        -dontskipnonpubliclibraryclasses
        #不做预校验的操作
        -dontpreverify
        # 混淆时不记录日志
        -verbose
        # 混淆采用的算法.
        -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
        #保留代码行号,方便异常信息的追踪
        -keepattributes SourceFile,LineNumberTable
    
        #dump文件列出apk包内所有class的内部结构
        -dump class_files.txt        
        #seeds.txt文件列出未混淆的类和成员
        -printseeds seeds.txt
        #usage.txt文件列出从apk中删除的代码
        -printusage unused.txt
        #mapping文件列出混淆前后的映射
        -printmapping mapping.txt
    

    避免混淆Android基本组件,下面是兼容性比较高的规则:

    -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
    
    #不提示V4包下错误警告
    -dontwarn android.support.v4.**
    #保持下面的V4兼容包的类不被混淆
    -keep class android.support.v4.**{*;}

    避免混淆所有native的方法,涉及到C、C++

    -keepclasseswithmembernames class * {
            native <methods>;
    }

    避免混淆自定义控件类的get/set方法和构造函数

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

    避免混淆枚举类

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

    避免混淆序列化类

        #不混淆Parcelable和它的实现子类,还有Creator成员变量
        -keep class * implements android.os.Parcelable {
          public static final android.os.Parcelable$Creator *;
        }
    
        #不混淆Serializable和它的实现子类、其成员变量
        -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();
        }

    避免混淆JSON类的构造函数

        #使用GSON、fastjson等框架时,所写的JSON对象类不混淆,否则无法将JSON解析成对应的对象
        -keepclassmembers class * {
            public <init>(org.json.JSONObject);
        }
    

    避免混淆第三方SDK

        # ==================环信混淆start=================
        -keep class com.hyphenate.** {*;}
        -dontwarn  com.hyphenate.**
        # ==================环信end======================
    
        # ==================bugly start==================
        -dontwarn com.tencent.bugly.**
        -keep public interface com.tencent.**
        -keep public class com.tencent.** {*;}
        -keep public class com.tencent.bugly.**{*;}
        # ==================bugly end====================
    
        # ===============百度定位 start====================
        -keep class vi.com.gdi.** { *; }
        -keep public class com.baidu.** {*;}
        -keep public class com.mobclick.** {*;}
        -dontwarn com.baidu.mapapi.utils.*
        -dontwarn com.baidu.platform.comapi.b.*
        -dontwarn com.baidu.platform.comapi.map.*
        # ===============百度定位 end======================
    
        //备注:其他的第三方包的混淆指令可以到其官方文档去拷贝

    避免混淆第三方框架

        # ==================picasso框架 start===============
        -keep class com.parse.*{ *; }
        -dontwarn com.parse.**
        -dontwarn com.squareup.picasso.**
        -keepclasseswithmembernames class * {
            native <methods>;
        }
        # ==================picasso end====================
    
        # ==================EventBus start=================
        -keep class org.greenrobot.** {*;}
        -keep class de.greenrobot.** {*;}
        -keepclassmembers class ** {
            public void onEvent*(**);
            void onEvent*(**);
        }
        # ==================EventBus end===================
    
        # ==================okhttp start===================
        -dontwarn com.squareup.okhttp.**
        -keep class com.squareup.okhttp.** { *;}
        -dontwarn okio.**
        -keep class okio.**{*;}
        -keep interface okio.**{*;}
        # ==================okhttp end=====================
    
        //备注:其它框架的混淆指令可以到其官方文档去拷贝   

    其它混淆指令

        #避免混淆属性动画兼容库
        -dontwarn com.nineoldandroids.*
        -keep class com.nineoldandroids.** { *;}    
    
        #不混淆泛型
        -keepattributes Signature
    
        #避免混淆注解类
        -dontwarn android.annotation
        -keepattributes *Annotation*
    
        #避免混淆内部类
        -keepattributes InnerClasses
    
        #避免混淆实体类,修改成你对应的包名
        -keep class com.wyk.test.bean.** { *; }
        -keep class com.wyk.test.event.** { *; }
        -keep public class com.wyk.test.utils.eventbus.** { *;}
    
        #避免混淆Rxjava/RxAndroid
        -dontwarn sun.misc.**
        -keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {
         long producerIndex;
         long consumerIndex;
        }
        -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {
         rx.internal.util.atomic.LinkedQueueNode producerNode;
        }
        -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {
         rx.internal.util.atomic.LinkedQueueNode consumerNode;
        }
    
    #避免混淆js相关的接口
    -keepattributes *JavascriptInterface*
    -keep class com.wyk.test.js.** { *; }
    

    Ⅳ.混淆配置注意点

    1.假设当配置 “-libraryjars libs/jpush-android-2.1.6.jar” 对jar包进行混淆白名单化,如果gradle报错的话,可以考虑注释掉(格式:-libraryjars [jar包名])这样的配置信息.采用下面的配置信息进行替换

     -dontwarn cn.jpush.**
     -keep class cn.jpush.** { *; }

    2.下面是对属性动画兼容库的混淆白名单配置信息,刚开始觉得只是保持com.nineoldandroids包下的类不被混淆,后来经过反编译混淆后的apk包,发现效果是”不混淆该class com.nineoldandroids包下的类、子包和子包的类,也不混淆其中类的成员变量.

    -keep class com.nineoldandroids.** { *;}       

    Ⅴ.其它

    1.混淆套用模板

    个人觉得下面链接的博文就写得非常好,所以可以进行参考.

    参考博文:5分钟搞定android混淆

    2.资源混淆

    Proguard混淆只是针对代码进行混淆,解压之后的apk包还是能看到项目的资源文件和其名称,比如布局、logo图片等等.这时可以选择对资源文件进行混淆,下面两个链接是腾讯推出的资源混淆工具相关的博文,可以参考.

    资源混淆工具相关的博文

    http://bugly.qq.com/bbs/forum.php?mod=viewthread&tid=42
    https://github.com/shwenzhang/AndResGuard/blob/master/README.zh-cn.md

    3.加固

    为了使得apk更加不容易被破解,混淆之后还可以对apk进行加固,现今市面上的加固技术有很多种,有360加固、爱加密加固、梆梆加固等等,可以自行选择,加固技术就相当于给apk包加多一个壳,相应的体积也会增大,大概增大1M~2M左右,需要的话可以自行搜索,加固还是挺简单的.

    4.参考链接

    http://blog.csdn.net/maxwell_nc/article/details/51998766
    http://blog.csdn.net/chen930724/article/details/49687067
    http://blog.csdn.net/lovexjyong/article/details/24652085
    http://www.jianshu.com/p/f3455ecaa56e

    5.睡觉 ing~~~

    展开全文
  • Android混淆总结篇

    千次阅读 2018-04-02 10:29:37
    Android混淆总结篇Ⅰ.简述混淆的概念:将Android项目进行打包之时,可以将项目里的包名、类名、变量名进行更改,使得代码不容易泄露,类似于对其apk中的文件加密.混淆的作用:1.增加Apk反编译之后代码泄露的困难性 2....
  • Android Studio 代码混淆(包教包会)

    万次阅读 多人点赞 2019-10-28 16:49:47
    android使用的ProGuard,可以起到压缩,混淆,预检,优化的作用。 代码混淆技术基本原理是使反编译工具反编译出来的代码人难以阅读,从而达到防止被逆向破解的目的。其实还有一个重要的功能,就是能apk瘦身,混淆...
  • android混淆

    千次阅读 2018-08-14 14:20:54
    上个月跟朋友讨论了这么一问题:“项目上线之后由于代码被混淆的缘故,导致收集到的异常信息看着很困难”,刚好最近在复习混淆方面的知识,在总结混淆的知识点的同时,顺便探讨总结下这问题。项目上线肯定避免不了的...
  • 一、前期基础知识详解 ...测试了很久最后确认是混淆文件出了问题,之前项目中使用的混淆文件是原来开源项目带的,而上传功能是后来自己写的,而加了功能之后,没有对修改混淆文件。上传的功能中用到了Gson来实...
  • Android混淆

    千次阅读 2019-07-05 09:50:56
    Android 日常开发过程中,混淆是我们开发 App 的一项必不可少的技能。只要是我们亲身经历过 App 打包上线的过程,或多或少都需要了解一些代码混淆的基本操作。那么,混淆到底是什么?它的好处有哪些?具体效果...
  • android混淆规则笔记

    2020-01-21 15:20:50
    写在前面 混淆其实是包括了代码压缩、代码混淆以及资源压缩等的优化过程。依靠 ProGuard,混淆流程将...而依靠 Gradle 的 Android 插件,我们将移除未被使用的资源,可以有效减小 apk 安装包大小。 https://www.j...
  • android 混淆

    2015-10-02 20:53:55
    原文链接:http://www.eoeandroid.com/thread-173733-1-1.html 我怕自己忘记一些东西,故而记录一些东西。 ...转Android Java混淆(ProGuard) http://www.eoeandroid.com/thread-10933
  • Android混淆打包总结

    千次阅读 2016-05-05 15:51:38
    Android 混淆打包Android Studio和Eclipse虽然是两个不同的工具,混淆的使用虽然不同,但规则相同。Eclipse混淆在eclipse中,文件根目录中有如下两个文件projiect.properties和proguard-project.txt。 开启混淆打包...
  • 今天说说Android原生的混淆,原生项目即将上线,伴随着整体功能的完成和完善,一些涉及安全和自我保护以及优化的问题被提到日程上。混淆恰恰能解决的就是我们的APP代码的保护以及优化的问题。前言: 因为互联网环境...
  • Android混淆规则介绍

    千次阅读 2019-04-24 16:04:00
    Android混淆规则介绍 写在前面的话 APP上线推广,免不得是需要混淆加固的,况且劳动成果不易又会有谁希望自己的APP被破解抄袭呢。鉴于此方显本片文章的通用型和重要意义。 混淆简介 Android代码混淆是一种应用...
  • android混淆与反射

    千次阅读 2014-11-21 18:33:51
    android混淆与反射 Android包4.0(好像是4.0)以后混淆更加简单   1、在project.properties.txt将以下内容注释去掉 proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-...
  • Android 混淆

    千次阅读 2016-01-19 15:51:07
    虽然做了几年开发,但混淆在前两个公司还真没有接触过,被领导一问,“没做过?”感觉耳朵都红了,⊙﹏⊙b汗,赶紧补习了下,再此做个记录,希望遇到对混淆同样不了解的人能有所帮助。 不经混淆的代码,apk反编译就...
  • 5分钟搞定android混淆

    千次阅读 2016-07-07 18:34:08
    android使用的ProGuard,可以起到压缩,混淆,预检,优化的作用。但是很多童鞋还没有掌握正确的写混淆文件的姿势。我希望搞个模板化的东西,让大家轻松搞定混淆。那么,开始写一个项目的混淆吧。。。我是不是很直接...
  • Android 混淆代码总结

    万次阅读 多人点赞 2015-05-25 09:21:50
    Android 混淆代码总结
  • android混淆打包

    2019-05-15 17:53:12
    为什么要加代码混淆 --------------------不想开源应用,为了加大反编译的成本,但是并不能彻底防止反编译 开启混淆 通常我们需要找到项目路径下app目录下的build.gradle文件 找到minifyEnabled这个配置,...
  • Android 混淆机制详解

    2018-08-21 16:12:34
    前言 混淆是增加逆向工程和破解的难度,防止App知识产权被窃取的一个有力手段,高级的代码混淆甚至可以有效地保护存储在客户端的密钥,同时混淆也有很多要注意...java 代码的混淆Android 中是最为常见的一种混淆...
1 2 3 4 5 ... 20
收藏数 45,556
精华内容 18,222
关键字:

android混淆