转载请注明出处:

Android 代码混淆 选项说明

http://blog.csdn.net/jjwwmlp456/article/details/44977721 -----------------匆忙拥挤repeat



语法规范说明地址:https://stuff.mit.edu/afs/sipb/project/android/sdk/android-sdk-linux/tools/proguard/docs/index.html#manual/usage.html

sdk目录: /sdk/tools/proguard


Input/Output Options 输入/输出 选项

@filename
Short for '-include filename'.
-include filename
递归读取目录中(如果有)文件的 配置:configuration options
-basedirectory directoryname
配置文件的目录 directoryname规则见 filename
-injars class_path
输入(即使用的) jar文件路径

例:-injars "my program.jar":"/your directory/your program.jar"引号可以不要
-outjars class_path
输出 jar 路径
-libraryjars class_path
指定的jar将不被混淆,just run-time jar
-skipnonpubliclibraryclasses
跳过(不混淆) jars中的 非public classes
-dontskipnonpubliclibraryclasses
不跳过(混淆) jars中的 非public classes 默认选项
-dontskipnonpubliclibraryclassmembers
不跳过 jars中的非public classes的members
-keepdirectories [directory_filter]
指定目录 keep 在 out jars中 directory_filter规则见file filter
-target version
java版本 1.0, 1.1, 1.2, 1.3, 1.4, 1.5 (or just 5), 1.6 (or just 6), or 1.7 (or just 7).
-forceprocessing
指定input处理,即使output seems up to date


Keep Options 保持不变的选项

-keep [,modifier,...] class_specification

保持class_specification规则若有[,modifier,...],则先启用它的规则

-keepclassmembers [,modifier,...]class_specification

保持类的成员:属性(可以是成员属性、类属性)、方法(可以是成员方法、类方法)

-keepclasseswithmembers [,modifier,...] class_specification

与-keep功能基本一致(经测试)

-keepnames class_specification
Short for -keep,allowshrinking class_specification

-keepclassmembernames class_specification
Short for -keepclassmembers,allowshrinking class_specification

-keepclasseswithmembernames class_specification
Short for -keepclasseswithmembers,allowshrinking class_specification

-printseeds [filename]

打印匹配的-keep家族处理的 类和类成员列表,到标准输出。

用Proguard 命令行,能看到输出效果(未测试)


Shrinking Options 压缩选项

shrink,测试后发现会将一些无效代码给移除,即没有被显示调用的代码

-dontshrink

shrink操作默认启用,每个optimization步骤后,都会执行一步shrink。

该选项 表示 不启用 shrink。

测试后发现是全局性的,且即便使用了-keep 开启shrink,也无效

-printusage [filename]

打印被移除的代码,在标准输出
-whyareyoukeeping class_specification

打印 在shrink过程中 为什么有些代码被 keep


Optimization Options 优化选项

基于控制流、数据流分析后,删除、合并一些代码 -dontoptimize

optimization,默认启用

该选项表示 不启用

当不使用该选项时,下面的才有效
-optimizations optimization_filter

根据optimization_filter指定要优化的文件
-optimizationpasses n

优化数量 n
-assumenosideeffects class_specification

如果一个方法有返回值,在调用的时候没使用到它的返回值,那么可能被忽略。

-allowaccessmodification

优化时允许访问并修改类和类的成员的 访问修饰符,可能作用域会变大。
-mergeinterfacesaggressively

竭力合并接口,即使它们的实现类未实现合并后接口的所有方法。


Obfuscation Options 混淆选项

混淆类名、属性名、方法名、变量名等,变成无意义的类似a,b,c,d...的名字

-dontobfuscate
不混淆
-printmapping [filename]
打印 映射旧名到新名
-applymapping filename
打印相关
-obfuscationdictionary filename
指定外部模糊字典
-classobfuscationdictionary filename
指定class模糊字典
-packageobfuscationdictionary filename
指定package模糊字典
-overloadaggressively
过度加载,多个属性和方法使用相同的名字,只是参数和返回类型不同 可能各种异常
-useuniqueclassmembernames
类和类成员都使用唯一的名字
-dontusemixedcaseclassnames
不使用大小写混合类名
-keeppackagenames [package_filter]
保持packagename 不混淆
-flattenpackagehierarchy [package_name]
指定重新打包,所有包重命名,这个选项会进一步模糊包名 好东西
将包里的类混淆成n个再重新打包到一个个的package中
-repackageclasses [package_name]
将包里的类混淆成n个再重新打包到一个统一的package中 会覆盖flattenpackagehierarchy选项
-keepattributes [attribute_filter]
# 混淆时可能被移除下面这些东西,如果想保留,需要用该选项。对于一般注解处理如 -keepattributes *Annotation*
# attribute_filter : Exceptions, Signature, Deprecated, SourceFile, SourceDir, LineNumberTable,
#LocalVariableTable, LocalVariableTypeTable, Synthetic,
#EnclosingMethod, RuntimeVisibleAnnotations, RuntimeInvisibleAnnotations, RuntimeVisibleParameterAnnotations,
#RuntimeInvisibleParameterAnnotations, and AnnotationDefault.

