I'm using the android "Groundy" library containing the GroundTask class, which makes use of annotations. Further I created a class
public class DownloadTask extends GroundyTask
and a callback object:
private final Object mCallback = new Object() {
#OnProgress(DownloadTask.class)
public void onNiceProgress(#Param(Groundy.PROGRESS) int progress) {
mProgressDialog.setProgress(progress);
}
....
But after obfusecation using proguard the method annotated with "OnProgress" never gets called (but no errors occure)
In the proguard file I added
-keep class com.telly.groundy.*** {
public protected private *;
}
-keepattributes *Annotation*, EnclosingMethod
-keepattributes *OnSuccess*
-keepattributes *OnProgress*
-keepattributes *OnCancel*
-keepattributes *OnCallback*
-keepattributes *OnFailure*
-keepattributes *OnStart*
-keepattributes *Param*
-keepattributes *Traverse*
-keep class com.my.namespace.DownloadTask {
public protected private *;
}
Any idea what "keep" configurations could be missing here ?
I just added a basic proguard configuration to the readme. It looks like this:
-keepattributes *Annotation*
-keepclassmembers,allowobfuscation class * {
#com.telly.groundy.annotations.* *;
<init>();
}
-keepnames class com.telly.groundy.generated.*
-keep class com.telly.groundy.generated.*
-keep class com.telly.groundy.ResultProxy
-keepnames class * extends com.telly.groundy.ResultProxy
-keep class * extends com.telly.groundy.GroundyTask
ProGuard doesn't know that the code accesses the annotation through reflection, so you probably need to preserve it explicitly:
-keep #interface com.telly.groundy.annotations.OnProgress
Related
I have a library on Kotlin I want to obfuscate almost completely but leave the public classes, properties and methods untouched. Here is an example of one of the public classes I intend to obfuscate:
class SomeClass(val propertyToShow: SomePublicClass, private val propertyToHide: SomeOtherPublicClass) {
fun methodToShow(someArg: SomeArg) {
// Some code
}
private fun methodToHide(someOtherArg: SomeOtherArg) {
// Some more code
}
}
The ProGuard file is based on a typical library ProGuard file and looks like this:
-keepattributes SourceFile,LineNumberTable
-renamesourcefileattribute SourceFile
-dontwarn javax.annotation.**
-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase
-dontwarn org.codehaus.mojo.animal_sniffer.*
-dontwarn okhttp3.internal.platform.ConscryptPlatform
-keepattributes Signature
-keepattributes *Annotation*
-dontwarn sun.misc.**
-keep class com.google.gson.stream.** { *; }
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
-keepclassmembers,allowobfuscation class * {
#com.google.gson.annotations.SerializedName <fields>;
}
-keep public class * {
public protected *;
}
-keepclassmembernames class * {
java.lang.Class class$(java.lang.String);
java.lang.Class class$(java.lang.String, boolean);
}
-keepclasseswithmembernames class * {
native <methods>;
}
-keeppackagenames **
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod,Synthetic,PermittedSubclasses
-keepparameternames
-renamesourcefileattribute SourceFile
-keepclassmembers class **$WhenMappings {
<fields>;
}
-keep class kotlin.Metadata { *; }
-keep class kotlin.** { *; }
-keep class kotlin.Metadata { *; }
-keep class kotlin.reflect.** { *; }
-dontwarn kotlin.reflect.**
-dontwarn kotlin.**
-keepclassmembers class **$WhenMappings {
<fields>;
}
-keepclassmembers class kotlin.Metadata {
public <methods>;
}
-assumenosideeffects class kotlin.jvm.internal.Intrinsics {
static void checkParameterIsNotNull(java.lang.Object, java.lang.String);
}
-keepclassmembers,allowobfuscation class * {
#javax.inject.* *;
#dagger.* *;
<init>();
}
-keep class javax.inject.** { *; }
-keep class **$$ModuleAdapter
-keep class **$$InjectAdapter
-keep class **$$StaticInjection
-keep class dagger.** { *; }
-keepclassmembers class * extends java.lang.Enum {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-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();
}
Running ./gradlew assembleRelease results in .aar file. The SomeClass.class from it looks like this (if we take a look at it via Android Studio)
public final class SomeClass public constructor(propertyToShow: SomePublicClass, propertyToHide: SomeOtherPublicClass) {
public final val propertyToShow: SomePublicClass /* compiled code */
private final val propertyToHide: SomeOtherPublicClass /* compiled code */
public final fun methodToShow(someArg: SomeArg): kotlin.Unit { /* compiled code */ }
private final fun a(someOtherArg: SomeOtherArg): kotlin.Unit { /* compiled code */ }
}
As we can see, the name of the private method has been obfuscated but its argument is not as well as the private property. It doesn’t matter if we obfuscate it with ProGuard or R8, the result is the same.
Is it possible to obfuscate private properties and private methods' arguments for Kotlin source code? Or is it pointless, since it will not interfere with others doing reverse engineering?
So the answer to this question was more or less explained in this article. Basically the issue was that the code was indeed obfuscated properly but there was still Kotlin Metadata and Android Studio was reconstructing the code based on this Metadata.
I need to keep all model classes to be unobfuscated, so I added this line in proguard rules to keep all model classes:
-keep class my_package_name.model.** { *; }
All model classes are getting kept by this command but still, it is obfuscating the annotations inside the Model classes. I tried adding the following line:
-keepattributes *Annotation*
-keepattributes EnclosingMethod
But still, results are same. My model classes contain these two annotations:
#SerializedName("message")
#Expose
private String message;
How can I keep the two annotations unobfuscated?
Try this:
-keepattributes *Annotation*
-keepattributes Signature
-dontnote sun.misc.**
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
Actually, there is a proguard config in official repo on github https://github.com/google/gson/blob/master/examples/android-proguard-example/proguard.cfg
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.
Trying adding
-keepattributes Signature
-keepattributes EnclosingMethod
-keepattributes InnerClasses
-keepattributes Annotation
For using GSON #Expose annotation
-keepattributes *Annotation*
For Gson specific classes
-keep class sun.misc.Unsafe { *; }
Prevent proguard from stripping interface information from TypeAdapterFactory,JsonSerializer, JsonDeserializer instances (so they can be used in #JsonAdapter)
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
-keep #package.annotationclassname public class *
The rule
-keep class com.google.gson.annotations.*
will keep all annotations in the package com.google.gson.annotations including the SerializedName and Expose ones that you have used.
Add to your proguard : It's preventing specific classes to be obfuscated.
Mandatory : -dontshrink. : https://www.guardsquare.com/en/proguard/manual/usage
Not mandatory : try to use -dontoptimize.
I don't really understand the issue, are you referring to a field or inner class ?
If you have an inner class inside a class, you need to specify its inner fields.
For example, if this is the class :
public class Parent {
protected Child child;
protected class Child {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
}
In the proguard, you need to specify Child class :
-keep class com.package.name.Parent$Child {*; }
You may Need To Create an annotation called DontObfuscate in your project
for more check this
Managing obfuscation with annotations
I have the following class
class CodeRequest(#JsonProperty("phone") val phoneNumber: String)
When I send request (using retrofit) with an object of this class as body (while minification is not enabled) everything works and request will be send in this form {"phone": "123"}
But enabling minification with the following proguard-rules.pro will result in a {"phoneNumber": "123"} request body.
# Jackson
-keep class com.fasterxml.jackson.databind.ObjectMapper {
public <methods>;
protected <methods>;
}
-keep class com.fasterxml.jackson.databind.ObjectWriter {
public ** writeValueAsString(**);
}
-keep #com.fasterxml.jackson.annotation.* class * { *; }
-keep #com.fasterxml.jackson.annotation.** class * { *; }
-keep class com.fasterxml.** { *; }
-keepattributes *Annotation*,EnclosingMethod,Signature,Exceptions,InnerClasses
-keep class * {
#com.fasterxml.jackson.annotation.* *;
}
-keep class * { #com.fasterxml.jackson.annotation.JsonProperty *;}
# Application classes that will be serialized/deserialized over Jackson
-keepclassmembers class my.application.data.models.** { *; }
-keepclassmembers class my.application.domain.network.rest.** { *; }
What's missing here?
Thank you.
Found solution a couple of minutes after posting the question.
The problem is not with proguard nor jackson, it's that Kotlin erases required data which are stored in kotlin.Metadata.
Adding the following rule to proguard fixed the issue:
-keep class kotlin.Metadata { *; }
i have developed which is working fine at weblogic on managed server and admin server.
then i obfuscate it for security requirement by using eclipse proguard tool.
please look at project.propertis file
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
target=android-19
android.library.reference.1=../../../Desktop/XYZ/CaptureActivity
android.library.reference.2=CordovaLib
and proguard-project.text file
-keep public class * extends com.phonegap.api.Plugin
-keep public class * extends org.apache.cordova.api.Plugin
-keep public class org.apache.cordova.DroidGap
-keep public class org.apache.cordova.**
-keep public class org.apache.cordova.camera
-keep public class com.plugin.datepicker.**
-keep public class com.credentek.imagetransfer.**
-keep public class mobi.roshka.cordova.callphone.**
-keep public class org.apache.cordova.dialogs.**
-keep public class de.appplant.cordova.plugin.emailcomposer.**
-keep public class fr.louisbl.cordova.gpslocation.**
-keep public class org.apache.cordova.camera.**
-keep public class com.phonegap.plugins.barcodescanner.**
-keep public class org.apache.cordova.networkinformation.**
-dontwarn android.webkit.*
-dontwarn org.apache.**
-keep public class * extends org.apache.cordova.api.CordovaPlugin
-keep class org.apache.cordova.**
{
*;
}
-keepclassmembers class *
{
#android.webkit.JavascriptInterface <methods>;
}
-keep public class org.apache.commons.** { *; }
after obfuscating application stop working. not even connecting to server.
actually ajax call is not working.
if anybody have some idea please share. thanks...
It would be helpful if you could post any exceptions raised when running your program.
Whenever dealing with Proguard issues, one strategy is to disable optimization and keep everything. Something like this:
-keep class com.** { *; }
-keep class org.** { *; }
-keep class mobi.** { *; }
-keep class fr.** { *; }
-keep class de.** { *; }
-keepattributes '*'
-dontshrink
-dontoptimize
Make the configuration as pessimistic as possible until the configuration allows the app to work. After that, start removing packages from -keep. Also, remove -dontoptimize and -keepattributes, one at a time.
I am trying to enable ProGuard when compiling my Android application.
Below is the ProGuard configuration.
The problem I have is that I get a lot of warnings about duplicate definition (pretty much for all classes, in my app or the basic java classes) and what's worse is that when I make changes in my code, those do not get reflected when I run on the device.
I am compiling (and developing) using IntelliJ IDEA 11.1.5 (and just enable ProGuard in the project structure, I did not set it to use the system proguard configuration).
I saw that other question, but it does not help at all, I don't think my problem is limited to 3rd party libraries, I imagine it's more about setting the right input/output... ?
-injars bin/classes
-outjars bin/classes-processed.jar
-libraryjars /home/matthieu/android/platforms/android-17/android.jar
-dontpreverify
-repackageclasses ''
-allowaccessmodification
-optimizations !code/simplification/arithmetic
-keepattributes *Annotation*,SourceFile,LineNumberTable,*Annotation*
-renamesourcefileattribute SourceFile
-dontwarn java.awt.**,javax.security.**,java.beans.**,com.sun.**
-keep public class my.package.MainMenuActivity
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-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*(...);
}
-keep public class * extends android.view.ViewGroup
-keep public class * extends android.support.v4.app.Fragment
-keep class android.support.v4.app.** { *; }
-keep interface android.support.v4.app.** { *; }
-keep class com.actionbarsherlock.** { *; }
-keep interface com.actionbarsherlock.** { *; }
-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.os.Parcelable {
static android.os.Parcelable$Creator CREATOR;
}
-keepclassmembers class **.R$* {
public static <fields>;
}
#ACRA specifics
# keep this class so that logging will show 'ACRA' and not a obfuscated name like 'a'.
# Note: if you are removing log messages elsewhere in this file then this isn't necessary
-keep class org.acra.ACRA {
*;
}
# keep this around for some enums that ACRA needs
-keep class org.acra.ReportingInteractionMode {
*;
}
-keepnames class org.acra.sender.HttpSender$** {
*;
}
-keepnames class org.acra.ReportField {
*;
}
# keep this otherwise it is removed by ProGuard
-keep public class org.acra.ErrorReporter
{
public void addCustomData(java.lang.String,java.lang.String);
public void putCustomData(java.lang.String,java.lang.String);
public void removeCustomData(java.lang.String);
}
# keep this otherwise it is removed by ProGuard
-keep public class org.acra.ErrorReporter
{
public void handleSilentException(java.lang.Throwable);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
Assuming you are building with Ant inside IntelliJ IDEA, you mustn't add -injars, -outjars, or -libraryjars options; the Ant script already does that for you. This explains the warnings about duplicates.
Note that it's better to remove the generic part of the configuration in your proguard-project.txt and rely on the configuration of the Android SDK. The latter is partly generated by aapt (tuned for your project) and partly maintained inside the SDK.