JAVA代码proguard混淆

12 篇文章 1 订阅
一,混淆文件一般设置
#输出log
-verbose
#略过warning,不输出warning(有warning时无法继续)
-ignorewarnings
#不输出warning,这里可以限定某些类不要warning
-dontwarn 
#不校验.校验可以提高java虚拟机的加载效率(java6)
-dontpreverify
#不混淆
#-dontobfuscate
#需要混淆的目录 
#-obfuscationdictionary
#统一混淆.避免情况:两个有同样签名的接口. 一个类实现了上述的两个接口.如果两个接口签名混淆之后不同,那么是有问题的.所以一开始就混淆为相同的
-useuniqueclassmembernames
#指定在混淆时应用主动重载。即一个类zhongyingg不同签名的方法. 可以混淆为同一个名称(只要签名不一样)
-overloadaggressively
#不混用大小写(即把大写和小写字母当成同一个), 在一些不分辨大小写的系统打开类是有用的
-dontusemixedcaseclassnames
#将所有重命名的包移动到指定包, 无参数或空串则移动到根包,会使混淆更加难以理解. 类似的还有 -repackageclasses(针对class)
#-flattenpackagehierarchy [package_name]
#########优化
#不优化
#-dontoptimize
#优化等级
#-optimizationpasses 3
#优化时允许访问并修改有修饰符的类和类的成员,(可配合repackageclasses使用). (作为lib的不应该使用)
#-allowaccessmodification
#合并接口
#-mergeinterfacesaggressively
#############压缩
#不压缩
-dontshrink
##########输入输出#######
#目标版本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)
-target 1.7
#指定lib,在maven中一般只需要${java.home}/lib/rt.jar
#-libraryjars class_path
#指定输出jar
#-outjars class_path
#指定输入jar 
-injars class_path
#指定基础路径
#-basedirectory directoryname
#指定在读取库jar时跳过非公共类,以加快处理速度并减少ProGuard的内存使用。某些情况可能出错,因此不使用
#-skipnonpubliclibraryclasses
#指定不忽略非公共图书馆类。默认配置
#-dontskipnonpubliclibraryclasses
#指定不忽略包可见库类成员(字段和方法)。
-dontskipnonpubliclibraryclassmembers

二, keep相关

通配符和关键字
  • 类通配符
?  # 表示一个字符
* # 多个字符, 如. pac1.*Test* 则 pac1.MyTest12 符合 , pac2.* 则表示包下pac2的类都符合,但不包括子包   
** # 通配多个字符和路径. 如 **.Test 则表示所有包的Test类,  pac3.** 则表示pac3的类和子包下的类.
  • 字段和方法通配符
?    #单个字符
*    #多个字符
  • 类型通配符
% # 不包含void的基本类型.void直接用void表示即可.
? #单个字符
* #多个字符,不包含类路径. (不包括基础类型)
** #多个字符,包括类路径. (不包括基础类型),即用这个可以表示所有非基础类型的值类型
*** # 通配所有类型
... # 所有数量所有类型参数.
  • 否定和与
! #表示否定
, #可以表示与的含义,如 !foobar,*bar 表示以bar结尾但是除了foobar. foo,*bar 表示匹配foo和bar结尾的(空)
  • 描述通配符
<init>  # 通配所有构造函数
<fields> # 通配所有字段
<methods> # 通配所有方法
* # 字段或方法.(与上面三个处于同一级时)
  • 其他描述符基本上和我们看到的意义一样, 简单挑几个解释一下
extends 和 implements  # 目前是等价的.注意,这个限定不包含自身,如果需要自身,则增加一条keep即可.
class   # 所有class和interface
interface # 限制为interface . 可以和否定 ! 一起使用
enum   # 枚举. 可以和否定 ! 一起使用
  • 完整的类和类型,方法
