Android studio代码混淆

一、简介:

大家应该知道有些工具比如apktool,dextojar等是可以对我们android安装包进行反编译,获得源码的。为了减少被别人破解,导致源码泄露,程序被别人盗取代码,等等。我们需要对代码进行混淆,android的sdk中为我们提供了ProGrard这个工具,可以对代码进行混淆(一般是用无意义的名字来重命名),以及去除没有使用到的代码,对程序进行优化和压缩,这样可以增加你想的难度。最近我做的项目,是我去配置的混淆配置,因此研究了一下,这里分享一下。

在build.gradle中进行配置
minifyEnabled true 表示编译时会混淆代码

buildTypes {
        //开发调试的时候有效
        debug {
            // 显示Log
            buildConfigField "boolean", "LOG_DEBUG", "true"
            minifyEnabled false
            zipAlignEnabled true
            shrinkResources true
        }
        //打包的时候使用
        release {
            // 不显示Log
            buildConfigField "boolean", "LOG_DEBUG", "false"
            //混淆
            minifyEnabled true
            //Zipalign优化
            zipAlignEnabled true
            // 移除无用的resource文件
            shrinkResources true
            //加载混淆配置文件
            //proguard-android.txt为默认的混淆文件
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

一些常用包的Proguard配置,在proguard-rules.pro中配置,以下是基本的配置

# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in E:\SDK\sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# 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 *;
#}
-dontskipnonpubliclibraryclasses # 不忽略非公共的库类
-optimizationpasses 5            # 指定代码的压缩级别
-dontusemixedcaseclassnames      # 是否使用大小写混合
-dontpreverify                   # 混淆时是否做预校验
-verbose                         # 混淆时是否记录日志
-keepattributes *Annotation*     # 保持注解
-ignorewarning                   # 忽略警告
-dontoptimize                    # 优化不优化输入的类文件

-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
-keep public class * extends android.app.Fragment
#如果有引用v4包可以添加下面这行
-keep public class * extends android.support.v4.app.Fragment

#生成日志数据,gradle build时在本项目根目录输出
-dump class_files.txt            #apk包内所有class的内部结构
-printseeds seeds.txt            #未混淆的类和成员
-printusage unused.txt           #打印未被使用的代码
-printmapping mapping.txt        #混淆前后的映射

-keep public class * extends android.support.** #如果有引用v4或者v7包,需添加
-libraryjars libs/xxx.jar        #混淆第三方jar包,其中xxx为jar包名
-keep class com.xxx.**{*;}       #不混淆某个包内的所有文件
-dontwarn com.xxx**              #忽略某个包的警告
-keepattributes Signature        #不混淆泛型
-keepnames class * implements java.io.Serializable #不混淆Serializable

-keepclassmembers class **.R$* { #不混淆资源类
  public static <fields>;
}
-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 *;
}

ProGuard配置

上面说到android为我们提供了两个默认的配置文件,在其中,我们可以看到他的一些语法。本节进行描述。

保留选项(配置不进行处理的内容)

  • -keep {Modifier} {class_specification} 保护指定的类文件和类的成员

  • -keepclassmembers {modifier} {class_specification} 保护指定类的成员,如果此类受到保护他们会保护的更好

  • -keepclasseswithmembers {class_specification} 保护指定的类和类的成员,但条件是所有指定的类和类成员是要存在。

  • -keepnames {class_specification} 保护指定的类和类的成员的名称(如果他们不会压缩步骤中删除)

  • -keepclassmembernames {class_specification} 保护指定的类的成员的名称(如果他们不会压缩步骤中删除)

  • -keepclasseswithmembernames {class_specification} 保护指定的类和类的成员的名称,如果所有指定的类成员出席(在压缩步骤之后)

  • -printseeds {filename} 列出类和类的成员-keep选项的清单,标准输出到给定的文件

压缩

  • -dontshrink 不压缩输入的类文件

  • -printusage {filename}

  • -whyareyoukeeping {class_specification}

优化

  • -dontoptimize 不优化输入的类文件

  • -assumenosideeffects {class_specification} 优化时假设指定的方法,没有任何副作用

  • -allowaccessmodification 优化时允许访问并修改有修饰符的类和类的成员

混淆

  • -dontobfuscate 不混淆输入的类文件

  • -obfuscationdictionary {filename} 使用给定文件中的关键字作为要混淆方法的名称

  • -overloadaggressively 混淆时应用侵入式重载

  • -useuniqueclassmembernames 确定统一的混淆类的成员名称来增加混淆

  • -flattenpackagehierarchy {package_name} 重新包装所有重命名的包并放在给定的单一包中

  • -repackageclass {package_name} 重新包装所有重命名的类文件中放在给定的单一包中

  • -dontusemixedcaseclassnames 混淆时不会产生形形色色的类名

  • -keepattributes {attribute_name,…} 保护给定的可选属性,例如LineNumberTable, LocalVariableTable, SourceFile, Deprecated, Synthetic, Signature, and InnerClasses.

  • -renamesourcefileattribute {string} 设置源文件中给定的字符串常量

后面的文件名,类名,或者包名等可以使用占位符代替
?表示一个字符
可以匹配多个字符,但是如果是一个类,不会匹配其前面的包名

  • 可以匹配多个字符,会匹配前面的包名。

在android中在android Manifest文件中的activity,service,provider, receviter,等都不能进行混淆。一些在xml中配置的view也不能进行混淆,android提供的默认配置中都有。

    原文作者:唠嗑008
    原文地址: https://www.jianshu.com/p/cf2bcc0348ec
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