ProGuard使用文档

介绍

是一个对于Java字节码的免费的压缩器,优化器,混淆器和审核器;

l  它检测并删除未使用的类,字段,方法和属性。

l  它优化字节码并删除未使用的指令。

l  它重命名其余类、字段和方法使用短毫无意义的名字。

 

官方文档

使用文档

https://www.guardsquare.com/en/products/proguard/manual/usage

常见问题文档:

https://www.guardsquare.com/en/products/proguard/manual/troubleshooting

 

 

了解通配符:

指定类时,可以使用如下通配符

  •   class 关键字表示任意的类或接口
  •   interface 关键字只表示接口
  •   enum 关键字表示枚举类
  •  interface 和 enum 关键字可以加上 !表示除...之外
  •   ?匹配任意字符,不包括包分隔符
  •   匹配任意多个字符,不包括包分隔符
  •  ** 匹配任意多个字符,包括包分隔符
  •  为了向后兼容,* 也可以表示任意的类,包括包分隔符
  •  extends 和 implements 关键字是等效的,表示继承或实现 A 的类,但不包括 A 本身
  •  @ 关键字用于表示使用指定注解修饰的类和类成员

指定类的成员时,可以指定如下通配符

  •   <init> 匹配任意的构造器
  •   <fileds> 匹配任意的成员变量
  •   <methods> 匹配任意的方法

 匹配任意的成员变量或方法

  •  上述通配符不含返回类型,只有<init>有参数列表
  •   除了使用上述全能通配符以外,同样可以使用常用表达式,此时可以使用 ? 和 * 通配符
  • 指定修饰符的类型时,可以使用如下通配符
  •   % 匹配基本类型
  •  ? 匹配任一字符
  •   匹配任意多个字符,不含包分隔符
  •  ** 匹配任意多个字符,包含包分隔符
  •   *** 匹配任意类型(基本或非基本,数组或非数组)
  •   ... 匹配任意数量、任意类型的参数
  •   ? * 和 ** 不会匹配基本类型
  •   可以使用权限控制符帮助匹配(例如 public static)

参考来源:

https://www.guardsquare.com/en/products/proguard/manual/usage#filename

使用 ProGuard  GUI

输入输出部分

 需要确保目录结构为jar目录结构:

错误的目录结构:

 

如果目录结构是下面这种类web目录结构,混淆器无法正确混淆,process会提示大量警告 … unexpectedly contains class …

或者根据官方文档上的解决方法,将打包的jar包放入lib目录,执行混淆(这个没有试验)

 

为了得到这种目录结构,可将项目由eclipse打开,仅对src/main/java项目下的源代码文件导出为jar文件

将该jar包作为输入,add Input

 

依赖库需要添加jre目录下的所有jar和 项目所有的依赖项 lib目录下的jar包

输出名字自定义

 

依赖库除了jre下的jar包,其他依赖根据项目使用情况加入,圈起来的两个是关键jar包

 

点击Next

----------------------------------------------------------------------------------------------------------------

压缩部分

 

 

不勾选,表示不压缩

Keep 输入框

保留某些类,成员不被混淆,(不明白它这个为什么放在压缩部分)

 

在配置文件中的形式:

-keep public class cn.xxx.xxx.controller.* {

    <fields>;

    <methods>;

}

 

#我的model目录结构为 model/po , model/vo ,所以为 model.*.*

-keep public class cn.xxx.xxx.model.*.* {

    <fields>;

    <methods>;

}

主启动类:

-keep class cn.xxx.xxx.XXXApplication {

    *** main(...);

}

该部分功能: 删除没有使用的的类或成员

注意:保留启动类

点击next

------------------------------------------------------------------------------------------------------------------

混淆部分

 

该部分功能: 对代码进行模糊处理,混淆类名、方法名和变量名(使用单字母a,b,c,d,e,f,g…)

介绍一下勾选所代表的意思:

Obfuscate :启用混淆功能

Use unique class member name: 使用统一的类名称

Keep package names:保留包名

Keep attarbute:保留的属性、异常、注解等

Keep paremeter name:保留方法参数名

Keep native: 保留本地方法

-----------------------------------------------------------------------------------------------------------------------------

优化部分

 

不勾选,表示不优化

Allow access modification: 允许修改

该部分功能:它内联并合并类和类成员,并在字节码级别优化所有方法。

---------------------------------------------------------------------------

信息部分

 

Prevify:验证

Target: 更据JDK版本选择

Note: 提示

Warn: 警告

 

Skip non-public library classes: 指定在读取库jar时跳过非公共类,以加快处理速度并减少ProGuard的内存使用量

Skip non-public library class members: 指定跳过包可见的库类成员(字段和方法)

如果实在有警告,解决不了,可以勾选忽略警告

配置文件全部内容

-injars target.jar
-outjars result.jar

