Android 混淆

	Android中的混淆可以分为两个部分:
	* Java代码的优化与混淆,依靠proguard混淆器来实现
	* 另一种是资源压缩,移除项目及依赖库中未被使用的资源

一、Proguard规则

1.1基本指令

  • -ignorewarning:是否忽略警告
  • -optimizationpasses n:指定代码的压缩级别(在0~7之间,默认为5)
  • -dontusemixedcaseclassnames:是否使用大小写混合(windows大小写不敏感,建议加入)
  • -dontskipnonpubliclibraryclasses:是否混淆非公共的库的类
  • -dontskipnonpubliclibraryclassmembers:是否混淆非公共的库的类的成员
  • -dontpreverify:混淆时是否做预校验(Android不需要预校验,去掉可以加快混淆速度)
  • -verbose:混淆时是否记录日志(混淆后会生成映射文件)
  • -obfuscationdictionary dictionary_path:指定外部模糊字典
  • -classobfuscationdictionary dictionary_path:指定class模糊字典
  • -packageobfuscationdictionary dictionary_path:指定package模糊字典
  • -optimizations !code/simplification/arithmetic,!field/,!class/merging/,!code/allocation/variable:混淆时所采用的算法(谷歌推荐算法)
  • -libraryjars libs(*.jar;):添加支持的jar(引入libs下的所有jar包)
  • -renamesourcefileattribute SourceFile:将文件来源重命名为“SourceFile”字符串
  • -keepattributes Annotation:保持注解不被混淆
  • -keep class * extends java.lang.annotation.Annotation {*;}:保持注解不被混淆
  • -keep interface * extends java.lang.annotation.Annotation { *; }:保持注解不被混淆
  • -keepattributes Signature:保持泛型不被混淆
  • -keepattributes EnclosingMethod:保持反射不被混淆
  • -keepattributes Exceptions:保持异常不被混淆
  • -keepattributes InnerClasses:保持内部类不被混淆
  • -keepattributes SourceFile,LineNumberTable:抛出异常时保留代码行号

二、keep命令

  1. 不混淆某个类
    -keep public class com.android.proguard.example.Test { *; }
  2. 不混淆某个包的所有类
    -keep class com.android.proguard.example.** { *; }
  3. 不混淆某个类的子类
    -keep public class * extends com.android.proguard.example.Test { *; }
  4. 不混淆所有类名中包含了“model”的类及其成员
    -keep public class **.*model*.** {*;}
  5. 不混淆某个接口的实现
    -keep class * implements com.android.proguard.example.TestInterface { *; }
  6. 不混淆某个类的构造方法
-keepclassmembers class com.android.proguard.example.Test {
    public <init>();
}
  1. 不混淆某个类的特定的方法
-keepclassmembers class com.android.proguard.example.Test {
    public void test(java.lang.String);
}
  1. 不混淆某个类的内部类
-keep class com.android.proguard.example.Test$* {
        *;
 }

2.2.1 保持基本组件不被混淆

-keep public class * extends android.app.Fragment
-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

2.2.2 保持 Google 原生服务需要的类不被混淆

-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService

2.2.3 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.**

2.2.4 保持 native 方法不被混淆

-keepclasseswithmembernames class * { ####
    native <methods>;
}

2.2.5 保留自定义控件(继承自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);
}

2.2.6 保留指定格式的构造方法不被混淆

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

2.2.7 保留在Activity中的方法参数是view的方法(避免布局文件里面onClick被影响)

-keepclassmembers class * extends android.app.Activity {
    public void *(android.view.View);
}

2.2.8 保持枚举 enum 类不被混淆

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

2.2.9 保持R(资源)下的所有类及其方法不能被混淆

-keep class **.R$* { *; }

2.2.10 保持 Parcelable 序列化的类不被混淆(注:aidl文件不能去混淆)

-keep class * implements android.os.Parcelable {
    public static final android.os.Parcelable$Creator *;
}

2.2.11 需要序列化和反序列化的类不能被混淆(注:Java反射用到的类也不能被混淆)

-keepnames class * implements java.io.Serializable

2.2.12 保持 Serializable 序列化的类成员不被混淆

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

2.2.13 保持 BaseAdapter 类不被混淆

