Java Proguard不混淆方法getId()和getSerialNumber()

Java Proguard不混淆方法getId()和getSerialNumber(),java,obfuscation,proguard,Java,Obfuscation,Proguard,我有一个简单的POJO,具有各种属性,每个属性都有getter和setter。除了名为id和serialNumber的代码外,所有代码都被模糊处理 id属性不会被重命名,其getter和setter也不会被重命名 serialNumber属性确实会重命名,但其getter和setter不会重命名 这些属性没有什么特别之处,我也没有在Proguard配置中添加任何东西,以使Proguard区别对待它们 我的Proguard配置 # Fudge around some issues -dontski

我有一个简单的POJO,具有各种属性,每个属性都有getter和setter。除了名为id和serialNumber的代码外,所有代码都被模糊处理

id属性不会被重命名,其getter和setter也不会被重命名

serialNumber属性确实会重命名,但其getter和setter不会重命名

这些属性没有什么特别之处,我也没有在Proguard配置中添加任何东西,以使Proguard区别对待它们

我的Proguard配置

# Fudge around some issues
-dontskipnonpubliclibraryclasses

# Preserve all annotations.
-keepattributes *Annotation*

# Preserve all native method names and the names of their classes.
-keepclasseswithmembernames class * {
    native <methods>;
}

# Preserve the special static methods that are required in all enumeration
# classes.
-keepclassmembers class * extends java.lang.Enum {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

# 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 application doesn't use serialization.
# If your code contains serializable classes that have to be backward 
# compatible, please refer to the manual.
-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    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();
}

# Keep some source file attributes so we have a chance of decoding stack traces
-renamesourcefileattribute SourceFile
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,
        SourceFile,LineNumberTable,*Annotation*,EnclosingMethod

# make sure we keep info for downstream libraries
-dontshrink
-dontoptimize
-useuniqueclassmembernames

这是由于使用了-useuniqueclassmembernames选项

如果类成员名称必须全局对应(包括Java运行时库),则此选项将所有类中的所有类成员链接在一起

这意味着,如果一个类中有任何方法FoogetName被模糊化为a,则其他类中具有相同名称BargetName的方法也将映射到模糊化名称a:

现在让图书馆的罐子发挥作用。由于ProGuard也会查看库jar以了解有关引用的信息,因此它会扫描rt.jar以查找类,并会找到如下类:

com/sun/servicetag/SystemEnvironment java/security/cert/X509CertSelector 等 这些类也有方法,这些方法包括:

com.sun.servicetag.SystemEnvironment.getSerialNumber java.security.cert.X509CertSelector.getSerialNumber 等 由于混淆,这些成员被忽略,但是它们的名称映射getSerialNumber>getSerialNumber由ProGuard记录,并由于useUniqueClassMemberNames配置选项而保留在描述符映射中

仅供参考:我是通过使用配置文件调试ProGuard发现这一点的。对于成员信息链接器,似乎使用了AllMemberVisitor而不是BottomClassFilter,但我还没有对ProGuard的内部工作原理有如此深入的了解。

选项-useuniqueclassmembernames可以做到这一点,以便将来验证代码中更改的模糊映射。未来的代码可能会为此类和包含这些方法的某些库类添加一个公共接口。如果重命名这些方法,这将破坏映射

java.lang.String id -> id
  int productCode -> a
  int platform -> b
  java.lang.String model -> c
  java.lang.String serialNumber -> d
  java.lang.String machineID -> e
  java.lang.String parentSerialNumber -> f
  long clientTime -> g
  38:38:java.lang.String getId() -> getId
  47:48:void setId(java.lang.String) -> setId
  52:52:int getProductCode() -> a
  57:58:void setProductCode(int) -> a
  62:62:int getPlatform() -> b
  67:68:void setPlatform(int) -> b
  72:72:java.lang.String getModel() -> c
  77:78:void setModel(java.lang.String) -> a
  82:82:java.lang.String getSerialNumber() -> getSerialNumber
  87:88:void setSerialNumber(java.lang.String) -> setSerialNumber
  92:92:java.lang.String getMachineID() -> d
  97:98:void setMachineID(java.lang.String) -> b
  102:102:java.lang.String getParentSerialNumber() -> e
  107:108:void setParentSerialNumber(java.lang.String) -> c
  112:112:long getClientTime() -> f
  117:118:void setClientTime(long) -> a
Foo.getName() -> Foo.a()
Bar.getName() -> Bar.a()