-libraryjars 'D:\Program Files\Java\jdk1.8.0_241\jre\lib\charsets.jar'
-libraryjars 'D:\Program Files\Java\jdk1.8.0_241\jre\lib\deploy.jar'
-libraryjars 'D:\Program Files\Java\jdk1.8.0_241\jre\lib\javaws.jar'
-libraryjars 'D:\Program Files\Java\jdk1.8.0_241\jre\lib\jce.jar'
-libraryjars 'D:\Program Files\Java\jdk1.8.0_241\jre\lib\jfr.jar'
-libraryjars 'D:\Program Files\Java\jdk1.8.0_241\jre\lib\jfxswt.jar'
-libraryjars 'D:\Program Files\Java\jdk1.8.0_241\jre\lib\jsse.jar'
-libraryjars 'D:\Program Files\Java\jdk1.8.0_241\jre\lib\management-agent.jar'
-libraryjars 'D:\Program Files\Java\jdk1.8.0_241\jre\lib\plugin.jar'
-libraryjars 'D:\Program Files\Java\jdk1.8.0_241\jre\lib\resources.jar'
-libraryjars 'D:\Program Files\Java\jdk1.8.0_241\jre\lib\rt.jar'
-libraryjars lib\HikariCP-3.4.1.jar
-libraryjars lib\byte-buddy-1.10.2.jar
-libraryjars lib\classmate-1.5.1.jar
-libraryjars lib\commons-codec-1.13.jar
-libraryjars lib\commons-lang3-3.4.jar
-libraryjars lib\druid-1.1.9.jar
-libraryjars lib\druid-spring-boot-starter-1.1.9.jar
-libraryjars lib\guava-20.0.jar
-libraryjars lib\hibernate-validator-6.0.18.Final.jar
-libraryjars lib\jackson-annotations-2.10.0.jar
-libraryjars lib\jackson-core-2.10.0.jar
-libraryjars lib\jackson-databind-2.10.0.jar
-libraryjars lib\jackson-datatype-jdk8-2.10.0.jar
-libraryjars lib\jackson-datatype-joda-2.10.0.jar
-libraryjars lib\jackson-datatype-jsr310-2.10.0.jar
-libraryjars lib\jackson-module-parameter-names-2.10.0.jar
-libraryjars lib\jakarta.annotation-api-1.3.5.jar
-libraryjars lib\jakarta.validation-api-2.0.1.jar
-libraryjars lib\java-jwt-3.4.0.jar
-libraryjars lib\jboss-logging-3.4.1.Final.jar
-libraryjars lib\joda-time-2.10.5.jar
-libraryjars lib\jsqlparser-1.0.jar
-libraryjars lib\jul-to-slf4j-1.7.29.jar
-libraryjars lib\log4j-api-2.12.1.jar
-libraryjars lib\log4j-to-slf4j-2.12.1.jar
-libraryjars lib\logback-classic-1.2.3.jar
-libraryjars lib\logback-core-1.2.3.jar
-libraryjars lib\lombok-1.18.10.jar
-libraryjars lib\mapstruct-1.2.0.Final.jar
-libraryjars lib\mybatis-3.4.6.jar
-libraryjars lib\mybatis-spring-1.3.2.jar
-libraryjars lib\mybatis-spring-boot-autoconfigure-1.3.2.jar
-libraryjars lib\mybatis-spring-boot-starter-1.3.2.jar
-libraryjars lib\ojdbc8-19.3.0.0.jar
-libraryjars lib\ons-19.3.0.0.jar
-libraryjars lib\oraclepki-19.3.0.0.jar
-libraryjars lib\orai18n-12.1.0.2.0.jar
-libraryjars lib\osdt_cert-19.3.0.0.jar
-libraryjars lib\osdt_core-19.3.0.0.jar
-libraryjars lib\pagehelper-5.1.4.jar
-libraryjars lib\pagehelper-spring-boot-autoconfigure-1.2.5.jar
-libraryjars lib\pagehelper-spring-boot-starter-1.2.5.jar
-libraryjars lib\simplefan-19.3.0.0.jar
-libraryjars lib\slf4j-api-1.7.29.jar
-libraryjars lib\snakeyaml-1.25.jar
-libraryjars lib\spring-aop-5.2.1.RELEASE.jar
-libraryjars lib\spring-beans-5.2.1.RELEASE.jar
-libraryjars lib\spring-boot-2.2.1.RELEASE.jar
-libraryjars lib\spring-boot-autoconfigure-2.2.1.RELEASE.jar
-libraryjars lib\spring-boot-starter-2.2.1.RELEASE.jar
-libraryjars lib\spring-boot-starter-jdbc-2.2.1.RELEASE.jar
-libraryjars lib\spring-boot-starter-json-2.2.1.RELEASE.jar
-libraryjars lib\spring-boot-starter-logging-2.2.1.RELEASE.jar
-libraryjars lib\spring-boot-starter-tomcat-2.2.1.RELEASE.jar
-libraryjars lib\spring-boot-starter-validation-2.2.1.RELEASE.jar
-libraryjars lib\spring-boot-starter-web-2.2.1.RELEASE.jar
-libraryjars lib\spring-context-5.2.1.RELEASE.jar
-libraryjars lib\spring-core-5.2.1.RELEASE.jar
-libraryjars lib\spring-expression-5.2.1.RELEASE.jar
-libraryjars lib\spring-jcl-5.2.1.RELEASE.jar
-libraryjars lib\spring-jdbc-5.2.1.RELEASE.jar
-libraryjars lib\spring-plugin-core-1.2.0.RELEASE.jar
-libraryjars lib\spring-plugin-metadata-1.2.0.RELEASE.jar
-libraryjars lib\spring-tx-5.2.1.RELEASE.jar
-libraryjars lib\spring-web-5.2.1.RELEASE.jar
-libraryjars lib\spring-webmvc-5.2.1.RELEASE.jar
-libraryjars lib\springfox-core-2.9.2.jar
-libraryjars lib\springfox-schema-2.9.2.jar
-libraryjars lib\springfox-spi-2.9.2.jar
-libraryjars lib\springfox-spring-web-2.9.2.jar
-libraryjars lib\springfox-swagger-common-2.9.2.jar
-libraryjars lib\springfox-swagger-ui-2.9.2.jar
-libraryjars lib\springfox-swagger2-2.9.2.jar
-libraryjars lib\swagger-annotations-1.5.20.jar
-libraryjars lib\swagger-models-1.5.20.jar
-libraryjars lib\tomcat-embed-core-9.0.27.jar
-libraryjars lib\tomcat-embed-el-9.0.27.jar
-libraryjars lib\tomcat-embed-websocket-9.0.27.jar
-libraryjars lib\ucp-19.3.0.0.jar

