Verhindern Sie die Verschleierung des Namens von Klassenmitgliedern durch ProGuard


77

Ich habe meine Klasse ClassMultiPointmit Unterklassen.

public class ClassMultiPoints
 {
   public String message;
   public List<ClassPoints> data;

   public class ClassPoints
    {
      public String id;
      public List<ClassPoint> points;
      public class ClassPoint
       {
         public String speed;
         public String bearing;
       }
    }
 }

Ich werde den Wert des Objekts oPointsaus der Analyse erhalten GSON:

oPoints = gson.fromJson( jsonString, ClassMultiPoints.class);

Ich versuche es zu benutzen oPoints.message.

Wenn ich meine Anwendung ohne proguardErfolg bei der App-Ausführung ausführe. Wenn ich meine App mit proguardmeinem App-Absturz starte.

Ich denke, das Problem ist: proguardbenenne das Attribut 'oPoints.message'meiner Klasse in kurz um 'a'.

Ich versuche, die Namen der Methoden und Attribute konstant zu halten, proguardbenenne sie aber um:

proguard.cfg:

-injars      bin/classes
-injars      libs
-outjars     bin/classes-processed.jar
-dontpreverify
-repackageclasses ''
-allowaccessmodification
-optimizations !code/simplification/arithmetic
-keepattributes *Annotation*
-dontskipnonpubliclibraryclasses
-optimizationpasses 5
-printmapping map.txt
-flattenpackagehierarchy

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.MapActivity
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider

-libraryjars  libs/commons-io-2.2.jar
-libraryjars  libs/ftp4j-1.7.1.jar
-libraryjars  libs/gson-2.2.2.jar

-keep public class org.apache.commons.io.**
-keep public class it.sauronsoftware.ftp4j.**
-keep public class com.google.gson.**

-keep public class com.mypackagename.ActivityMonitor$*

-keep public class * extends android.view.View {
    public <init>(android.content.Context);
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
    public void set*(...);
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers class * extends android.content.Context {
   public void *(android.view.View);
   public void *(android.view.MenuItem);
}

-keepclassmembers class * implements android.os.Parcelable {
    static android.os.Parcelable$Creator CREATOR;
}

-keepclassmembers class **.R$* {
    public static <fields>;
}

Was ist der richtige Weg, um Namen der Methoden und Attribute der my one (statischen) Klasse beizubehalten?

Antworten:


69

Wenn Sie nicht möchten, dass Ihre Klassenmitglieder verschleiert werden, verwenden Sie SerializedNamedie von Gson bereitgestellten Anmerkungen. Zum Beispiel:

public class ClassMultiPoints
{
   @SerializedName("message")
   public String message;
   @SerializedName("data")
   public List<ClassPoints> data;

   ...

}

Stellen Sie außerdem sicher, dass Sie auch für die Gson-Bibliothek die richtige Proguard-Konfiguration hinzufügen. Zum Beispiel:

##---------------Begin: proguard configuration for Gson ----------
# Gson uses generic type information stored in a class file when working with
#fields. Proguard removes such information by default, so configure it to keep
#all of it.
-keepattributes Signature

# For using GSON @Expose annotation
-keepattributes *Annotation*

# Gson specific classes
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }

# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }

##---------------End: proguard configuration for Gson ----------

Für weitere Informationen lesen Sie diese .


1
-keep class com.google.gson.examples.android.model. ** {*; } es funktioniert für mich, aber als ich Reverse Engg auf apk angewendet habe, habe ich alle Modellklassen ohne Änderung der Mitglieder erhalten, es bricht den Sicherheitszweck, gibt es keine andere Option, können wir das Modell auch verschleiern?
Umesh

7
Verwenden Sie @SerializedNameAnmerkungen zusätzlich zu Ihren Klassenmitgliedern? Wenn Sie dies tun, müssen Sie die Verschleierung benutzerdefinierter Klassen in der Proguard-Konfiguration nicht umgehen, wie Sie es tun com.google.gson.examples.android.model.** { *; }.
Waqaslam

