proguard 混淆代码,踩坑记录

一、开始原因

       因公司需要,故研究 proguard 混淆代码,期间踩了不少坑,记录一下过程,避免下次再次踩坑,也希望可以帮到大家。代码环境: spring-boot   2.2.5, jdk   1.8, maven   3.6

 

二 、proguard 使用 (使用 xml ,maven插件的形式配置使用,以下配置为最终配置)

   1、在需要混淆的代码 pom.xml 中添加以下 plugin

<plugin>
    <groupId>com.github.wvengen</groupId>
    <artifactId>proguard-maven-plugin</artifactId>
    <executions>
        <execution>
            <!--混淆时刻,这里是打包的时候混淆-->
            <phase>package</phase>
            <!--使用插件的什么功能,当然是混淆-->
            <goals>
                <goal>proguard</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <proguardVersion>6.2.2</proguardVersion>
        <!--是否将生成的PG文件安装部署-->
        <!--<attach>true</attach>-->
        <!--是否混淆-->
        <!--<obfuscate>true</obfuscate>-->
        <!--指定生成文件分类-->
        <!--<attachArtifactClassifier>pg</attachArtifactClassifier>-->
        <!-- 加载配置文件 -->
        <proguardInclude>../proguard.cfg</proguardInclude>
        <!-- 对什么东西进行加载,这里仅有classes成功,毕竟你也不可能对配置文件及JSP混淆吧-->
        <injar>classes</injar>
        <!--class 混淆后输出的jar包 或 文件夹-->
        <outjar>${project.build.finalName}.jar</outjar>
        <!-- <outjar>${project.build.finalName}-pg</outjar>-->
        <!-- 输出目录-->
        <outputDirectory>${project.build.directory}</outputDirectory>

        <libs>
            <!-- Include main JAVA library required.-->
            <lib>${java.home}/lib/rt.jar</lib>
            <!-- Include crypto JAVA library if necessary.-->
            <lib>${java.home}/lib/jce.jar</lib>
        </libs>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>net.sf.proguard</groupId>
            <artifactId>proguard-base</artifactId>
            <version>5.3.3</version>
        </dependency>
    </dependencies>
</plugin>

 2、上面配置中 <proguardInclude>../proguard.cfg</proguardInclude>,proguard.cfg 这个文件。

# -keep {Modifier} {class_specification} 防止类和成员被移除或者被重命名
# -keepclassmembers {modifier} {class_specification} 防止成员被移除或者被重命名
# -keepclasseswithmembers {class_specification} 防止拥有该成员的类和成员被移除或者被重命名
# -keepnames {class_specification} 防止成员被重命名
# -keepclasseswithmembernames {class_specification} 防止拥有该成员的类和成员被重命名
# -keepclasseswithmembers
# -basedirectory directoryname  在配置文件中出现的相对路径均是相对于该路径


# JDK目标版本1.8
-target 1.8
# 不做收缩(删除注释、未被引用代码)
-dontshrink
# 不做优化(变更代码实现逻辑)
-dontoptimize
# 不用大小写混合类名机制
-dontusemixedcaseclassnames
# 不去忽略非公共的库类
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
# 确定统一的混淆类的成员名称来增加混淆
-useuniqueclassmembernames
# 优化时允许访问并修改有修饰符的类和类的成员
-allowaccessmodification
# 不混淆所有包名
#-keeppackagenames

# 指定要保留在输出文件内的目录(解决 spring autowire 装配失败的问题)
-keepdirectories
#-keepdirectories target\classes\cn\XXX\busi\online\cgform\business\RestBusiness.class
#-keepdirectories cn.XXX.busi.online.cgform.business.*

# 需要保持的属性:异常,注解等
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod

#混淆时是否记录日志
#-verbose

# 不混淆所有的set/get方法
-keepclassmembers public class * {void set*(***);*** get*();}

-keep class cn.XXX.codegenerate.generate.** { *;}
-keep class cn.XXX.codegenerate.SettingUtils { *;}
-keep class cn.XXX.codegenerate.database.** { *;}
-keepclassmembers class cn.XXX.busi.online.cgform.controller.** { private *;}
-keep class cn.XXX.busi.online.config.** { *;}
-keep class cn.XXX.busi.online.cgreport.entity.** { *;}
-keep class cn.XXX.busi.online.cgreport.mapper.** { *;}
-keep class cn.XXX.busi.online.cgform.mapper.** { *;}
-keep class cn.XXX.busi.online.cgform.business.** { *;}
-keep class cn.XXX.busi.online.cgform.enums.ExecuteSqlEnum { *;}
-keep class cn.XXX.busi.online.cgform.util.SqlParamUtil { *;}
-keep class cn.XXX.busi.client.impl.* { *;}
-keep class cn.XXX.busi.client.aop.* { !private <methods>; }