-skipnonpubliclibraryclasses
-target 1.8
-dontshrink
-dontoptimize
-allowaccessmodification
-printmapping map.txt
-useuniqueclassmembernames
-dontusemixedcaseclassnames
-keeppackagenames
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod

 

-keep public class cn.xxx.xxx.controller.* {
}

-keep public class cn.xxx.xxx.model.*.* {
<fields>;
<methods>;
}

-keep class cn.xxx.xxx.XXXApplication {
*** main(...);
}

-keep class cn.xxx.xxx.mapper.* {
<methods>;
}

# Keep - Native method names. Keep all native class/method names.
-keepclasseswithmembers,includedescriptorclasses,allowshrinking class * {
native <methods>;
}

 

混淆效果:

类名被混淆:

未保留类名称被混淆

方法名被更改:

变量名被混淆:

 

 

 

 

 

混淆验证

将混淆后的jar包解压后的class文件替换原来项目编译后的可执行文件,idea中一般是 target/classes 目录下。

替换完成,运行项目,项目正常启动运行,接口正常访问,则说明混淆没有问题。

 

混淆成功后但运行失败常见的问题:

 

Bean名冲突:

l  启动报错BeanDefinitionStoreException,

如果使用@MapperScan()、@Configuration,@Component、@Service等注解没有为bean命名时,bean会以类名作为bean名称注入spring容器,由于混淆器的命名规则是对包下的类按原名进行排序,然后分配a,b,c,d…等名称,会导致不同包下有类获得相同的名称注入到bean容器,造成bean冲突

解决:

 如果使用默认的命名规则,在勾选了use mix-case class names (使用混合大写命名规则),包中超过26个类时情况下,默认命名为A.class,B.class,C.class…在某些操作系统(windows)下,会因为不区分class文件名称的大小写,会导致错误.

解决:取消勾选use mix-case class names

 

接口访问失败:

l如果是mybatis映射架构,访问接口失败,可查看编译后的接口文件类名,接口名称已经被更改,而对应得xml文件,xml中得sql语句无法与相应得接口名进行绑定,报绑定异常BindingException

解决:所以mapper层类名、方法名都不可更改

所以mapper层需要保留类名和方法名不被混淆

-keep class cn.hulingfeng.ylzdemo.mapper.* {

    <methods>;

}

额外内容

打印混淆的映射关系,会清楚的告诉你混淆的映射关系

apply mapping:

则是根据自己自定义的规则去做混淆映射,比如将上一次的混淆映射应用在这一次,增量混淆可以用到

混淆字典

 

上面三个分别是:

Obfuscation dictory:根据自定义的混淆字典对方法和字段名称进行命名

Class Obfuscation dictory: 根据自定义的混淆字典对类名称进行命名

Package obfuscation dictory: 根据自定义的混淆字典对包名称进行命名

字典示例:

 

混淆结果:

 

 

 

总结

Proguard作为一款混淆器,混淆能力比较有限,且配置比较繁琐,需要注意的问题比较多,尽量降低混淆对象在主程序中的耦合度,才能进一步提升混淆覆盖率

posted on 2020-09-09 16:19  蒟蒻鸡  阅读(981)  评论(0编辑  收藏  举报