nein, eigentlich wollte ich es verschleiern. aber jetzt wurde mir klar, dass wenn sich die Feldnamen ändern, sie nicht mit dem json-Schlüssel übereinstimmen, so dass der gson ihn nicht analysieren konnte.
Umesh

3
genau ... und deshalb müssen wir @SerializedName
waqaslam

Ist diese Option für die gesamte Klasse verfügbar?
Oliver Dixon

28

Danke Waqas!

Ich finde eine Lösung für meinen Fall:

-optimizationpasses 5
-dump class_files.txt
-printseeds seeds.txt
-printusage unused.txt
-printmapping mapping.txt
-optimizations !code/simplification/arithmetic,!field/*,!class/merging*/
-allowaccessmodification
-repackageclasses ''

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.MapActivity
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider

-libraryjars  libs/commons-io-2.2.jar
-libraryjars  libs/gson-2.2.2.jar
-keep public class org.apache.commons.io.**
-keep public class com.google.gson.**
-keep public class com.google.gson.** {public private protected *;}

##---------------Begin: proguard configuration for Gson ----------
-keepattributes *Annotation*,Signature
-keep class com.mypackage.ActivityMonitor.ClassMultiPoints.** { *; }
-keep public class com.mypackage.ActivityMonitor$ClassMultiPoints     { public protected *; }
-keep public class com.mypackage.ActivityMonitor$ClassMultiPoints$ClassPoints { public protected *; }
-keep public class com.mypackage.ActivityMonitor$ClassMultiPoints$ClassPoints$ClassPoint { public protected *; }
# To support Enum type of class members
-keepclassmembers enum * { *; } 
##---------------End: proguard configuration for Gson ----------

Auch ich benutze nicht @SerializedName("message")in meiner Klasse, obige Konfiguration funktioniert gut ohne Serialisierung.


@iDroid Explorer Ich benutze apkTool, um die Veröffentlichung apk zu testen, aber die Verschleierung hat bei mir nicht funktioniert. Die Klassen wurden nicht umbenannt
Muhammad Younas

1
Diese Einstellungen erlauben es, den Code NICHT zu verschleiern. Benötigen Sie verschleierten Code?
Tapa Save

Ja, dieser Code ist nicht verschleiert oder ich
teste

24

Ich habe auch festgestellt, dass ich dies -keepclassmemberstun muss, wenn ich die Optimierungsoption von Dexguard verwende. Ohne dies konnten einige meiner Modellobjekte nicht deserialisiert werden

##---------------Begin: proguard configuration for Gson  ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature

# For using GSON @Expose annotation
-keepattributes *Annotation*

# Application classes that will be serialized/deserialized over Gson, keepclassmembers
-keep class com.myapp.model.** { *; }
-keepclassmembers class com.myapp.model.** { *; }

1
Besonderer Dank für -keepclassmembers class com.myapp.model.** { *; }. Obwohl ich Jackson Lib anstelle von Gson verwende, hat mir diese Zeile geholfen! Vielen Dank.
Mirjalal

9

Wenn Sie die @ExposeAnmerkung wie ich verwenden, können Sie ProGuard anweisen, jedes Feld mit Anmerkungen zu versehen:

# keep anything annotated with @Expose
-keepclassmembers public class * {
    @com.google.gson.annotations.Expose *;
}
# Also keep classes that @Expose everything
-keep @com.google.gson.annotations.Expose public class *

Laut GSON kann javadoc @Expose nur auf Felder abzielen. Die zweite Anweisung scheint also nutzlos zu sein
Anton Kazakov,


5

Um Ihre Klasse von der Verschleierung auszuschließen, behalten Sie die Attribute von InnerClasses bei, behalten Sie Ihre Klasse bei und behalten Sie die Klassenmitglieder der Klasse, z.

-keepattributes InnerClasses
 -keep class com.yourproject.YourClass**
 -keepclassmembers class com.yourproject.YourClass** {
    *;
 }

Weitere Informationen finden Sie unter http://proguard.sourceforge.net/manual/examples.html



1

Sie können die Verschleierung in allen Anforderungsartenklassen überspringen

open class Request
data class Example(val name: String) : Request()

proguard-rules.pro

-keepclassmembers class * extends <your-package-name>.util.ws.Request { *; }

GL


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.