-keepparameternames

-renamesourcefileattribute [string]

-adaptclassstrings [class_filter]

-adaptresourcefilenames [file_filter]

-adaptresourcefilecontents [file_filter]


Preverification Options 预校验选项

-dontpreverify
-microedition


General Options 通用选项

-verbose

打印详细
-dontnote [class_filter]

不打印某些错误
-dontwarn [class_filter]

不打印警告信息
-ignorewarnings

忽略警告,继续执行
-printconfiguration [filename]

打印配置文件
-dump [filename]

指定打印类结构


其他说明

Class Paths : class_path

类路径,unix分隔符为冒号(:),windows分隔符为分号(;) 可以表示的文件类型有: · a class file or resource file · a jar file · a war file · an ear file · a zip file · a directory(structure)

File Names : filename

文件或目录名,可以使用相对或绝对路径 可以使用Java system properties,表示法:<...> 如:

File Filters : file_filter

文件过滤。 通配符: ? 匹配任意一个单个字符 * 匹配任意多个字符,不含目录分隔符:unix下为(/),windows下为(\) ** 匹配任意多个字符,含目录分隔符 还可以使用一个逻辑符号:! ! 表示 求反,除...之外

Filters : package_filter、attribute_filter、class_filter

可以过滤的有:names of files, directories, classes, packages, attributes, optimizations(见下文) 通配符: ? 匹配任意一个单个字符 * 匹配任意多个字符,不含目录分隔符和package分隔符: . ** 匹配任意多个字符,含目录分隔符和package分隔符:. 还可以使用一个逻辑符号:! ! 表示 求反,除...之外

Overview of Keep Options

keep 选项,表示保持 类或类成员(方法和属性) 不变。各选项间的关系:

Keep

(保护、保持)

From being removed or renamed

(保护将会删除或重命名)

From being renamed

(保护将重命名)

Classes and class members

-keep

-keepnames

Class members only

-keepclassmembers

-keepclassmembernames

Classes and class members, if class members present

-keepclasseswithmembers

-keepclasseswithmembernames

每个keep选项 后面都跟一个class_specification
注意:
· 只指定class时,那么类的成员还是可以被移除、优化、混淆 · 指定了类的某些成员时,那么除这些之外的其它的成员 还是可以被 移除、优化、混淆

Keep Option Modifiers:modifiers

allowshrinking 启用压缩

压缩默认启用

如果 上一条keep 了(即不压缩),而下一条allowshrinking,则还是会压缩,即:会覆盖上面的配置
allowoptimization启用优化

优化默认启用

会覆盖上面的配置
allowobfuscation启用混淆

混淆默认启用

会覆盖上面的配置

例:

-keep public class com.stone.*Activity 保护任意com.stone包下的*Activity

-keep ,allowshrinkingpublic class com.stone.*Activity 启用压缩


Class Specifications 类规范

完整语法
[ @ annotationtype ] [[ ! ] public | final | abstract | @ ... ] [!] interface | class | enum classname [ extends | implements [ @ annotationtype ] classname ]
[{
[
@ annotationtype ] [[!] public | private | protected | static | volatile | transient ... ] | (fieldtype fieldname);
[
@ annotationtype ] [[!]public|private|protected|static| synchronized | native | abstract
| strictfp ...] | (argumenttype,...) |classname(argumenttype,...) |(returntype methodname(argumenttype,...));
[ @ annotationtype ] [[!] public | private | protected | static ... ] * ;
...
}]
蓝色的java关键字 [ ] 表示里面的内容是可选的。
@ 表示是一个注解类型 annotationtype的规范与classname类似 ... [[!]public|final|abstract|@ ...] : ...表示可以写上前面选项中的任意一种或多种。不参与语法 (argumenttype,...) :... 参与语法,表示0个或多个任意参数类型
| 表示或 ! 表示非 ()在表示方法时,才是语法的一部份;其它时候,只是用来分组
classname 需要使用完全限定类名(即含包名的类名)
可以使用如下通配符匹配类名:
? 匹配一个任意字符
* 匹配多个任意字符,不含package分隔符.
** 匹配多个任意字符,含package分隔符.

