当前位置: 首页 > 工具软件 > ProGuard > 使用案例 >

proguard介绍

田德运
2023-12-01

1.ProGuard介绍

ProGuard是一个压缩、优化和混淆Java字节码文件的免费的工具,它可以删除无用的类、字段、方法和属性。可以删除没用的注释,最大限度地优化字节码文件。它还可以使用简短的无意义的名称来重命名已经存在的类、字段、方法和属性。常常用于Android开发用于混淆最终的项目,增加项目被反编译的难度。
下面是官网http://proguard.sourceforge.net/)的一段介绍:

ProGuard is a free Java class file shrinker, optimizer, obfuscator, and preverifier. It detects and removes unused classes, fields, methods, and attributes. It optimizes bytecode and removes unused instructions. It renames the remaining classes, fields, and methods using short meaningless names. Finally, it preverifies the processed code for Java 6 or higher, or for Java Micro Edition.

ProGuard's main advantage compared to other Java obfuscators is probably its compact template-      based configuration. A few intuitive command line options or a simple configuration file are usually sufficient. The user manual explains all available options and shows examples of this powerful configuration style.

ProGuard特点是免费,可以压缩,优化和混淆java代码。最重要的一点应该是混淆代码,防止代码轻易被反编译。作者是Eric P.F. Lafortune,比利时人,主要从事计算机图形学研究。从2002年开始发布ProGuard,一直维护到现在,最新版本是ProGuard5.2 下载连接。ProGuard总体上还是比较简单的,提供了一个GUI简单界面,如果代码相对简单,按照默认操作就可以混淆了,但是对于稍微复杂一点的项目,还是需要手动配置proguard.conf。官网上ProGuard Troubleshooting页面有一些常见问题的回答,同时作者也经常在sourceforge.net上回答相关的问题。

2.ProGuard语法

ProGuard是基于命令行的工具,出现的问题基本上要靠相关命令来解决。所以有必要了解一些语法。更详细的见参考内容。

1、ProGuard的常用语法
-libraryjars class_path 应用的依赖包,如android-support-v4
-keep [,modifier,...] class_specification 不混淆某些类
-keepclassmembers [,modifier,...] class_specification 不混淆类的成员
-keepclasseswithmembers [,modifier,...] class_specification 不混淆类及其成员
-keepnames class_specification 不混淆类及其成员名
-keepclassmembernames class_specification 不混淆类的成员名
-keepclasseswithmembernames class_specification 不混淆类及其成员名
-assumenosideeffects class_specification 假设调用不产生任何影响,在proguard代码优化时会将该调用remove掉。如system.out.println和Log.v等等
-dontwarn [class_filter] 不提示warnning
2、常用proguard.cfg代码段
不混淆某类的构造方法,需指定构造函数的参数类型,如JSONObject

-keepclassmembers class cn.trinea.android.common.service.impl.ImageCache {
   public <init>(int);
}
 
不混淆某个包所有类或某个类class、某个接口interface, 不混淆指定类则把**换成类名

-keep class cn.trinea.android.common.** { *; }
 
不混淆指某个方法,*可换成指定的方法或类名

-keepclassmembers class cn.trinea.android.common.service.impl.ImageCache {
   public boolean get(java.lang.String, android.view.View);
}
 
不混淆Parcelable的子类,防止android.os.BadParcelableException

-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}
 
添加android-support-v4.jar依赖包

-libraryjars   libs/android-support-v4.jar
-dontwarn android.support.v4.**    
-keep class android.support.v4.** { *; }  
-keep interface android.support.v4.app.** { *; }

3.maven+ProGuard混淆java代码

我是需要讲web工程中打包后的类进行代码混淆。工程采用maven来管理,它已经有类似插件了。只要下回插件并添加相应的配置文件即可。
主要有两步。一是修改pom.xml文件。添加依赖和插件如下:

<!-- 使用5.2版本来混淆  --> 
        <dependency>
            <groupId>net.sf.proguard</groupId>
            <artifactId>proguard-base</artifactId>  
            <version>5.2</version>
            <scope>runtime</scope>
        </dependency> 