-keep public class * extends android.widget.BaseAdapter { *; }

2.2.14 保持 CusorAdapter 类不被混淆

-keep public class * extends android.widget.CusorAdapter{ *; }

三、资源保持规则

3.1 keep.xml

shrinkResources true开启资源压缩后,所有未被使用的资源默认被移除。假如你需要定义哪些资源必须被保留,在res/raw/路径下创建一个xml文件,例如keep.xml。 通过一些属性的设置可以实现定义资源保持的需求,可配置的属性有:

  • tools:keep 定义哪些资源需要被保留(资源之间用“,”隔开)
  • tools:discard 定义哪些资源需要被移除(资源之间用“,”隔开)
  • tools:shrinkMode 开启严格模式 当代码中通过 Resources.getIdentifier() 用动态的字符串来获取并使用资源时,普通的资源引用检查就可能会有问题。例如,如下代码会导致所有以“img_”开头的资源都被标记为已使用。
String name = String.format("img_%1d", angle + 1);
res = getResources().getIdentifier(name, "drawable", getPackageName());

我们可以设置 tools:shrinkMode 为 strict 来开启严格模式,使只有确实被使用的资源被保留。 以上就是自定义资源保持规则相关的配置,举个例子:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
    tools:keep="@drawable/img_*,@drawable/ic_launcher,@layout/layout_used*"
    tools:discard="@layout/layout_unused"
    tools:shrinkMode="strict"/>

3.2 移除替代资源

一些替代资源,例如多语言支持的 strings.xml,多分辨率支持的 layout.xml 等,在我们不需要使用又不想删除掉时,可以使用资源压缩将它们移除。 我们使用 resConfig 属性来指定需要支持的属性,例如

android {
    defaultConfig {
        ...
        resConfigs "en", "zh"
    }
}

其他未显式声明的语言资源将被移除。

四、Proguard的使用

4.1 开启混淆

在项目的可执行工程Module中打开build.gradle文件进行编辑:

android {
    ......
    defaultConfig {
        ......
    }
    buildTypes {
        release {
            minifyEnabled true      // 开启代码混淆
            zipAlignEnabled true    // 开启Zip压缩优化
            shrinkResources true    // 移除未被使用的资源
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    ......
}

minifyEnabled:是否进行代码混淆
zipAlignEnabled:是否进行Zip压缩优化
shrinkResources:是否移除未被使用的资源
proguardFiles:混淆规则配置文件
proguard-android.txt:AndroidStudio默认自动导入的规则,这个文件位于Android SDK根目录\tools\proguard\proguard-android.txt。这里面是一些比较常规的不能被混淆的代码规则。
proguard-rules.pro:针对自己的项目需要特别定义的混淆规则,它位于项目每个Module的根目录下面,里面的内容需要我们自己编写。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android混淆是一种通过对代码进行重命名和优化来增加应用程序安全性和性能的技术。在Android开发中,可以使用自带的混淆工具来进行代码混淆。默认情况下,Android SDK提供了一些默认的混淆文件,如proguard-android.txt或proguard-android-optimize.txt。这些文件包含了一些常用的混淆命令,可以对代码进行混淆处理。如果需要对自定义的混淆进行配置,可以在proguard-rules.pro文件中进行设置。\[1\] 在进行混淆时,需要注意不要混淆Activity中参数是View的方法。因为在Android开发中,有一种常见的用法是在XML中配置android:onClick属性,当用户点击按钮时,会调用Activity中的对应方法,例如buttonClick(View view)。如果这个方法被混淆,就无法找到对应的方法了。为了避免这种情况,可以使用如下混淆命令来保留Activity中参数是View的方法:-keepclassmembers class * extends android.app.Activity { public void *(android.view.View); }\[2\] 此外,还可以使用一些通用的混淆命令来保留Android中的一些常用类,例如Activity、Application、Service、BroadcastReceiver和ContentProvider:-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\[3\] 通过使用混淆技术,可以有效地保护Android应用程序的代码安全性,并提高应用程序的性能。 #### 引用[.reference_title] - *1* [Android:代码混淆概念整理](https://blog.csdn.net/qjyws/article/details/126488356)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Android--混淆配置(比较详细的混淆规则)](https://blog.csdn.net/weixin_42602900/article/details/127671586)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值