ProGuard的各种参数说明(1)

简介: ProGuard的各种参数说明(1)

proguard分为4个步骤:

压缩(shrink)

移除未使用的类、方法、字段等;

优化(optimize)

优化字节码、简化代码等操作;

混淆(obfuscate)

使用简短的、无意义的名称重全名类名、方法名、字段等;

预校验(preverify)

为class添加预校验信息。

一、4个步骤中的常量配置

1. 压缩(shrink)

-dontshrink

声明不进行压缩操作,默认情况下,除了-keep配置(下详)的类及其直接或间接引用到的类,都会被移除。


2. 优化(optimize)

-dontoptimize

不对class进行优化,默认开启优化。

注意:由于优化会进行类合并、内联等多种优化,-applymapping可能无法完全应用,需使用热修复的应用,建议使用此配置关闭优化。


-optimizationpasses n

执行优化的次数,默认1次,多次能达到更好的优化效果。


-optimizations optimization_filter

优化配置,可进行字段优化、内联、类合并、代码简化、算法指令精简等操作。


#只进行 移除未使用的局部变量、算法指令精简
-optimizations code/removal/variable,code/simplification/arithmetic
#进行除 算法指令精简、字段、类合并外的所有优化
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

3. 混淆(obfuscate)

-dontobfuscate

不进行混淆,默认开启混淆。除-keep指定的类及成员外,都会被替换成简短、随机的名称,以达到混淆的目的。


-applymapping filename

根据指定的mapping映射文件进行混淆。


-obfuscationdictionary filename

指定字段、方法名的混淆字典,默认情况下使用abc等字母组合,比如根据自己的喜好指定中文、特殊字符进行混淆命名。


-classobfuscationdictionary filename

指定类名混淆字典。


-packageobfuscationdictionary filename

指定包名混淆字典。


-useuniqueclassmembernames

指定相同的混淆名称对应不同类的相同成员,不同的混淆名称对应不同的类成员。在没有指定这个选项时,不同类的不同方法都可能映射到a,b,c。

有一种情况,比如两个不同的接口,拥有相同的方法签名,在没有指定这个选项时,这两个接口的方法可能混淆成不同的名称。但如果新增一个类同时实现这两个接口,并且利用-applymapping指定之前的mapping映射文件时,这两个接口的方法必须混淆成相同的名称,这时就和之前的mapping冲突了。

在某此热修复场景下需要指定此选项。


-dontusemixedcaseclassnames

指定不使用大小写混用的类名,默认情况下混淆后的类名可能同时包含大写小字母。这在某些对大小写不敏感的系统(如windowns)上解压时,可能存在文件被相互覆盖的情况。


-keeppackagenames [package_filter]

指定不混淆指定的包名,多个包名可以用逗号分隔,可以使用? * **通配符,并且可以使用否定符(!)。


-keepattributes [attribute_filter]

指定保留属性,多个属性可以用多个-keepattributes配置,也可以用逗号分隔,可以使用? * **通配符,并且可以使用否定符(!)。

比如,在混淆ibrary库时,应该至少keep Exceptions, InnerClasses, Signature;如果在追踪代码,还需要keep符号表;使用到注解时也需要keep。


-keepattributes Exceptions,InnerClasses,Signature
-keepattributes SourceFile,LineNumberTable
-keepattributes *Annotation*
-keepparameternames

指定keep已经被keep的方法的参数类型和参数名称,在混淆library库时非常有用,可供IDE帮助用户进行信息提示和代码自动填充。


4. 预校验(preverify)

-dontpreverify

指定不对class进行预校验,默认情况下,在编译版本为micro或者1.6或更高版本时是开启的。但编译成Android版本时,预校验是不必须的,配置这个选项可以节省一点编译时间。

(Android会把class编译成dex,并对dex文件进行校验,对class进行预校验是多余的。)


二、keep配置

-keep [,modifier,...] class_specification

指定类及类成员作为代码入口,保护其不被proguard,如:


-keep class com.rush.Test
-keep interface com.rush.InterfaceTest
-keep class com.rush.** {
    <init>;
    public <fields>;
    public <methods>;
    public *** get*();
    void set*(***);
}

class表示keep类或接口

interface仅表示keep接口

类名 通配符如下:


| 通配符 | 含义 |

| --- |

| ? | 匹配单个字符,包名分隔符(.)除外 |

| * | 匹配除(.)外的任意字符 |

| ** | 匹配任意字符(包含.),如com.rush.**匹配com.rush包下的所有类及其所有子包的类。 |


字段和方法 通配符如下:


| 通配符 | 含义 |

| --- |

| <init> | 匹配所有构造方法 |

| <fields> | 匹配所有字段 |

| <methods> | 匹配所有方法 |

| ? | 匹配单个字符,包名分隔符(.)除外 |

| * | 匹配除(.)外的任意字符 |


类型 通配符如下:


| 通配符 | 含义 |

| --- |

| % | 匹配原始类型,如int, boolean等 |

| ? | 匹配任意单个字符 |

| * | 匹配除包名分隔符(.)外的任意字符 |