# 指定IOnlCgformHeadService类名不被混淆,且IOnlCgformHeadService 的executeSelectSql方法不被混淆
# 注意:返回值 和 参数的 类型要写全路径
-keep class cn.XXX.busi.online.cgform.service.IOnlCgformHeadService {
     cn.XXX.XXX.framework.common.api.RestResponse* execute*Sql(com.alibaba.fastjson.JSONObject);
}

3、以上proguard.cfg 这个文件的内容也可以直接写在pom.xml 中,以个人喜好和需要选择

 <plugin>
                    <groupId>com.github.wvengen</groupId>
                    <artifactId>proguard-maven-plugin</artifactId>
                    <executions>
                        <execution>
                            <!--混淆时刻,这里是打包的时候混淆-->
                            <phase>package</phase>
                            <!--使用插件的什么功能,当然是混淆-->
                            <goals>
                                <goal>proguard</goal>
                            </goals>
                        </execution>
                    </executions>
                    <configuration>
                        <proguardVersion>6.2.2</proguardVersion>
                        <!--是否将生成的PG文件安装部署-->
<!--                        <attach>true</attach>-->
                        <!--是否混淆-->
<!--                        <obfuscate>true</obfuscate>-->
                        <!--指定生成文件分类-->
<!--                        <attachArtifactClassifier>pg</attachArtifactClassifier>-->
                        <options>
                            <!-- JDK目标版本1.8-->
                            <option>-target 1.8</option>
                            <!-- 不做收缩(删除注释、未被引用代码)-->
                            <option>-dontshrink</option>
                            <!-- 不做优化(变更代码实现逻辑)-->
                            <option>-dontoptimize</option>
                            <!-- 不去忽略非公用类文件及成员-->
                            <option>-dontskipnonpubliclibraryclasses</option>
                            <option>-dontskipnonpubliclibraryclassmembers</option>
                            <!--不用大小写混合类名机制-->
                            <option>-dontusemixedcaseclassnames</option>

                            <!-- 优化时允许访问并修改有修饰符的类和类的成员 -->
<!--                            <option>-allowaccessmodification</option>-->
                            <!-- 确定统一的混淆类的成员名称来增加混淆-->
                            <option>-useuniqueclassmembernames</option>
                            <!-- 不混淆所有包名-->
<!--                            <option>-keeppackagenames</option>-->

                            <!-- 需要保持的属性:异常,注解等-->
                            <!-- Error: You have to specify '-keep' options if you want to write out kept elements with '-printseeds'.-->
                            <option>-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod</option>
<!--                            <option>-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,*Annotation*,Synthetic,EnclosingMethod</option>-->
                            <!-- 不混淆所有的set/get方法-->
                            <option>-keepclassmembers public class * {void set*(***);*** get*();}</option>

                            <!-- 不混淆包下的所有类名,且类中的方法也不混淆-->
                            <option>-keep class cn.xxx.codegenerate.generate.** { *;}</option>
                            <option>-keep class cn.xxx.codegenerate.SettingUtils { *;}</option>
                            <option>-keep class cn.xxx.codegenerate.database.** { *;}</option>
                            <option>-keep class cn.xxx.busi.online.cgform.mapper.** { *;}</option>
                            <option>-keep class cn.xxx.busi.online.cgform.business.RestBusiness { *;}</option>
                            <option>-keep class cn.xxx.busi.online.cgform.enums.ExecuteSqlEnum { *;}</option>
                            <option>-keep class cn.xxx.busi.online.cgform.util.SqlParamUtil { *;}</option>
                            <option>-keep class cn.xxx.busi.client.impl.SysBaseApiImpl { *;}</option>
                            <option>-keep class cn.xxx.busi.online.cgform.service.IOnlCgformHeadService { *;} </option>
                            <option>-keep class cn.xxx.busi.online.cgform.service.impl.OnlCgformHeadServiceImpl {*;}</option>
                            <option>-printseeds ${project.build.directory}</option>

                        </options>
                        <!-- 加载配置文件 -->
                        <proguardInclude>E:\ideaProject\busi-base-common\proguard.cfg</proguardInclude>
                        <!-- 对什么东西进行加载,这里仅有classes成功,毕竟你也不可能对配置文件及JSP混淆吧-->
                        <injar>classes</injar>
                        <!--class 混淆后输出的jar包 或 文件夹-->
                        <outjar>${project.build.finalName}.jar</outjar>
