ProGuard代码混淆器如何使用_proguard使用手册中文-程序员宅基地

技术标签: java  Ashの代码之路  

一、概述

1. ProGuard简介

背景:
ProGuard 是一个免费的 Java 类文件的压缩,优化,混肴器。它删除没有用的类,字段,方法与属性。使字节码最大程度地优化,使用简短且无意义的名字来重命名类、字段和方法 。

使用场景:
我们在工程应用中经常会遇到核心代码不希望给别人抄袭,但系统是用java开发的,无法避免被反编译的情况,这样可以用代码混淆的方式来解决。

使用原因:
版本一直在更新维护,功能也比较多。

2. 相关资料

官网地址: Java Obfuscator and Android App Optimizer | ProGuard
官方手册: ProGuard
中文手册: ProGuard 最全混淆规则说明_proguard混淆规则_程序员_jasen的博客-程序员宅基地
中文语法基础: 语法基础——Proguard语法基础_-keepattributes innerclasses_Dij__柯南的博客-程序员宅基地
Springboot中的使用: Spring boot使用ProGuard实现代码混淆_proguard springboot_Blueeyedboy521的博客-程序员宅基地

二、配置说明

1. 配置要点

建议逐个java包定义混淆规则,这样思路更清晰

  • repository(dao)层需要保存包名和类名,因为Mybatis的xml文件中引用了dao层的接口 ;
  • controller层注意在使用@PathVariable、@RequestParam时需要显式声明参数名 ;
  • dao层用于映射数据库表的类和controller层映射前台参数的类,都需要保留类成员 ;
  • 修改spring的bean命名策略,改成按类的全限定名来命名。
  • -entity和dto中的字段要保留命名,否则无法执行拷贝动作
  • -service最好用@Service(“xxxService”)指定名字,否则会模糊成a,导致依赖问题
  • 多模块依赖的模块最好不要模糊,否则无法依赖正常

2. 使用方案

  • 使用proguard.cfg
  • 直接在pom文件里配置插件(推荐,快速方便)

3. 在pom里配置的例子

<build>
        <plugins>
            <!-- ProGuard混淆插件-->
            <plugin>
                <groupId>com.github.wvengen</groupId>
                <artifactId>proguard-maven-plugin</artifactId>
                <version>2.4.0</version>
                <executions>
                    <execution>
                        <!-- 混淆时刻,这里是打包的时候混淆-->
                        <phase>package</phase>
                        <goals>
                            <!-- 使用插件的什么功能,当然是混淆-->
                            <goal>proguard</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <!-- 是否将生成的PG文件安装部署-->
                    <attach>true</attach>
                    <!-- 是否混淆-->
                    <obfuscate>true</obfuscate>
                    <!-- 指定生成文件分类 -->
                    <attachArtifactClassifier>pg</attachArtifactClassifier>
                    <options>
                        <!-- JDK目标版本1.8-->
                        <option>-target 1.8</option>
                        <!-- 不做收缩(删除注释、未被引用代码)-->
                        <!-- proguard会对代码进行优化压缩,他会删除从未使用的类或者类成员变量等,shrink这个功能一般最好别用,所以这里添加了<option>-dontshrink</option>,我就遇到过启动jar的时候不支持压缩jar的问题-->
                        <option>-dontshrink</option>
                        <!-- 不做优化(变更代码实现逻辑)-->
                        <option>-dontoptimize</option>
                        <!-- 不路过非公用类文件及成员-->
                        <option>-dontskipnonpubliclibraryclasses</option>
                        <option>-dontskipnonpubliclibraryclassmembers</option>
                        <!--不用大小写混合类名机制-->
                        <option>-dontusemixedcaseclassnames</option>

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

                        <!-- 需要保持的属性:异常,注解等-->
                        <option>-keepattributes
                            Exceptions,InnerClasses,Signature,Deprecated,SourceFile,*Annotation*,Synthetic,EnclosingMethod
                        </option>
                        <option>-keep class javax.annotation.**</option>
                        <option>-dontwarn javax.crypto.**</option>
                        <option>-keep class javax.crypto.**</option>
                        <option>-keepnames class com.redotsoft.dmp.**</option>
                        <!-- 此选项将保存接口中的所有原始名称(不混淆)-->
                        <option>-keepnames interface ** { *; }</option>
                        <!-- 此选项将保存所有软件包中的所有原始接口文件(不进行混淆)-->
                        <option> -keep interface * extends * { *; }</option>
                        <!-- 保留参数名,因为控制器,或者Mybatis等接口的参数如果混淆会导致无法接受参数,xml文件找不到参数-->
                        <option>-keepparameternames</option>
                        <!-- 保留枚举成员及方法-->
                        <option>-keepclassmembers enum * { *; }</option>
                        <!-- 不混淆所有类,保存原始定义的注释 -->
                        <option>-keepclassmembers class * {
                        @com.baomidou.mybatisplus.annotation *;
                        @org.springframework.context.annotation.Bean *;
                        @org.springframework.beans.factory.annotation.Autowired *;
                        @org.springframework.beans.factory.annotation.Value *;
                        @org.springframework.stereotype.Service *;
                        @org.springframework.stereotype.Component *;
                        }</option>
                        <!-- 不混淆当前包中的public方法、变量等等 -->
                        <option>-keep class com.redotsoft.dmp.** {
                            public *; }</option>
                    </options>

                    <outjar>${project.build.finalName}-pg.jar</outjar>
                    <libs>
                        <lib>${java.home}/lib/rt.jar</lib>
                    </libs>
                    <!-- 对什么东西进行加载,这里仅有classes成功,毕竟你也不可能对配置文件及JSP混淆吧-->
                    <injar>classes</injar>
                    <!-- 输出目录-->
                    <outputDirectory>${project.build.directory}</outputDirectory>
                </configuration>
            </plugin>
        </plugins>
    </build>