| ** | 匹配任意字符,包括包名分隔符(.) |

| *** | 匹配任意类型(原始类型、非原始类型、数组或非数组类型)|

| ... | 匹配任意参数个数,任意参数类型 |


其中类配置完整定义如下,其中[]表示可选


[@annotationtype] [[!]public|final|abstract|@ ...] [!]interface|class|enum classname
    [extends|implements [@annotationtype] classname]
[{
    [@annotationtype] [[!]public|private|protected|static|volatile|transient ...] <fields> |
                                                                      (fieldtype fieldname);
    [@annotationtype] [[!]public|private|protected|static|synchronized|native|abstract|strictfp ...] <methods> |
                                                                                           <init>(argumenttype,...) |
                                                                                           classname(argumenttype,...) |
                                                                                           (returntype methodname(argumenttype,...));
    [@annotationtype] [[!]public|private|protected|static ... ] *;
    ...
}]

keep过于简单粗暴,proguard提供了6种不同的配置:


| 保留 | 防止被移除或重命名 | 防止被重命名(未使用的会被移除) |

| --- | --- |

| 类和类成员 | -keep | -keepnames |

| 仅类成员 | -keepclassmembers | -keepclassmembernames |

| 如类含有某成员,保留类及其成员 | -keepclasseswithmembers | -keepclasseswithmembernames |


三、其它常用配置

-verbose

指定在混淆过程中输出更多信息,配置这个选项后,在遇到异常时,将输出完整的堆栈,而不仅仅是异常消息。


-dontnote [class_filter]

指定不输出潜在的错误或者遗漏,比如拼写错误或者缺失了有用的信息。class_filter是一个正则表达式,匹配到类将不输出这些信息。


-dontwarn [class_filter]

指定一组类,不警告这些类中找不到引用或其它重要的问题。这个选项是很危险的,比如,找不到引用的错误可能导致代码不能正常work。

(在引用一些存在警告的jar包,这个选项比较有用。)


-ignorewarnings

指定输出所以警告信息,但继续进行混淆。同上一选项,慎用。


-printconfiguration [filename]

指定输出整个过程中的所有配置,输出到标准输出流或者指定文件中。这有时候在调度配置时有用。


-dump [filename]

指定在任一处理过程后,输出class文件的结构,可以输出到标准输出流或者指定文件中。

目录
相关文章
【TS】函数重载--可选参数--默认参数
【TS】函数重载--可选参数--默认参数
136 0
|
IDE 开发工具 Android开发
ProGuard的各种参数说明(2)
ProGuard的各种参数说明(2)
247 0
ProGuard:保留包名,混淆类
ProGuard:保留包名,混淆类
248 0
|
安全 Android开发 数据安全/隐私保护
【Android 安全】DEX 加密 ( Proguard 混淆 | 混淆后的报错信息 | Proguard 混淆映射文件 mapping.txt )
【Android 安全】DEX 加密 ( Proguard 混淆 | 混淆后的报错信息 | Proguard 混淆映射文件 mapping.txt )
303 0
【Android 安全】DEX 加密 ( Proguard 混淆 | 混淆后的报错信息 | Proguard 混淆映射文件 mapping.txt )
|
安全 Java Android开发
【Android 安全】DEX 加密 ( Proguard 简介 | Proguard 相关网址 | Proguard 混淆配置 )(一)
【Android 安全】DEX 加密 ( Proguard 简介 | Proguard 相关网址 | Proguard 混淆配置 )(一)
244 0
【Android 安全】DEX 加密 ( Proguard 简介 | Proguard 相关网址 | Proguard 混淆配置 )(一)
|
安全 Android开发 数据安全/隐私保护
【Android 安全】DEX 加密 ( Proguard 简介 | Proguard 相关网址 | Proguard 混淆配置 )(二)
【Android 安全】DEX 加密 ( Proguard 简介 | Proguard 相关网址 | Proguard 混淆配置 )(二)
157 0
【Android 安全】DEX 加密 ( Proguard 简介 | Proguard 相关网址 | Proguard 混淆配置 )(二)
|
Java Android开发
ProGuard混淆
ProGuard技术的功能概括为以下4项: 1.压缩(shrinks) :检查并移除代码中无用的类,字段,方法,属性。 2.优化(optimizes):对字节码进行优化,移除无用的指令。 3.混淆(obfuscates):使用a,b,c,d等简短而无意义的名称,对类,字段和方法进行重名,这样即使代码被逆向工程,对方也比较难以读懂。 4.预检测(Preveirfy):在java平台上对处理后的代码进行再次检测。 详细介绍 (1) ProGuard 配置 -include{filename}:从给定的文件中读取配置参数。 -basedirectory{directoryname}:指定基础目录为
502 0
|
Android开发
ProGuard中keep到底有什么作用
一直以为keep就是不要混淆,近期发现还有另外一个作用
393 0
|
安全 Android开发 数据安全/隐私保护
【Android 安全】DEX 加密 ( Proguard 简介 | 默认 ProGuard 分析 )
【Android 安全】DEX 加密 ( Proguard 简介 | 默认 ProGuard 分析 )
246 0