<plugin>
                <groupId>com.github.wvengen</groupId>
                <artifactId>proguard-maven-plugin</artifactId>
                <version>2.0.10</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>proguard</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <proguardVersion>5.2</proguardVersion>
                    <obfuscate>true</obfuscate>
                    <proguardInclude>${basedir}/proguard.conf</proguardInclude> 
                    <!-- 添加依赖,这里你可以按你的需要修改 -->
                    <libs>
                        <lib>${java.home}/lib/rt.jar</lib>                      
                        <lib>${basedir}/lib</lib>
                      
                    </libs>
                    <addMavenDescriptor>false</addMavenDescriptor>
                  <!--  <injar>${project.build.finalName}.war</injar>
                    <libraryjars>${basedir}/src/main/radi.jar</libraryjars>   
                    <outjar>${project.build.finalName}-pg.war</outjar> --> 
                    <outputDirectory>${project.build.directory}</outputDirectory>
                </configuration>

            </plugin>   
二是 添加proguard.conf文件,放到pom.xml目录下就可以。
# ----------------------------------
#  通过指定数量的优化能执行
#  -optimizationpasses n
# ----------------------------------
-dontoptimize
# ----------------------------------
#   混淆时不会产生形形色色的类名 
#   -dontusemixedcaseclassnames
# ----------------------------------
#-dontusemixedcaseclassnames

# ----------------------------------
#      指定不去忽略非公共的库类
#  -dontskipnonpubliclibraryclasses
# ----------------------------------
-dontskipnonpubliclibraryclasses

# ----------------------------------
#       不预校验
#    -dontpreverify
# ----------------------------------
 #-dontpreverify

# ----------------------------------
#      输出生成信息
#       -verbose
# ----------------------------------
-verbose

#不缩减代码
-dontshrink

#混淆时应用侵入式重载 
-overloadaggressively 
 
#优化时允许访问并修改有修饰符的类和类的成员 
-allowaccessmodification
#确定统一的混淆类的成员名称来增加混淆 
-useuniqueclassmembernames

-injars D:/progrs/DOMSGS/OrbitService/target/OrbitService.war(!WEB-INF/classes/**)
-outjars D:/progrs/DOMSGS/OrbitService/target/OrbitService6pg.war

-dontnote
-ignorewarnings
-dontwarn net.landwind.hip.console.**

#消除警告 Warning: can't find superclass or interface
#Warning: can't find referenced class
-dontwarn org.springframework.**
-keep class org.springframework.** { *;}
-dontwarn org.codehaus.**
-keep class org.codehaus.** { *;}
-dontwarn org.apache.**
-keep class org.apache.** { *;}

# obfuscates the package names further
#-flattenpackagehierarchy 'myobfuscated'

-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod

#这里添加你不需要混淆的类
-dontwarn radi.domsgs.mvc.**
-keep class radi.domsgs.mvc.endpoint.** { *;}
#-keep class radi.domsgs.mvc.service.** { *;} 
-keep class radi.domsgs.mvc.controller.** { *;} 

#保留类及其所有方法 成员
#-keepclasseswithmembers class radi.domsgs.mvc.endpoint.AccessEndpoint {
    
  #  <fields>;#匹配所有成员
  #  <methods>;#匹配所有方法
#}

# ---------保护所有实体中的字段名称----------
-keepclassmembers class * implements java.io.Serializable {
    <fields>;
}
-keepclassmembers class **.R$* {
    public static <fields>;
}

# --------- 保护类中的所有方法名 ------------
-keepclassmembers class * {
	public <methods>;
}
-keepclasseswithmembernames,includedescriptorclasses class * {
    native <methods>;
}
# Preserve the special static methods that are required in all enumeration classes.
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}
-printmapping out.map  
-renamesourcefileattribute SourceFile  
-keepattributes Exceptions,SourceFile  
 
这里面需要注意的是下列类不能进行混淆:
(1)、反射用到的类
(2)、在AndroidManifest中配置的类(Activity、Service等的子类及Framework类默认不会进行混淆)
(3)、Jni中调用的类
这些类是需要保留的,同时,一些第三方包的类也需要保留,我前面一篇文章proguard 提示Warning: can't find referenced classes等问题有说到一些相关方法。配置没有问题,混淆成功后就可以发布测试了。

参考:
1.http://www.trinea.cn/android/proguard-grammar/
2.http://blog.csdn.net/zhangjianying/article/details/7939593
3.http://proguard.sourceforge.net/index.html#/manual/examples.html











 类似资料: