proguard保持类文件中的枚举类型名称

时间:2017-08-27 15:29:19

标签: java ant proguard

我试图在java中混淆​​一个枚举类型的文件,我注意到我可以得到proguard来模糊我想要的枚举类型的名称,包括引用,但是它保留了枚举类型的旧名称在类文件中。

例如:

Proguard配置:

<project name="Library" default="obfuscate" basedir=".">

<taskdef resource="proguard/ant/task.properties" classpath="proguard.jar"/>

<target name="build">
  <javac srcdir="src" includeantruntime="true" destdir="build">
    <compilerarg value="-Xlint:deprecation" />
  </javac>

  <jar jarfile="jarfile.jar" basedir="build" />

</target>

<target name="obfuscate">
  <taskdef resource="proguard/ant/task.properties"
           classpath="lib/proguard.jar" />

  <proguard printmapping="out.map"
            allowaccessmodification="true"
            obfuscationdictionary="random.txt"
            classobfuscationdictionary="random-c.txt"
            packageobfuscationdictionary="random-p.txt"
            renamesourcefileattribute="SourceFile">

    <!-- Specify the input jars, output jars, and library jars. -->

    <injar  file="jarfile.jar" />
    <outjar file="output/library_out.jar" />

    <libraryjar file="${java.home}/lib/rt.jar" />

    <!-- Keep some useful attributes. -->

    <keepattribute name="InnerClasses" />
    <keepattribute name="SourceFile" />
    <keepattribute name="LineNumberTable" />
    <keepattribute name="Deprecated" />
    <keepattribute name="*Annotation*" />

    <keep name="test.**" allowobfuscation="true">
        <field access="public protected" />
        <method access="public protected" />
    </keep>
    <keepclassmembernames access="public">
        <method access = "public static"
                type   = "void"
                name   = "main"
                parameters = "java.lang.String[]"/>
    </keepclassmembernames>
    <keepclassmembernames access="public">
      <method type      ="java.lang.Class"
              name      ="class$"
              parameters="java.lang.String" />
      <method type      ="java.lang.Class"
              name      ="class$"
              parameters="java.lang.String,boolean" />
    </keepclassmembernames>

    <!-- Preserve all native method names and the names of their classes. -->

    <keepclasseswithmembernames includedescriptorclasses="true">
      <method access="native" />
    </keepclasseswithmembernames>

    <!-- Preserve the methods that are required in all enumeration classes. -->

    <keepclassmembers allowoptimization="true" type="enum">
      <method access="public static"
              type="**[]"
              name="values"
              parameters="" />
      <method access="public static"
              type="**"
              name="valueOf"
              parameters="java.lang.String" />
    </keepclassmembers>

    <!-- Explicitly preserve all serialization members. The Serializable
         interface is only a marker interface, so it wouldn't save them.
         You can comment this out if your library doesn't use serialization.
         If your code contains serializable classes that have to be backward
         compatible, please refer to the manual. -->

    <keepclassmembers implements="java.io.Serializable">
      <field  access    ="final"
              type      ="long"
              name      ="serialVersionUID" />
      <field  access    ="static final"
              type      ="java.io.ObjectStreamField[]"
              name      ="serialPersistentFields" />
      <method access    ="private"
              type      ="void"
              name      ="writeObject"
              parameters="java.io.ObjectOutputStream" />
      <method access    ="private"
              type      ="void"
              name      ="readObject"
              parameters="java.io.ObjectInputStream" />
      <method type      ="java.lang.Object"
              name      ="writeReplace"
              parameters="" />
      <method type      ="java.lang.Object"
              name      ="readResolve"
              parameters="" />
    </keepclassmembers>

    <!-- Your application may contain more items that need to be preserved;
      typically classes that are dynamically created using Class.forName -->

  </proguard>
</target>

</project>

两个Java文件:

mainClass.java:

package test;

public class mainClass {
  public static void main(String[] args){
    System.out.println(TestEnum.TEST);
    System.out.println(TestEnum.TESTAGAIN);
    System.out.println(TestEnum.TESTAGAINAGAIN);
  }
}

TestEnum.java:

package test;
public enum TestEnum {
  TEST,
  TESTAGAIN,
  TESTAGAINAGAIN;
}

TestEnum.java的“模糊”类文件包含以下字符串:

> $ strings ff42d24eb40678f60462c47c07218c6ba0be/fdbdd99cf9e2f8336f5ac70ee1c6b0c002e23d44.class

()Ljava/lang/Object;
R()[Lff42d24eb40678f60462c47c07218c6ba0be/fdbdd99cf9e2f8336f5ac70ee1c6b0c002e23d44;
5(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
c(Ljava/lang/String;)Lff42d24eb40678f60462c47c07218c6ba0be/fdbdd99cf9e2f8336f5ac70ee1c6b0c002e23d44;
(Ljava/lang/String;I)V
<clinit>
<init>
Code
OLff42d24eb40678f60462c47c07218c6ba0be/fdbdd99cf9e2f8336f5ac70ee1c6b0c002e23d44;
TEST
    TESTAGAIN
TESTAGAINAGAIN
P[Lff42d24eb40678f60462c47c07218c6ba0be/fdbdd99cf9e2f8336f5ac70ee1c6b0c002e23d44;
(bd5e3e98f5d9552fad4cea7dd9f09ec970b5c537
c4b09ad3a6fc8bdb613d7a47ae6b62
clone
$f0330a7bb6fff9a6c846ffe92c696633cc9c
'fca7ea2fd7d090d4fc3b0f2f22c2a234b16cebb
Mff42d24eb40678f60462c47c07218c6ba0be/fdbdd99cf9e2f8336f5ac70ee1c6b0c002e23d44
java/lang/Enum
valueOf
values@1

这是mainClass的字符串转储:

> $ strings ff42d24eb40678f60462c47c07218c6ba0be/e254fec352c913191237dc8c2e9030b20da756f2.class 

(Ljava/lang/Object;)V
([Ljava/lang/String;)V
<init>
Code
OLff42d24eb40678f60462c47c07218c6ba0be/fdbdd99cf9e2f8336f5ac70ee1c6b0c002e23d44;
Ljava/io/PrintStream;
(bd5e3e98f5d9552fad4cea7dd9f09ec970b5c537
$f0330a7bb6fff9a6c846ffe92c696633cc9c
'fca7ea2fd7d090d4fc3b0f2f22c2a234b16cebb
Mff42d24eb40678f60462c47c07218c6ba0be/e254fec352c913191237dc8c2e9030b20da756f2
Mff42d24eb40678f60462c47c07218c6ba0be/fdbdd99cf9e2f8336f5ac70ee1c6b0c002e23d44
java/io/PrintStream
java/lang/Object
java/lang/System
main
println

正如您所见,TEST,TESTAGAIN和TESTAGAINAGAIN仍然包含在类文件中,但实际上并未在mainClass中使用,而是使用了它们的混淆名称。

事实上,如果你在像JD-GUI这样的程序中查看这些类文件,它们也不会显示,但它们本身也包含在类文件中。有没有办法通过proguard删除类文件中的TEST,TESTAGAIN和TESTAGAINAGAIN?

这是用proguard 5.3.3运行的,用java 8编译。可以在这里找到一个例子:https://github.com/mirabellatook/ant-proguard-example

0 个答案:

没有答案