Android Studio系列之代码混淆proguardFiles
来源:互联网 发布:c 数据结构与算法 编辑:程序博客网 时间:2024/06/06 01:52
前言:
android代码编译成apk后如果没有进行任何防护措施是很容易被反编译的,并且反编译的结果甚至就是简单的源码,带来的损失可大可小。幸好,AndroidStudio提供编译代码加密,即ProGuard。
简介
ProGuard 能够对 Java 类中的代码进行压缩(Shrink),优化(Optimize),混淆(Obfuscate),预检(Preveirfy)。
压缩(Shrink):检测和删除没有使用的类,字段,方法和属性。
优化(Optimize):对字节码进行优化,并且移除无用指令。
混淆(Obfuscate):使用 a,b,c 等无意义的名称,对类,字段和方法进行重命名。
预检(Preveirfy):主要是在 Java 平台上对处理后的代码进行预检。
配置:
简单看下,
- release表示正式版本,对应的是debug,一般debug是不需要进行代码加密的
- minifyEnabled true表示进行代码加密,false表示不加密
- proguardFiles 代码加密原则 有两个文件对,getDefaultProguardFile(‘proguard-android.txt’)表示默认文件,这个文件是sdk自带的,有一些通用的配置;但是如果apk需要更加严格的加密,我们可以在’proguard-rules.pro’文件中进行更加详尽的配置。
proguard-android.txt
来看下这个文件中的内容(可以Double Shift快速搜索改文件)
# This is a configuration file for ProGuard.# http://proguard.sourceforge.net/index.html#manual/usage.html# 包名不混合大小写-dontusemixedcaseclassnames# 不忽略非公共的库类-dontskipnonpubliclibraryclasses# 输出混淆日志-verbose# Optimization is turned off by default. Dex does not like code run# through the ProGuard optimize and preverify steps (and performs some# of these optimizations on its own).# 不进行优化-dontoptimize# 不进行预检验-dontpreverify# Note that if you want to enable optimization, you cannot just# include optimization flags in your own project configuration file;# instead you will need to point to the# "proguard-android-optimize.txt" file instead of this one from your# project.properties file.# 不混淆注解(注解不能被混淆)-keepattributes *Annotation*# 不混淆指定类-keep public class com.google.vending.licensing.ILicensingService-keep public class com.android.vending.licensing.ILicensingService# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native# 不混淆native的方法-keepclasseswithmembernames class * { native <methods>;}# keep setters in Views so that animations can still work.# see http://proguard.sourceforge.net/manual/examples.html#beans# 不混淆继承View的所有类的set和get方法-keepclassmembers public class * extends android.view.View { void set*(***); *** get*();}# We want to keep methods in Activity that could be used in the XML attribute onClick# 不混淆继承Activity的所有类的中的参数类型为View的方法-keepclassmembers class * extends android.app.Activity { public void *(android.view.View);}# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations# 不混淆枚举类型的values和valueOf方法-keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String);}# 不混淆继承Parcelable的所有类的CREATOR-keepclassmembers class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator CREATOR;}# 不混淆R类中所有static字段-keepclassmembers class **.R$* { public static <fields>;}# The support library contains references to newer platform versions.# Don't warn about those in case this app is linking against an older# platform version. We know about them, and they are safe.# 忽略兼容库的所有警告-dontwarn android.support.**# Understand the @Keep support annotation.# 不混淆指定的类及其类成员-keep class android.support.annotation.Keep# 不混淆使用注解的类及其类成员-keep @android.support.annotation.Keep class * {*;}# 不混淆所有类及其类成员中的使用注解的方法-keepclasseswithmembers class * { @android.support.annotation.Keep <methods>;}# 不混淆所有类及其类成员中的使用注解的字段-keepclasseswithmembers class * { @android.support.annotation.Keep <fields>;}# 不混淆所有类及其类成员中的使用注解的初始化方法-keepclasseswithmembers class * { @android.support.annotation.Keep <init>(...);}
从上面的解析可以看出,proguard-android.txt 中只提供了基本的内容,在实际使用 ProGuard 时通常需要配置大量的规则。例如,引用的第三方库的混淆配置,不混淆自定义控件,不混淆反射的类等。
首先我们来看下上述内容的语法:
基础语法:
-include {filename} 从给定的文件中读取配置参数 -basedirectory {directoryname} 指定基础目录为以后相对的档案名称 -injars {class_path} 指定要处理的应用程序jar,war,ear和目录 -outjars {class_path} 指定处理完后要输出的jar,war,ear和目录的名称 -libraryjars {classpath} 指定要处理的应用程序jar,war,ear和目录所需要的程序库文件 -dontskipnonpubliclibraryclasses 指定不去忽略非公共的库类。 -dontskipnonpubliclibraryclassmembers 指定不去忽略包可见的库类的成员。 保留选项 -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 不混淆输入的类文件 -printmapping {filename} -applymapping {filename} 重用映射增加混淆 -obfuscationdictionary {filename} 使用给定文件中的关键字作为要混淆方法的名称 -overloadaggressively 混淆时应用侵入式重载 -useuniqueclassmembernames 确定统一的混淆类的成员名称来增加混淆 -flattenpackagehierarchy {package_name} 重新包装所有重命名的包并放在给定的单一包中 -repackageclass {package_name} 重新包装所有重命名的类文件中放在给定的单一包中 -dontusemixedcaseclassnames 混淆时不会产生形形色色的类名 -keepattributes {attribute_name,...} 保护给定的可选属性,例如LineNumberTable, LocalVariableTable, SourceFile, Deprecated, Synthetic, Signature, and InnerClasses. -renamesourcefileattribute {string} 设置源文件中给定的字符串常量
关键字包括:
- keep 保留类和类中的成员,防止它们被混淆或者移除
- keepnames 保留类和类中的成员,防止它们被混淆,但当成员没有被引用时会被移除
- keepclassmembers 只保留类中的成员,防止它们被混淆或者移除
- keepclassmembernames 只保留类中的成员,防止它们被混淆,但当成员没有被引用时会被移除
- keepclasswithmembers 保留类和类中的成员,防止它们被混淆或者移除,前提是指名的类中的成员必须存在,如果不存在则还是会混淆
- keepclasswithmembernames 保留类和类中的成员,防止它们被混淆,但当成员没有被引用时会被移除,前提是指名的类中的成员必须存在,如果不存在则还是会混淆
通配符包括:
- field 匹配类中的所有字段
- method 匹配类中的所有方法
- init 匹配类中的所有的构造函数
*
匹配任意长度字符,但不含包名分隔符(.),比如说我们的完整类名是com.example.test.MainActivtiy,使用com.*
,或者com.example.*
,都是无法匹配的,因为*
无法匹配包名中的分隔符,正确的匹配方式是com.example.*
.*
,或者是com.example.test.*
,这些都是可以的。但如果你不写任何其他内容,只有一个*
,那就表示匹配所有的东西**
匹配任意长度字符,并且含包名分隔符(.),比如android.support.**
就可以匹配android.support包下所有的内容,包括任意长度的子包.***
匹配任意参数类型,比如void set(***
)就能匹配任意传入的参数类型,***
get*
()就能匹配任意返回值的类型- … 匹配任意长度的任意参数类型,比如void set(…)就能匹配任意的void set(String a)或者是void set(String a,int b)等方法
注意点:
- Java的反射不能混淆。因为代码混淆,类名、方法名、属性名都改变了,而反射它还是按照原来的名字去反射。
- 注解用了反射,所以不能混淆。
- 不混淆任何包含native方法的类的类名以及native方法名,否则找不到本地方法。
- Activity更不能混淆,因为AndroidManifest.xml文件中是完整的名字,混淆后怎么找?
- 自定义view也是带了包名写在xml布局中,给我换成a,怎么破? R文件混淆了,id没了,界面崩溃那时自然咯。
- 一般在使用第三方框架,sdk时主要其给出的混淆方案。github第三方混淆方案
每次构建时 ProGuard 都会输出下列文件:
- dump.txt 说明 APK 中所有类文件的内部结构。
- mapping.txt 提供原始与混淆过的类、方法和字段名称之间的转换。
- seeds.txt 列出未进行混淆的类和成员。
- usage.txt 列出从 APK 移除的代码。
这些文件保存在 modulename/build/outputs/mapping/release/ 中。
阅读全文
0 0
- Android Studio系列之代码混淆proguardFiles
- Android Studio之代码混淆
- android studio 代码混淆
- Android studio 混淆代码
- android studio 代码混淆
- android studio 代码混淆
- Android Studio 代码混淆
- android studio 代码混淆
- Android Studio 代码混淆
- android studio 代码混淆
- Android Studio混淆代码
- Android Studio 混淆代码
- Android studio 代码混淆
- android studio 代码混淆
- Android Studio 代码混淆
- Android Studio 代码混淆
- Android Studio 代码混淆
- Android studio代码混淆
- IAR9.0以上版本编译低版本的协议栈常见错误及解决方法
- ES6之箭头函数
- elasticsearch与数据库同步工具Logstash-input-jdbc
- spring boot整合freemark
- 时间戳与时间之间的转换
- Android Studio系列之代码混淆proguardFiles
- 初识flume
- 沉浸式状态栏
- Android异常分析(转)
- 分布式开放消息系统(RocketMQ)的原理与实践
- break和continue的区别
- 学习收录
- Android ViewGroup点击效果(背景色)
- idea创建scala项目