当前位置:   article > 正文

安卓代码混淆_android 混淆配置 lib库

android 混淆配置 lib库

AAR包混淆方案

  1. 将所有需要对外暴露的方法所在类统一移动到一个文件夹中。
  2. 对于暴露出来的包名,类名及方法名,需手动修改,例如:per.amon.lib.api
  3. 在 proguard-rules.pro 文件中,添加如下代码
-keep class per.amon.module.lib.** { *; }
  • 1
  1. 开启代码混淆
    开启代码混淆方式
buildTypes {
    release {
        // 1、是否进行混淆
        minifyEnabled true
        // 2、开启zipAlign可以让安装包中的资源按4字节对齐,这样可以减少应用在运行时的内存消耗
        zipAlignEnabled true
        // 3、移除无用的resource文件:当ProGuard 把部分无用代码移除的时候,        
        // 这些代码所引用的资源也会被标记为无用资源,然后系统通过资源压缩功能将它们移除。        
        // 需要注意的是目前资源压缩器目前不会移除values/文件夹中定义的资源(例如字符串、尺寸、样式和颜色)
        // 目前项目中用不到,设置成false 或不添加下方属性,仅做了解
        // shrinkResources false
        // 4、混淆文件的位置,其中 proguard-android.txt 为sdk默认的混淆配置,
        // 它的位置位于android-sdk/tools/proguard/proguard-android.txt,
        // 此外,proguard-android-optimize.txt 也为sdk默认的混淆配置,
        // 但是它默认打开了优化开关。并且,我们可在配置混淆文件将android.util.Log置为无效代码,
        // 以去除apk中打印日志的代码。而 proguard-rules.pro 是该模块下的混淆配置。
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

代码反编译查看混淆结果

选择release版本
Android studio 左侧工具栏 -》Build Variants -》 主模块的 Active Build Variant 选择 release
构建APK或AAR
Android studio 顶部工具栏 -》Build -》 Build Bundle(s)/APK(s) -> Build APK

Android studio 右侧工具栏 -》Gradle -》双击运行 项目名/模块名/Tasks/build/assemble

混淆结果映射表路径

在app/build/outputs/mapping/release/目录下
mapping.txt提供混淆前后类、方法、类成员等的对照表
seeds.txt列出没有被混淆的类和成员
usage.txt列出被移除的代码
混淆结果查看方式

  1. 结果在 app/build/outputs/apk/release/app-release.apk 或 app/build/outputs/aar/module-release.aar
  2. 在文件管理器中打开,遇到aar或apk等,直接把后缀改成zip解压,之后把class.dex或class.jar用android studio打开
  3. 混淆结果
    暂时无法在飞书文档外展示此内容

代码混淆相关知识

代码混淆是包含了代码压缩、优化、混淆等一系列行为的过程。如上图所示,混淆过程会有如下几个功能:

  1. 压缩。移除无效的类、类成员、方法、属性等;默认开启,用以减小应用体积,移除未被使用的类和成员,并且会在优化动作执行之后再次执行(因为优化后可能会再次暴露一些未被使用的类和成员)
    -dontshrink 关闭压缩
  2. 优化。分析和优化方法的二进制代码;根据proguard-android-optimize.txt中的描述,优化可能会造成一些潜在风险,不能保证在所有版本的Dalvik上都正常运行。
    -dontoptimize 关闭优化
    -optimizationpasses n 表示proguard对代码进行迭代优化的次数,Android一般为5
  3. 混淆。把类名、属性名、方法名替换为简短且无意义的名称;
    -dontobfuscate 关闭混淆
  4. 预校验。添加预校验信息。这个预校验是作用在Java平台上的,Android平台上不需要这项功能,去掉之后还可以加快混淆速度。

proguardFiles getDefaultProguardFile(‘proguard-android.txt’), ‘proguard-rules.pro’
这行代码定义了混淆规则由两部分构成:位于 SDK 的 tools/proguard/ 文件夹中的 proguard-android.txt 的内容以及默认放置于模块根目录的 proguard-rules.pro 的内容。前者是 SDK 提供的默认混淆文件(内容见附录1),后者是开发者自定义混淆规则的地方。

混淆配置文件区别

  1. proguard-android-optimize.txt:这是一个用于混淆和优化Android应用程序的配置文件。它包含了一系列的规则和配置选项,旨在通过删除未使用的代码、优化代码结构和减小输出文件的大小来提高应用程序的性能。
  2. proguard-android.txt:这是一个用于混淆Android应用程序的配置文件。它包含了一系列的规则和配置选项,用于对应用程序的代码进行混淆,以防止反编译和代码分析。混淆会对类名、方法名和字段名进行重命名,使得代码变得难以理解和逆向工程。
  3. proguard-project.txt:这是一个通用的ProGuard配置文件,可以用于任何类型的Java项目,包括Android项目。它提供了一些基本的混淆规则和配置选项,但可能需要根据具体项目的需求进行自定义。
    常见混淆命令
    暂时无法在飞书文档外展示此内容
    保持元素不参与混淆的规则
    形如:
    [保持命令] [类] {[成员]
    }
    “类”代表类相关的限定条件,它将最终定位到某些符合该限定条件的类。它的内容可以使用:- 具体的类- 访问修饰符(public、protected、private)- 通配符*,匹配任意长度字符,但不含包名分隔符(.)- 通配符**,匹配任意长度字符,并且包含包名分隔符(.)- extends,即可以指定类的基类- implement,匹配实现了某接口的类- $,内部类
    “成员”代表类成员相关的限定条件,它将最终定位到某些符合该限定条件的类成员。它的内容可以使用:- 匹配所有构造器- 匹配所有域- 匹配所有方法- 通配符*,匹配任意长度字符,但不含包名分隔符(.)- 通配符,匹配任意长度字符,并且包含包名分隔符(.)- 通配符*,匹配任意参数类型- …,匹配任意长度的任意类型参数。比如void test(…)就能匹配任意 void test(String a) 或者是 void test(int a, String b)这些方法。- 访问修饰符(public、protected、private)
    举个例子,假如需要将name.huihui.test包下所有继承Activity的public类及其构造函数都保持住,可以这样写:
-keep public class name.huihui.test.** 
extends Android.app.Activity {<init>}
常用的自定义混淆规则
- 不混淆某个类
-keep public class name.huihui.example.Test { *; }
- 不混淆某个包所有的类
-keep class name.huihui.test.** { *; }
- 不混淆某个类的子类
-keep public class * extends name.huihui.example.Test { *; }
- 不混淆所有类名中包含了“model”的类及其成员
-keep public class .*model*. {*;}
- 不混淆某个接口的实现
-keep class * implements name.huihui.example.TestInterface { *; }
- 不混淆某个类的构造方法
-keepclassmembers class name.huihui.example.Test { 
  public <init>(); 
  }
- 不混淆某个类的特定的方法
-keepclassmembers class name.huihui.example.Test { 
  public void test(java.lang.String); 
  }

# 保持所有类和成员的名称不被混淆
-keep class * {
    public protected private *;
}
# 忽略所有警告
-dontwarn *

# 防止删除未直接使用的类和成员
-dontshrink

# 禁用优化
#-dontoptimize

# 不进行混淆
#-dontobfuscate

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

自定义混淆规则

在 app module 下默认生成了项目的自定义混淆规则文件 proguard-rules.pro,多方调研后,一份适用于大部分项目的混淆规则最佳实践如下:
#指定压缩级别
-optimizationp

asses 5
  
  #不跳过非公共的库的类成员
  -dontskipnonpubliclibraryclassmembers
  
  #混淆时采用的算法
  -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
  
  #把混淆类中的方法名也混淆了
  -useuniqueclassmembernames
  
  #优化时允许访问并修改有修饰符的类和类的成员 
  -allowaccessmodification
  
  #将文件来源重命名为“SourceFile”字符串
  -renamesourcefileattribute SourceFile
  #保留行号
  -keepattributes SourceFile,LineNumberTable
  
  #保持所有实现 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();}
  
  #Fragment不需要在AndroidManifest.xml中注册,需要额外保护下
  -keep public class * extends android.support.v4.app.Fragment
  -keep public class * extends android.app.Fragment
  
  # 保持测试相关的代码
  -dontnote junit.framework.**
  -dontnote junit.runner.**
  -dontwarn android.test.**
  -dontwarn android.support.test.**
  -dontwarn org.junit.**
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

注意事项

1,jni方法不可混淆,因为这个方法需要和native方法保持一致;
-keepclasseswithmembernames class * { # 保持native方法不被混淆
native ;}
2,反射用到的类不混淆(否则反射可能出现问题);
3,AndroidMainfest中的类不混淆,所以四大组件和Application的子类和Framework层下所有的类默认不会进行混淆。自定义的View默认也不会被混淆;所以像网上贴的很多排除自定义View,或四大组件被混淆的规则在Android Studio中是无需加入的;
4,与服务端交互时,使用GSON、fastjson等框架解析服务端数据时,所写的JSON对象类不混淆,否则无法将JSON解析成对应的对象;
5,使用第三方开源库或者引用其他第三方的SDK包时,如果有特别要求,也需要在混淆文件中加入对应的混淆规则;
6,有用到WebView的JS调用也需要保证写的接口方法不混淆,原因和第一条一样;
7,Parcelable的子类和Creator静态成员变量不混淆,否则会产生Android.os.BadParcelableException异常;
-keep class * implements Android.os.Parcelable { # 保持Parcelable不被混淆 public static final Android.os.Parcelable$Creator *;}
8,使用enum类型时需要注意避免以下两个方法混淆,因为enum类的特殊性,以下两个方法会被反射调用,见第二条规则。
-keepclassmembers enum * {
public static [] values();
public static valueOf(java.lang.String);
}

参考文档 https://www.jianshu.com/p/cba8ca7fc36d

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号