4. 配置项要点说明

  • -keepattributes 保持不会混淆的属性
可配置项:Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod

如果你想混淆方法内部的变量名,则需要去掉LocalVariable*Table这个属性


  • - keepnames 指定要保留名称的类和类成员,前提是在压缩阶段未被删除。仅用于模糊处理

如果你不想混淆所有类的名称(比如你要暴露给父项目调用),需要这么写

-keepnames class com.redotsoft.dmp.**


  • - keep 指定需要保留的类和类成员(作为公共类库,应该保留所有可公开访问的public方法)

如果你想混淆所有的私有内部方法、变量,又希望所有的public公共方法、变量保持不被混淆,需要这么写

-keep class com.redotsoft.dmp.** {public *; }

关于keep命令的一些使用示例
  • 保持了类ClassOneOne里面所有public 修饰的成员和方法
-keepclassmembernames class com.dev.demo.one.ClassOneOne {
public *;
}

  • 保持了ClassOne里面public 修饰的构造函数
-keep class com.dev.demo.ClassOne {
public <init>();
}

  • 保持了类ClassTwoTwo里面public修饰的参数为int的构造函数
-keep class com.dev.demo.two.ClassTwoTwo {
public <init>(int);
}

  • 保持了类ClassTwoThree 里面public修饰的方法和private修饰的成员变量
-keepclassmember class com.dev.demo.two.ClassTwoThree {
public <methods>;
private <fields>;
}

  • 保持了ClassTwoThree的子类以及里面的成员和方法
-keep class * extends com.dev.demo.two.ClassTwoThree {*;}

  • 保持了前缀为ClassOne的类以及里面的成员和方法
-keepnames class com.dev.demo.one.ClassOne{;}

  • 保持了ClassTwoTwo的内部类ClassTwoTwoInner里面的成员和方法
-keep class com.dev.demo.two.ClassTwoTwo$ClassTwoTwoInner{*;}

三、语法目录

Input/Output Options 输入输出选项

-include filename
递归引入目录的配置文件
-basedirectory directoryname
-injars class_path
指定应用程序要处理的jars包(或者wars、ears、zip、或者目录结构),它们里面的class文件会被处理并被写入到输出jars里面。它们里面的任何非class文件会被直接复制过去但是不会处理。(需要注意过滤调一些IDE自动生成的文件);
-outjars class_path
指定输出jars(wars、ears、zip、目录结构)的名称;由-injars 指定的被处理的jars将被写入到指定的输出jars里。如果不指定outjars将不会有class文件被写入。
-libraryjars class_path 不混淆指定的jar库(android 项目中一般不混淆引入的第三方类库)
-skipnonpubliclibraryclasses 不混淆指定jars中的非public calsses
-dontskipnonpubliclibraryclasses 不忽略指定jars中的非public calsses (默认选项)和上面的选手想对
-dontskipnonpubliclibraryclassmembers
不忽略指定类库的public类成员(变量和方法),默认情况下,ProGuard会忽略他们
-keepdirectories [ directory_filter] 指定要保持的目录结构,默认情况下会删除所有目录以减小jar的大小。
-target version
指定java版本号。 版本号可以是1.0,1.1,1.2,1.3,1.4,1.5(或仅5),1.6(或仅6)或1.7(或仅7)中的一个。 默认情况下,类文件的版本号保持不变。 例如,您可能想要将类文件升级到Java 6,通过更改其版本号并对其进行预验证。
-forceprocessing 强制处理输入(-injars)jars。即使输出jars是最新的。通过指定的输入,输出和配置文件或者目录的时间戳判断是否最新。

Keep Options 保留选项