属性(fields)和方法(methods):
它们的规范与java中的规范类似,只是方法中不需要写上参数名,有参数类型即可
matches any constructor.
matches any field.
matches any method.
* matches any field or method. 注意这四个通配符,本身不含 访问修饰符
属性或方法后面都要以分号(;)结尾 属性名或方法名可以使用的通配符: ?匹配任意一个字符 * 匹配任意多个字符 属性或方法类型(类型可以直接写,如果是一个class,则写上class的完全限定名)可以使用的通配符: % 表示任意基本数据类型,不含void ? 表示匹配用作类型的 class name的任意一个字符 * 任意多个字符,不含package分隔符(.) ** 任意多个字符,含package分隔符(.) 匹配非基本数据类型和非数组类型 例: ** get*() 可匹配com.stone.User getCurUser(), 但不匹配String getName(),也不匹配com.stone.User[ ] getCurUser()。 *** 匹配任意类型 ... 表示任意数量的任意参数类型 构造方法中的class name,可以用短类名或含包名的类名

Optimizations : optimization_filter

当不使用-dontobfuscate选项时,则-optimizationsoptimization_filter才有效

optimization_filter可以使用的通配符:

?任意一个字符 (没啥用)

* 任意多个字符

可以用 ! 表示 非

For example, "code/simplification/variable,code/simplification/arithmetic" only performs the two specified peephole optimizations.

For example, "!method/propagation/*" performs all optimizations, except the ones that propagate values between methods.

For example, "!code/simplification/advanced,code/simplification/*" only performs all peephole optimizations.


optimization_filter 表示的有:

class/marking/final
Marks classes as final, whenever possible.

在任何可能的时候,将类标志为final class
class/merging/vertical
Merges classes vertically in the class hierarchy, whenever possible.

垂直合并类(上下层级的类 进行合并)
class/merging/horizontal
Merges classes horizontally in the class hierarchy, whenever possible.

水平合并类(同一层级的类 进行合并)
(⇒ code/removal/advanced) 表示当前选项是=>后的 前置选项

field/removal/writeonly
Removes write-only fields.

删除只写 属性
field/marking/private
Marks fields as private, whenever possible.

标记属性为private
(⇒ code/simplification/advanced)

field/propagation/value
Propagates the values of fields across methods.

在方法中传播属性值
method/marking/private
Marks methods as private, whenever possible (devirtualization).

标记属性为private(具体化)
(⇒ code/removal/advanced)

method/marking/static
Marks methods as static, whenever possible (devirtualization).

标记方法为static(具体化)
method/marking/final
Marks methods as final, whenever possible.

标记方法为final
(⇒ code/removal/advanced)

method/removal/parameter
Removes unused method parameters.

删除未使用的方法参数
(⇒ code/simplification/advanced)

method/propagation/parameter
Propagates the values of method parameters from method invocations to the invoked methods.

从方法的invocations传递方法参数值到 实际调用方法的地方invoked methods
(⇒ code/simplification/advanced)

method/propagation/returnvalue
Propagates the values of method return values from methods to their invocations.

传递方法的返回值 从方法到它们被调用的地方
method/inlining/short
Inlines short methods.

内联短方法
method/inlining/unique
Inlines methods that are only called once.

内联 仅被调用一次(或者说只被一个地方调用)的短方法
method/inlining/tailrecursion
Simplifies tail recursion calls, whenever possible.

简化尾递归 (尾递归转循环)
code/merging
Merges identical blocks of code by modifying branch targets.

合并相同的代码块
code/simplification/variable
Performs peephole optimizations for variable loading and storing.

变量加载和存储时 使用peephole optimization(窥孔优化)技术
code/simplification/arithmetic
Performs peephole optimizations for arithmetic instructions.

计算指令 用窥孔优化
code/simplification/cast
Performs peephole optimizations for casting operations.

类型转换 用窥孔优化
code/simplification/field
Performs peephole optimizations for field loading and storing.

属性加载和存储 用窥孔优化
(⇒ code/removal/simple)

code/simplification/branch
Performs peephole optimizations for branch instructions.

分支指令用窥孔优化
code/simplification/string
Performs peephole optimizations for constant strings.

常量字符串用窥孔优化
(best used with code/removal/advanced)

code/simplification/advanced
Simplifies code based on control flow analysis and data flow analysis.

简化代码基于控制流分析和数据流分析
(⇒ code/removal/exception)

