Android 代码混淆

一、代码混淆的定义

Java 是一种跨平台的、解释型语言。Java 源码编译成中间”字节码”存储于 class 文件里。因为跨平台的须要,Java 字节码中包含了非常多源码信息。如变量名、方法名。而且通过这些名称来訪问变量和方法,这些符号带有很多语义信息,非常easy被反编译成 Java 源码。

为了防止这样的现象,我们能够使用 Java 混淆器对 Java 字节码进行混淆。

混淆就是对公布出去的程序进行又一次组织和处理,使得处理后的代码与处理前代码完毕同样的功能。而混淆后的代码非常难被反编译,即使反编译成功也非常难得出程序的真正语义。

被混淆过的程序代码,仍然遵照原来的档案格式和指令集,执行结果也与混淆前一样,仅仅是混淆器将代码中的全部变量、函数、类的名称变为简短的英文字母代号。在缺乏对应的函数名和程序凝视的况下,即使被反编译,也将难以阅读。

同一时候混淆是不可逆的,在混淆的过程中一些不影响正常执行的信息将永久丢失。这些信息的丢失使程序变得更加难以理解。

混淆器的作用不不过保护代码,它也有精简编译后程序大小的作用。因为以上介绍的缩短变量和函数名以及丢失部分信息的原因。 编译后 jar 文件体积大约能降低25% ,这对当前费用较贵的无线网络传输是有一定意义的。

二、混淆文件 proguard.cfg 參数具体解释

<span style="font-size:14px;">-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 <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 *;
}

-keep class MyClass;                                                            # 保持自己定义的类不被混淆</span>

三、代码混淆的方法

依据 SDK 的版本号不同有 2 中不同的代码混淆方式。以上的 proguard.cfg 參数具体解释中所涉及到的信息是在较低版本号SDK 下的混淆脚本,其实在高版本号的 SDK 下混淆的原理和參数也与低版本号的相差无几,仅仅是在不同 SDK 版本号的环境下引入混淆脚本的方式有所不同。

具体方法例如以下:

  • 低版本号 SDK 下,项目中同一时候包括 proguard.cfg  project.properties 文件。则仅仅需在 project.properties 文件末尾加入 proguard.config=proguard.cfg 再将项目 Export 就可以。
  • 高版本号 SDK 下,项目中同一时候包括 proguard-project.txt  project.properties 文件,这时须要在 proguard-project.txt 文件里进行例如以下信息的配置,然后再将项目 Export 就可以

    以下以真实的文件进行演示说明。

<span style="font-size:14px;"># This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt

proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt

# Project target.
target=android-16</span>
四、保留某些包不混淆

以上的配置信息即是 project.properties 文件里内容,蓝色文字为我们在代码混淆过程中须要加入的配置信息。当中:sdk.dir 为你在当前机器上 SDK 的安装路径

假设想保留某个包下的文件不被混淆,能够在 proguard-project.txt 文件里增加保留相应包名的语句就可以。

<span style="font-size:14px;"># 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:

-dontwarn com.cnki.android.cnkireader.** 
-keep class com.cnki.android.cnkireader.** { *; }

# 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 *;
#}</span>

原文地址:https://www.cnblogs.com/mfmdaoyou/p/6685578.html