-keep [, modifier,...] class_specification
指定需要保留的类和类成员(作为公共类库,应该保留所有可公开访问的public方法)
-keepclassmembers [, modifier,...] class_specification
指定需要保留的类成员:变量或者方法
-keepclasseswithmembers [, modifier,...] class_specification
指定保留的类和类成员,条件是所指定的类成员都存在(既在压缩阶段没有被删除的成员,效果和keep差不多)
-keepnames class_specification
[-keep allowshrinking class_specification 的简写]
指定要保留名称的类和类成员,前提是在压缩阶段未被删除。仅用于模糊处理
-keepclassmembernames class_specification
[-keepclassmembers allowshrinking class_specification 的简写]
指定要保留名称的类成员,前提是在压缩阶段未被删除。仅用于模糊处理
-keepclasseswithmembernames class_specification
[-keepclasseswithmembers allowshrinking class_specification 的简写]
指定要保留名称的类成员,前提是在压缩阶段后所指定的类成员都存在。仅用于模糊处理
-printseeds [ filename]
指定详尽列出由各种-keep选项匹配的类和类成员。 列表打印到标准输出或给定文件。 该列表可用于验证是否真的找到了预期的类成员,特别是如果您使用通配符。 例如,您可能想要列出所有应用程序或您保存的所有小程序。

Keep选项概述对比(Overview of Keep Options)

作用范围

保持所指定类、成员

所指定类、成员在压缩阶段没有被删除,才能被保持

类和类成员

-keep

-keepnames

仅类成员

-keepclassmembers

-keepclassmembernames

类和类成员(前提是成员都存在)

-keepclasseswithmembers

-keepclasseswithmembernames


通用通配符

通配符

意义

?

匹配名称当中的任意一个字符

*

匹配名称中的任意部分,但是不包括目录的分隔符、包分隔符

**

匹配名称中的任意部分,可以包含任意数量的目录分隔符、包分隔符


类描述通配符

通配符

意义

?

匹配单个字符

*

匹配类名中的任何部分,但不包含包分隔符

**

匹配类名中的任何部分,并且可以包含包分隔符

%

匹配java中的基本数据类型(int, boolean, long, float,double等)

...

匹配任意参数列表

*

匹配所有类型,包括初始类型和非初始类型,数组和非数组

< init >

匹配任何构造器

< ifield>

匹配任何字段名

< imethod>

匹配任何方法

$

指内部类

四、关于打包和发布

  • 需要注意的是,使用ProGuard混淆打包,并不会替换正常的jar包,而是会多出一个代码混淆后的jar包

  • 如果要使用混淆后的jar包进行发布

1. 将原版jar包中的META-INF文件夹拖到混淆后的jar包里去

2. 将混淆后的jar包重命名为原版名称

3. 手动上传至私库(不要用maven的deploy命令上传,这样做会同时上传两个jar包并导致版本混乱)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_54892309/article/details/131653721

智能推荐

yum 安装tomcat_yum tomcat位置-程序员宅基地

文章浏览阅读2.6k次。下面说下yum安装tomcat1. 安装在linux下部署java开发的web应用,一般采用Tomact+jre环境(可不需要apache),在RHEL和CentOS下,可以采用yum在线自动安装方式安装,具体操作如下:可以先查看tomcat在服务器上面的版本:yum search tomcat 可以看到需要安装的tomcat版本号为tomcat6安装命令:yum install tomcat6( 执行以上命令系统会自动安装tomcat和所关联的jdk)2. 安装位置具体说明结束安装系统_yum tomcat位置

流量项目总结_流量类的项目是什么-程序员宅基地

文章浏览阅读708次。硬件配置规模:Sca是一个单独的hadoop集群(24个节点,每个节点的配置:412core CPU,101T硬盘,64G/128G内存)Tas有一个单独的hadoop集群(部署了hive)(35节点)预处理ftp采集集群(6节点,上面部署了采集程序及zookeeper服务)Storm集群(单独)(手机位置实时分析&详单输出解析入hbase库)(10节点)kafka&zoo..._流量类的项目是什么

【CeleX5事件相机使用系列】传感器时间戳同步问题_时间戳是递增的吗-程序员宅基地

文章浏览阅读1.6k次,点赞4次,收藏6次。由于我需要同时获得event和frame,所以需要在Loop模式下获得两种数据的时间戳。这两日折腾了好久,发现CeleX的传感器缺少相关API,且存在一定的问题。在这里做记录总结,以及分享。转载请注明出处 Loop模式的时序根据手册,Loop模式下,当前处在Mode1-3的任意一个模式,且这个模式完成后切换到下一个模式。所谓“完成”,对于fullframe来说,就是采集够了设定的图片数量,而event模式,则是持续了足够的时间。根据手册,可以采用setPictureNumber()设定图片的数.._时间戳是递增的吗

linux一直卡在nfsd_Linux nfsd的过程和含义是什么?-程序员宅基地