code/removal/advanced
Removes dead code based on control flow analysis and data flow analysis.

删除死代码基于控制流分析和数据流分析
(⇒ code/removal/exception)

code/removal/simple
Removes dead code based on a simple control flow analysis.

删除死代码基于一个简单的控制流分析
code/removal/variable
Removes unused variables from the local variable frame.

从本地变量框架中,删除 未使用的变量
code/removal/exception
Removes exceptions with empty try blocks.

当try-catch中,try块内为空时,删除exceptions
code/allocation/variable
Optimizes variable allocation on the local variable frame.

在本地变量框架中 优化变量分配

注意

·上一句保护,下一句启用modifers, 启用无效; 上一句启用modifiers,下一句保护,保护有效。重在保护

· 使用了-dontshrink|dontoptimize|dontobfuscate 这些全局选项后,那么再使用相应的kepp modifiers 无效

·当不使用-dontoptimize选项时,则-optimizationsoptimization_filter才有效

· 测试发现jdk中就有优化不通过的地方,并且这个优化时间很长时间,还可能造成优化程序不结束(一直在运行,结束不了)

所以一般还是直接使用-dontoptimize。sdk中的proguard的配置文件也是这么写的。如果你想专业点,自行调试吧~


示例

-dontoptimize  #不优化-dontpreverify #不预校验#保持源文件和行号的信息,用于混淆后定位错误位置-keepattributes SourceFile,LineNumberTable-libraryjars class_path  #不处理 class_path指定的文件-dontusemixedcaseclassnames  #不使用大小写混合类名-dontskipnonpubliclibraryclasses #不跳过jars中的非public classes。在proguard4.5时,是默认选项-verbose-flattenpackagehierarchy com.stone.myapplication.interfaces # 将包里的类混淆成n个再重新打包到一个一个的package中-repackageclasses com.stone.myapplication.interfaces #将包里的类混淆成n个再重新打包到一个统一的package中 会覆盖flattenpackagehierarchy选项-keepattributes *Annotation* #保持含有Annotation字符串的 attributes-keep public class com.google.vending.licensing.ILicensingService-keep public class com.android.vending.licensing.ILicensingService#保持 本化方法及其类声明-keepclasseswithmembernames class * {     native ;}#保持view的子类成员: getter setter-keepclassmembers public class * extends android.view.View {    void set*(***);   *** get*();}#保持Activity的子类成员:参数为一个View类型的方法   如setContentView(View v)-keepclassmembers class * extends android.app.Activity {   public void *(android.view.View);}#保持枚举类的成员:values方法和valueOf  (每个enum 类都默认有这两个方法)-keepclassmembers enum * {    public static **[] values();    public static ** valueOf(java.lang.String);}#保持Parcelable的实现类和它的成员:类型为android.os.Parcelable$Creator 名字任意的 属性-keep class * implements android.os.Parcelable {  public static final android.os.Parcelable$Creator *;}#保持 任意包名.R类的类成员属性。  即保护R文件中的属性名不变-keepclassmembers class **.R$* {    public static ;}#不警告 support包-dontwarn android.support.**-keepattributes Signature   #保持签名#下面三个gson相关-keep class sun.misc.Unsafe {*;}-keep class com.google.gson.examples.android.model.**{*;}-keep class com.tv.kuaisou.bean.* {*;}-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



后记:

边翻译,边测试了三四天,头痛,有些什么打印、重命名及不怎么用的选项,实在翻译不下去了。

有些官方上也没有看到示例,比如 外部的混淆字典...

如有失误,请指正。



更多相关文章

  1. Android 获取控件宽高的3种方法
  2. Android中创建与几种解析xml的方法!
  3. Android当方法总数超过64K时(Android Studio)
  4. android ViewPager 使用方法
  5. android Menu 选项菜单示例
  6. Android 方法数超过64k限制的解决办法
  7. android的Services生命周期和使用方法
  8. 10.Android ImageView ScaleType属性
  9. Android onClick事件三种实现方法

随机推荐

  1. 浅谈mysql密码遗忘和登陆报错的问题
  2. 解说mysql之binlog日志以及利用binlog日
  3. MySQL 5.7中的关键字与保留字详解
  4. mysql 列转行,合并字段的方法(必看)
  5. mysql列转行以及年月分组实例
  6. mysql 列转行的技巧(分享)
  7. MySQL 按指定字段自定义列表排序的实现
  8. mysql索引使用技巧及注意事项
  9. 老生常谈MYSQL模式匹配 REGEXP和like的用
  10. 浅谈mysql的索引设计原则以及常见索引的