Maven 环境下使用 proguard-maven-plugin 插件混淆你的源码

摘要  a、ProGuard(http://proguard.sourceforge.net/) 是比较出色的 Java 代码混淆工具,可以有效的保护与优化你的代码。当然这里说的保护是防止恶意抄袭,通过混淆造成反编译阅读困难。但逻辑与内容并不会加密,仔细分析还是可以获得一些信息。 b、proguard-maven-plugin 是 Maven 中的 ProGuard 插件,可以非常方便的在你做 Maven 打包时进行代码混淆。 c、本文重点介绍 Maven 环境下插件的配置(重点参数),与类路径加载资源问题。
proguard  maven  混淆  jar  java

目录[-]

  • 一、场景介绍
  • 二、Maven 配置
  • 1、Project1 的 pom.xml
  • 2、Project2 的 pom.xml
  • 三、Java 混淆前后内容比较
  • 1、混淆前的 Project2 类
  • 2、混淆后的 Project2 类
  • 四、类路径中资源加载问题
  • 五、总结
  • 一、场景介绍

    两个工程 Project1,Project2(将被混淆的工程)。Project1 将通过 Maven 依赖配置的方式引用混淆后的 Project2。后面我会详细介绍 pom.xml 的配置。

    二、Maven 配置

    1、Project1 的 pom.xml

    该 pom.xml 比较简单主要通过 classifier 来判断是否使用混淆的 Jar(Project2)

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    xml version = "1.0" encoding = "UTF-8" ?>
    < project xmlns = "http://maven.apache.org/POM/4.0.0"
              xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" >
         < modelVersion >4.0.0 modelVersion >
     
         < groupId >org.noahx.proguard.example groupId >
         < artifactId >project1 artifactId >
         < version >1.0-SNAPSHOT version >
     
         < dependencies >
             < dependency >
                 < groupId >org.noahx.proguard.example groupId >
                 < artifactId >project2 artifactId >
                 < classifier >pg classifier >
                 < version >1.0-SNAPSHOT version >
             dependency >
         dependencies >
     
    project >


    2、Project2 的 pom.xml

    pom.xml 中配置的 proguard-maven-plugin 来做混淆,详细说明见注释。

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    xml version = "1.0" encoding = "UTF-8" ?>
    < project xmlns = "http://maven.apache.org/POM/4.0.0"
              xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" >
         < modelVersion >4.0.0 modelVersion >
     
         < groupId >org.noahx.proguard.example groupId >
         < artifactId >project2 artifactId >
         < version >1.0-SNAPSHOT version >
     
     
         < build >
             < plugins >
     
                 < plugin >
                     < groupId >com.github.wvengen groupId >
                     < artifactId >proguard-maven-plugin artifactId >
                     < version >2.0.7 version >
                     < executions >
                         < execution >
                             < phase >package phase >
                             < goals >
                                 < goal >proguard goal >
                             goals >
                         execution >
                     executions >
                     < configuration >
                         < attach >true attach >
                         < attachArtifactClassifier >pg attachArtifactClassifier >
                        
                         < options >
                            
                             < option >-ignorewarnings option >
                             < option >-dontshrink option >  
                             < option >-dontoptimize option >
                             < option >-dontskipnonpubliclibraryclasses option >
                             < option >-dontskipnonpubliclibraryclassmembers option >
     
                             < option >-repackageclasses org.noahx.proguard.example.project2.pg option >
                            
     
                            
     
                             < option >-keep class **.package-info option >
                            
     
                             < option >-keepattributes Signature option >
                            
                            
     
                             < option >-keepattributes SourceFile,LineNumberTable,*Annotation* option >
                            
     
                             < option >-keepclassmembers enum org.noahx.proguard.example.project2.** { *;} option >
                            
     
                             < option >-keep class org.noahx.proguard.example.project2.bean.** { *;} option >
                            
     
                             < option >-keep class org.noahx.proguard.example.project2.Project2 { public void init(); public void
                                 destroy(); }
                             option >
                            
     
                         options >
                         < outjar >${project.build.finalName}-pg outjar >
                         < libs >
                             < lib >${java.home}/lib/rt.jar lib >
                         libs >
     
                     configuration >
                 plugin >
     
              plugins >
         build >
     
    project >


    三、Java 混淆前后内容比较

    这里只比较 Project2 类的不同。其它类的比较,请大家使用 jd-gui 等反编译工具进行比较。

    1、混淆前的 Project2 类

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    package org.noahx.proguard.example.project2;
     
    import org.noahx.proguard.example.project2.dao.TestDao;
    import org.noahx.proguard.example.project2.impl.User;
     
    /**
      * Created by noah on 8/20/14.
      */
    public class Project2 {
     
         public void init() {
             test1();
             test2();
         }
     
         private void test1() {
             Status on = Status.valueOf( "On" );
             switch (on) {
                 case On: {
     
                 }
                 break ;
                 case Off: {
     
                 }
                 break ;
             }
         }
     
         private void test2() {
             TestDao testDao= new TestDao();
             User user= new User();
             user.setUserid( "abc" );
             user.setPassword( "pwd" );
             user.setDescription( "des" );
             testDao.save(user);
     
         }
     
         private void test3() {
         }
     
         private void test4() {
         }
     
         private void throwException() {
             throw new RuntimeException( "hello" );
         }
     
         public void destroy() {
             test3();
             test4();
             throwException();
         }
    }


    2、混淆后的 Project2 类

    所有没有指定 keep 的内容都变为了 a,b,c...,增大了阅读难度。

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    package org.noahx.proguard.example.project2;
     
    import org.noahx.proguard.example.project2.pg.a;
     
    public class Project2
    {
       public void init()
       {
         b();
         c();
       }
     
       private void b() {
         b localb = b.valueOf( "On" );
         switch (a.a[localb.ordinal()])
         {
         case 1 :
           break ;
         case 2 :
         }
       }
     
       private void c()
       {
         a locala = new a();
         org.noahx.proguard.example.project2.pg.b localb = new org.noahx.proguard.example.project2.pg.b();
         localb.a( "abc" );
         localb.b( "pwd" );
         localb.c( "des" );
         locala.a(localb);
       }
     
       private void d()
       {
       }
     
       private void e() {
       }
     
       public void a() {
         throw new RuntimeException( "hello" );
       }
     
       public void destroy() {
         d();
         e();
         a();
       }
    }


    四、类路径中资源加载问题

    使用 ProGuard 产生的 Jar 包,会发生无法定位 Jar 中资源的问题。原因不详,我没有太深入研究。

    使用 [类名].class.getResource(),Thread.currentThread().getContextClassLoader().getResource(),不论是否以“/”开头都返回 null。没有混淆的 Jar 是没有这个问题的。

    我使用了一种直接读取 Jar 中内容的方式来解决。

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    final File jarFile = new File([类名]. class .getProtectionDomain().getCodeSource().getLocation().getPath()); //定位类所在的 Jar 文件
                 if (jarFile.isFile()) {
                     final JarFile jar = new JarFile(jarFile);
                     Enumeration entries = jar.entries();
                     while (entries.hasMoreElements()) {
                         JarEntry entry = entries.nextElement();
                         if (entry.getName().startsWith( "org/noahx" )) {
                             InputStream entryInputStream = jarFile.getInputStream(entry);  //遍历包中的内容来获得资源
                         }
                     }
                     jar.close();
                 }

    五、总结

    使用 proguard-maven-plugin 插件,既保持了 Maven 的依赖模式,又满足了我的混淆需求。其它详细的参数配置,大家可以参考官方文档。

    ProGuard 满足了我的需求。至于是好是坏,希望大家不要围绕这点做没有必要的争论,谢谢。

    样例程序下载:http://pan.baidu.com/s/1dDGNoDr

    你可能感兴趣的:(Java,maven)