文章浏览阅读3.2k次。linux一直卡在nfsdNFS is Unix and Linux type network based file system. This file system is served over network. In order to serve file system with files and directory nfsddaemon is used. It is actually a..._nfsd

dw2019连接mysql数据库_如何在 Dreamweaver 中连接到 MySQL 数据库-程序员宅基地

文章浏览阅读2.4k次。本文档适用于 DreamweaverCreative Suite 用户(使用运行 PHP 5x 的服务器)。如果您使用的是 Dreamweaver,请参阅以下文档了解有关数据库连接的信息:概述此文档介绍在 Dreamweaver 中使用 PHP 服务器模型时,创建成功的 MySQL 数据库连接过程中涉及的一些重要因素。它还介绍了一些基本的 MySQL 用户帐户设置。本文假定您在本地或远程计算机上..._dw链接mysql实现注册登录

druid 版本bug导致discard connection问题记录_com.alibaba.druid.pool.druiddatasource : discard c-程序员宅基地

文章浏览阅读1.1w次。1.项目中遇到的bug,记录一下,以下是转载https://blog.csdn.net/mj158518/article/details/53091064背景之前处理了一个mybatis的bug(详见之前的文章),在给系统升级mybatis的时候,想顺便把所有系统的druid也升级了,从版本(0.2.18~1.0.18不等)升级到统一的最新版本(1.0.26)。但是在beta测试期间,遇..._com.alibaba.druid.pool.druiddatasource : discard connection

随便推点

探索PinYin4j.jar将汉字转换为拼音的基本用法_pinyin4j 阿拉伯数字转拼音-程序员宅基地

文章浏览阅读391次。将汉字转换为拼音在Android开发中是个很常见的问题。例如:在android手机应用开发中,要查询联系人的姓名,通常都是用拼音进行查询的。Pinyin4j是一个功能强悍的汉语拼音工具包,是sourceforge.net上的一个开源项目。主要的功能有: - 支持同一汉字有多个发音 - 支持拼音的格式化输出,比如第几声之类的 - 支持简体中文、繁体中文转换为拼音 首先_pinyin4j 阿拉伯数字转拼音

iOS检查更新_ios 无法检查更新-程序员宅基地

文章浏览阅读254次。#pragma -mark 检查更新-(void)CheckVersionUpdate{ NSDictionary *infoDic = [[NSBundlemainBundle] infoDictionary]; NSString *currentVersion = [infoDic objectForKey:_ios 无法检查更新

编程笔记一:Windows程序内部运行原理_笔记编程是怎么让别的东西远行原理-程序员宅基地

文章浏览阅读431次。《疯狂的程序员》里面boss绝的数据库老师说,“‘数据库原理与应用’,实际上就是数据库应用,像原理这种高深的东西,不能说,说了你们也无法理解。”想来教训得是,什么windows程序内部运行原理,其实就是教我们怎样编写一个窗口程序,一个简单的窗口程序。好,开始吧。一、程序编写函数预处理就不用说了:#include /*头文件,不解释*/#include Windows程序的入口函数,是WinMain,让我们查询MSDN。得到如下:int WINAPI WinMain( HINSTANC_笔记编程是怎么让别的东西远行原理

银联渠道实名认证鉴权接口_五要素鉴权-程序员宅基地

文章浏览阅读9.8k次,点赞2次,收藏8次。为消费信贷及小微贷款提供风控服务,为用户提供从身份验证、反欺诈到信用评分的(贷前)全流程风控服务。典型用例:用户输入被查询人姓名、身份证、手机号、银行卡号四要素,产品返回风险评估报告和决策建议。客户群体: 信贷机构、助贷机构、数据公司等企业用户目标业务类型:现金贷、消费分期、信用卡余额代偿等场景: 线上、线下1. 两要素认证,卡号 +姓名_五要素鉴权

【Java爬虫】使用Jsoup爬取网页<table>表格的分页信息_上海浦东机场爬虫-程序员宅基地

文章浏览阅读2.8k次,点赞2次,收藏12次。爬取网站:https://flights.ctrip.com/actualtime/arrive-sha.p1/爬取上海浦东机场的航班信息技术:使用Jsoup技术jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。参考Jsoup官方文档 Jsoup_Do..._上海浦东机场爬虫

python socket connect函数,python-socket模块基本用法收集-程序员宅基地

文章浏览阅读8.9k次。基本上,Socket 是任何一种计算机网络通讯中最基础的内容。例如当你在浏览器地址栏中输入 www.oschina.net 时,你会打开一个套接字,然后连接到 www.oschina.net 并读取响应的页面然后然后显示出来。而其他一些聊天客户端如 gtalk 和 skype 也是类似。任何网络通讯都是通过 Socket 来完成的。本教程假设你已经有一些基本的 Python 编程的知识。让我们开始..._python socket connect

推荐文章

热门文章

相关标签