<!--                        <outjar>${project.build.finalName}-pg</outjar>-->
                        <!-- 输出目录-->
                        <outputDirectory>${project.build.directory}</outputDirectory>

                        <libs>
                            <!-- Include main JAVA library required.-->
                            <lib>${java.home}/lib/rt.jar</lib>
                            <!-- Include crypto JAVA library if necessary.-->
                            <lib>${java.home}/lib/jce.jar</lib>
                        </libs>
                    </configuration>
                    <dependencies>
                        <dependency>
                            <groupId>net.sf.proguard</groupId>
                            <artifactId>proguard-base</artifactId>
                            <version>6.2.2</version>
                        </dependency>
                    </dependencies>
                </plugin>

4、配置完之后用maven 直接打包即可。options中是配置的混淆方式和忽略的类或方法

三、踩坑记录(废话不多说,直接上坑坑)

1、报错:(Can't process class [META-INF/versions/9/module-info.class] (Unsupported class version number [53.0] (maximum 52.0, Java 1.8))

     解决方式:<proguardVersion>6.2.2</proguardVersion>   版本改为了 最新的 6.2.2,

<dependencies>
    <dependency>
        <groupId>net.sf.proguard</groupId>
        <artifactId>proguard-base</artifactId>
        <version>6.2.2</version>
    </dependency>
</dependencies> 
     
依赖改为同样的版本,刷新maven,即可。

 

2、报错:Error: You have to specify '-keep' options if you want to write out kept elements with '-printseeds'.

     翻译一下:如果要用'-printseeds'写出保留的元素,则必须指定'-keep'选项。

     解决方式:根据需求 配置  -keep  要保留的元素

 

3、 <proguardInclude>../proguard.cfg</proguardInclude>    配置文件未生效  

解决:是因为 路径写的有问题,此路径是相对于 编译后的 target 文件的路径,如果是maven多模块,这些配置又写在父模块的目录下,重点来了,想要混淆子模块的代码,那么这个路径就是相对于子模块的target文件夹的路径

 

4、想要混淆 某个类,但是这个类里面的 几个方法不能混淆,怎么配置都不行,那么 如下:

    返回值和入参  一定要写全包名,要不然无效

# 指定IOnlCgformHeadService类名不被混淆,且IOnlCgformHeadService 的executeSelectSql方法不被混淆
# 注意:返回值 和 参数的 类型要写全路径
-keep class cn.xxx.busi.online.cgform.service.IOnlCgformHeadService {
     cn.xxx.xxx.framework.common.api.RestResponse* execute*Sql(com.alibaba.fastjson.JSONObject);
}

 

5、混淆之后  其他项目调用  @Autowired   注入失败,找不到这个bean

解决方式: -keepdirectories  ,配置文件里加入此项目,可解决问题。网上说 这个配置后面可以加 包名或加目录,但我试了没有效果,这个之后再研究一下,解决问题最重要嘛!

 

6、打包之后 不知道混淆成功了没,或者混淆配置生效了没,查看这个jar包里的代码又很麻烦。那么:

     outjar   配置一个目录即可。如果要上传私服,打包之后却有两个包,混淆的那个包无法直接上传私服,那么 outjar  配置的jar包名称 和  ${project.build.finalName} 一致,即可覆盖。然后 一键轻松上传私服。

<!--class 混淆后输出的jar包 或 文件夹-->
<!-- <outjar>${project.build.finalName}.jar</outjar>-->
<outjar>${project.build.finalName}-pg</outjar>

 


  最后配上 几个配置文件的指令参数说明的文章:

        https://www.cnblogs.com/hanschen-coder/p/6528828.html

        https://blog.csdn.net/byhook/article/details/52529617

 

     先到这里吧,有些坑 前脚踩了 后脚就忘了,希望大家少踩坑,一路阳光道

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值