0

それぞれゲッターとセッターを持つさまざまな属性を持つ単純な POJO があります。id と serialNumber という名前のものを除いて、すべて問題なく難読化されています。

id 属性の名前は変更されず、ゲッターとセッターも変更されません。

serialNumber 属性の名前は変更されますが、ゲッターとセッターは変更されません。

これらの属性について特別なことは何もありません。また、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

およびマップファイルからの出力

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
4

2 に答える 2

4

-useuniqueclassmembernamesオプションの使用によるものです。

クラス メンバー名がグローバルに対応する必要がある場合( Java ランタイム ライブラリを含む)、このオプションはすべてのクラスのすべてのクラス メンバーをリンクします。

つまり、あるクラスFoo#getName()に難読化されているメソッドがある場合a()、他のクラスの同じ名前のメソッドBar#getName()も難読化された名前にマップされますa()

Foo.getName() -> Foo.a()
Bar.getName() -> Bar.a()

ライブラリ jar が登場します。ProGuard はライブラリ jar も参照して参照を調べるため、クラスをスキャンrt.jarして次のようなクラスを見つけます。

  • com/sun/servicetag/SystemEnvironment
  • java/セキュリティ/証明書/X509CertSelector

これらのクラスにはメソッドもあります:

  • com.sun.servicetag.SystemEnvironment.getSerialNumber()
  • java.security.cert.X509CertSelector.getSerialNumber()

これらのメンバーは難読化のために無視されますが、それらの名前マッピング ( getSerialNumber> getSerialNumber) は ProGuard によって記録され、 useUniqueClassMemberNames 構成オプションにより記述子マップに保持されます。

参考までに、構成ファイルを使用してProGuardをデバッグすることでこれを見つけました。メンバー情報リンカーの場合、BottomClassFilter の代わりに AllMemberVisitor が使用されているようですが、ProGuard の内部がどのように機能するかについて、私はそれほど深く理解していません。

于 2012-06-13T19:18:03.203 に答える
3

このオプション-useuniqueclassmembernamesは、コードの変更に対する難読化マッピングを将来的に保証するためにこれを行います。将来のコードでは、このクラスと、これらのメソッドを含む一部のライブラリ クラスに共通のインターフェイスが追加される可能性があります。メソッドの名前が変更された場合、これによりマッピングが壊れます。

于 2012-06-13T19:20:53.043 に答える