[@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说明
  • 对类和成员都生效的 -keepkeepnames
  • 只对成员生效的 -keepclassmembers-keepclassmembernames
  • 对类和成员生效,如果类成员存在(前提). -keepclasseswithmembers-keepclasseswithmembernames
其他keep
  • -keeppackagenames [package_filter] : 指定不混淆的包名, 可用通配符 ? * ** !
  • -keepattributes [attribute_filter] : 指定要保留的属性(方法类型和参数, 注释也属于属性), 例如Exception, 可以用多个或","分割, 一般为如下:
    -keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod
  • -keepparameternames : 保留方法参数名和类型. 相当于 -keepattributes LocalVariableTable,LocalVariableTypeTable
  • -keepdirectories [directory_filter] :指定要保存在输出jar(或war、ear或目录)中的目录。如果没有指定, 则保留全部目录
  • p.s -adaptclassstrings [class_filter] -adaptxxxxxxx 有点和-keepXXX 相反的意思. 过滤掉keep中的特殊.

三,maven中使用

  • 常用配置说明
<!-- ProGuard混淆插件-->
            <plugin>
                <groupId>com.github.wvengen</groupId>
                <artifactId>proguard-maven-plugin</artifactId>
                <version>2.1.1</version>
                <executions>
                    <execution>
                        <!-- 混淆时刻,这里是打包的时候混淆,还可以选择compile,process-class,取决于injar配置-->
                        <phase>package</phase>
                        <goals>
                            <!-- 使用插件的混淆功能-->
                            <goal>proguard</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                	<!-- 是否另外创建构件,默认为false,true则在target目录产生 同名_small.jar文件,后缀取决于另一配置-->
                    <attach>false</attach>
                    <!-- 另外产生的构件 后缀名,attach为true时才有用, 不指定时为small-->
                    <attachArtifactClassifier>proguard</attachArtifactClassifier>
                    <!-- 是否混淆,默认为true-->
                    <obfuscate>true</obfuscate>
                    <!-- 混淆配置文件,可选,不配置的话只需要在configuration下配置相关的配置即可-->
                    <proguardInclude>${basedir}/proguard.conf</proguardInclude>
                    <!-- 可放 proguard的配置  -->
                    <!-- <options></options> -->
                    <!-- 依赖,按需修改,一般一个JRE的Runtime包就行了 -->
                    <libs>
                        <lib>${java.home}/lib/rt.jar</lib>
                    </libs>
                    <!-- 指定要处理的jar|war|zip包,默认${project.build.finalName}.jar
                    <!-- 即,该插件默认是在package产生原始jar包后,对输出jar包进行处理的. 这里也可以指定为classes--对产生原始jar的class输入进行处理,但是这样子要生效,则必须修改插件作用的生命周期,将package改为 compile 或 process-classes -->
                    <injar>${project.build.finalName}.jar</injar>
                    <!-- 指定多生成jar包名称(原始名称的jar还是混淆的),在attach为true时不生效(attach本身就会多产生jar包)-->
                    <!-- <outjar>${project.build.finalName}-proguard.jar</outjar> -->
                    <!-- 输出目录,默认即为${project.build.directory}-->
                    <!-- <outputDirectory>${project.build.directory}</outputDirectory> -->
                </configuration>
            </plugin>
  • 简单配置如下, 该配置会使生成的 jar已经混淆, 同时在 target下产生一个 同名_proguard_base.jar , 这个文件为未混淆前的jar.
<build>
        <plugins>
            <plugin>
                <groupId>com.github.wvengen</groupId>
                <artifactId>proguard-maven-plugin</artifactId>
                <executions>
                   <execution>
                       <phase>package</phase>
                       <goals><goal>proguard</goal></goals>
                   </execution>
                </executions>
                <configuration>
                    <proguardInclude>${basedir}/proguard.conf</proguardInclude>
                    <libs>
                        <lib>${java.home}/lib/rt.jar</lib>
                    </libs>
                </configuration>
            </plugin>
        </plugins>
    </build>

四,例子

  • 混淆文件
-target 1.7
-dontshrink
-dontoptimize
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-useuniqueclassmembernames
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod
-verbose
-keepclassmembernames class * {
    java.lang.Class class$(java.lang.String);
    java.lang.Class class$(java.lang.String, boolean);
}
#-repackageclasses ''
-keepclasseswithmembernames class * {
    native <methods>;
}

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

# servlet和filter或者其他配置在bean上需要保留类名的
-keepnames class * implements javax.servlet.Filter
-keep public class * implements javax.servlet.Servlet
-keepnames class * extends org.springframework.web.servlet.handler.HandlerInterceptorAdapter
-keepnames class com.jt.base.web.servlet.JTFreeMarkerView
-keepnames class com.jt.crm.common.helper.FreeMarkerStaticExtImpl
-keepnames class net.bull.javamelody.SpringDataSourceFactoryBean


# 保留事务和缓存切面的包路径
-keeppackagenames com.jt.*.*.domain.*
-keeppackagenames **.service.*
-keeppackagenames **.repository.*

# 拦截器不要修改其公共方法
-keep public class * extends org.springframework.web.servlet.handler.HandlerInterceptorAdapter{
    public *;
}


# 事务类read事务不改变方法名
-keepclassmembernames class com.jt.*.*.domain.*{
	*** get*(***);
	*** is*(***);
	*** find*(***);
	*** query*(***);
}
# 事务类read事务不改变方法名
-keepclassmembernames class com.jt.*.*.service.*{
	*** get*(***);
	*** is*(***);
	*** find*(***);
	*** query*(***);
}
# filter不修改其重写的方法
-keepclassmembers class * implements javax.servlet.Filter {
    public void init(javax.servlet.FilterConfig);
    public void doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse,javax.servlet.FilterChain);
    public void destroy();
}
-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
    !static !transient <fields>;
    !private <fields>;
    !private <methods>;
}

-keepnames class * implements java.io.Serializable



-keepattributes *Annotation*
-keep class * implements java.sql.Driver

-adaptresourcefilenames    **.properties,**.gif,**.jpg
-adaptresourcefilecontents **.properties,META-INF/MANIFEST.MF,WEB-INF/conf


# 特定包需要保留的类名等
-keepnames class com.jt.components.upload.* 
-keepnames class com.jt.components.upload.constants.** 
-keepnames class com.jt.components.upload.local.controller.**  
-keepnames class com.jt.components.upload.download.** 
-keepnames class com.jt.components.upload.mongodb.helper.MGFileHelper 
-keepnames class com.jt.components.upload.mongodb.util.** 
-keepnames class com.jt.components.cloud.aliyunoss.**
-keepclassmembernames class com.jt.components.upload.*** {
    public *;
}

主要是能够理解上面提到的三个方面(keep是重点) , 就能根据自己的需要进行相应的修改.
参考:

proguard
proguard官网
proguard插件

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值