I'm trying to enable proguard code obfuscation on my Android project. I see lots of questions over the years, but many of the threads are quite old and it's hard to tell how relevant they are for me.
I was unable to get Eclipse to generate a default proguard configuration file so I've been trying to piece one together and it's painful (The build I get from it crashes almost immediately and appears that it's obscuring some elements of the 3rd party libs I used in the app). I can appreciate that a generated file might now be perfect, but it seems like it could at least take a crack at handling the project libs properly.
Here's the steps I've taken to try to enable proguard.
1 Make sure my Eclipse and Android SDKs where fully up to date.
2 edit project.properties, uncomment
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
3 Immediately build fails due to pro guard-project.txt not existing. (here's where I wish it would generate one)
4 I created my own pro guard.config file at proguard-project.txt (contents shown below)
-injars bin/classes
-outjars bin/classes-processed.jar
-libraryjars libs/FlurryAgent.jar:libs/GoogleAdMobAdsSdk-4.1.1.jar
-libraryjars libs/commons-codec-1.4.jar
-libraryjars libs/commons-io-2.1.jar
-libraryjars libs/commons-logging-1.1.1.jar
-libraryjars libs/httpclient-4.1.2.jar
-libraryjars libs/httpclient-cache-4.1.2.jar
-libraryjars libs/httpcore-4.1.3.jar
-libraryjars libs/httpmime-4.1.2.jar
-libraryjars libs/mapquest-android-sdk-1.0.3.jar
-libraryjars libs/oranjestad-notifications-1.0.jar
-dontwarn org.apache.**
-dontwarn org.ietf.*
-keepnames org.apache.**
-dontpreverify
-repackageclasses ''
-allowaccessmodification
-optimizations !code/simplification/arithmetic
-keepattributes Annotation
-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 (android.content.Context);
public (android.content.Context, android.util.AttributeSet);
public (android.content.Context, android.util.AttributeSet, int);
public void set*(...); }
-keepclasseswithmembers class * {
public (android.content.Context, android.util.AttributeSet); }
-keepclasseswithmembers class * {
public (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 ; }
5 At this point my project builds, but fails due to some class cast exceptions around logging. This takes me back to step 3, where I wish a reasonable proguard-project.txt had been generated based of the eclipse library dependencies. Clearly the on I've created isn't right.
After having updated the SDK, you must also make sure to update the project itself:
android update project --path MyAndroidProjectDirectory
In recent Android SDKs, this should create proguard-project.txt.
Unless you got something wrong with your setup in general, creating new Android project, writes down proguard config file as well. So just set up dummy project and check its folder - it should be there. Copy it back to your current project and adjust if needed.
Related
i am working on xamarin application. When i enable "ProGuard" in android properties, while building the application, I'm getting the following error:
"java.exe" exited with code1.
proguard cfg file has the following:
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
Developing Environment:
Visual Studio 2015
Xamarin 4.0.4.4
I had the same issue when enabling ProGuard. By following the advice on this link, I fixed the issue by updating my proguard manually. The steps are fairly easy to follow and they fixed the problem. Hope this helps you.
Download the ProGuard zip file available from: https://sourceforge.net/projects/proguard/files/. At time of writing the latest version of ProGuard was 5.3.
ProGuard does not have a setup program, so you will need to unzip the file and copy the proguard folder structure into the location identified in the steps below.
Launch the SDK Manager and note the path in the top left under the menu options. In my case this was C:\Users\Sahar\AppData\Local\Android\android-sdk. The proguard folder is located in the tools folder of this path (in my case this was C:\Users\Sahar\AppData\Local\Android\android-sdk\tools\proguard).
Close any development environments that might be accessing the SDK and rename the proguard folder to proguard.old.
Copy the proguard folder of the new version into the tools folder and rename it to proguard if necessary (in my case the copied folder was renamed from proguard5.3).
Finally copy the configuration files from the proguard.old folder to the new folder. In my case these were:-
proguard-android.txt, proguard-android-optimize.txt and proguard-project.txt.
Clean and rebuild your project with ProGuard enabled.
I had a problem where Proguard was removing the Google Play Services libraries from my app.
I had to add the following lines of text to the proguard-android.txt file found in this folder:
/(Path to your Android SDK Folder)/tools/proguard
-keep public class com.google.android.gms.* { public *; }
-dontwarn com.google.android.gms.**
Complete proguard-android.txt File
-keep public class com.google.android.gms.* { public *; }
-dontwarn com.google.android.gms.**
# This is a configuration file for ProGuard.
# http://proguard.sourceforge.net/index.html#manual/usage.html
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-verbose
# Optimization is turned off by default. Dex does not like code run
# through the ProGuard optimize and preverify steps (and performs some
# of these optimizations on its own).
-dontoptimize
-dontpreverify
# Note that if you want to enable optimization, you cannot just
# include optimization flags in your own project configuration file;
# instead you will need to point to the
# "proguard-android-optimize.txt" file instead of this one from your
# project.properties file.
-keepattributes *Annotation*
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService
# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
-keepclasseswithmembernames class * {
native <methods>;
}
# keep setters in Views so that animations can still work.
# see http://proguard.sourceforge.net/manual/examples.html#beans
-keepclassmembers public class * extends android.view.View {
void set*(***);
*** get*();
}
# We want to keep methods in Activity that could be used in the XML attribute onClick
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keepclassmembers class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator CREATOR;
}
-keepclassmembers class **.R$* {
public static <fields>;
}
# The support library contains references to newer platform versions.
# Don't warn about those in case this app is linking against an older
# platform version. We know about them, and they are safe.
-dontwarn android.support.**
# Understand the #Keep support annotation.
-keep class android.support.annotation.Keep
-keep #android.support.annotation.Keep class * {*;}
-keepclasseswithmembers class * {
#android.support.annotation.Keep <methods>;
}
-keepclasseswithmembers class * {
#android.support.annotation.Keep <fields>;
}
-keepclasseswithmembers class * {
#android.support.annotation.Keep <init>(...);
}
I have seen many posts about how to obfuscate an Android application (.apk file) using ProGuard in Eclipse. Also see http://developer.android.com/guide/developing/tools/proguard.html:
"When you build your application in release mode, either by running ant release or by using the Export Wizard in Eclipse, the build system automatically checks to see if the proguard.config property is set. If it is, ProGuard automatically processes the application's bytecode before packaging everything into an .apk file."
But in case of exporting an Android project in a .jar file using Eclipse Export Wizard, following the described steps (of creating a file proguard.cfg, configuring proguard.config property to proguard.cfg in the file default.properties, using Export Wizard etc.) does not seem to work - I see no obfuscation of class names, etc. in the resulting jar file. I also have the following settings in my proguard.cfg file, but I don't see any output files in my project directory or in the proguard directory (that directory is not even created).
-dump class_files.txt
-printseeds seeds.txt
-printusage unused.txt
-printmapping mapping.txt
I have even created a file project.properties in my project directory with the following line but that did not seem to entice ProGuard into action:
proguard.config=proguard.cfg
There are no activities defined in this project. I am using Android 2.3.1 and Eclipse Galileo 3.5.2 on Windows. Same results with Android 3.0. Seems like the obfuscation step has to be somehow interjected explicitly in the Eclipse Export Wizard. I will appreciate any help or insight. Thanks.
as suggested in the comments to one of the answers above (but which i didn't notice at first because it was buried amongst one of the "additional comments") …
we simply run progruard on the command line (see the first block below) on the library outside of eclipse with the parameters in the second block below in our our proguard.cfg file (and definitely do not use -dontpreverify, or projects that use your project as an android library won't be able to properly be obfuscated due to StackMapTable problems from your project.jar).
command line:
$ java -jar $ANDROID_SDK/tools/proguard/lib/proguard.jar \
-libraryjars $ANDROID_SDK/platforms/android-18/android.jar #proguard.cfg
-outjars /tmp/project.jar -verbose
proguard.cfg:
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontwarn our.company.project.R*
-injars bin/project.jar
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-keep class org.apache.3rdparty.stuff.**
-keep public class our.company.project.ProjectAPI
-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.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keepclassmembers public class our.company.project.ProjectAPI {
public static <fields>;
}
-keepclasseswithmembernames class * {
native <methods>;
}
-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.app.Activity {
public void *(android.view.View);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
it's possible not all of the parameters and -keep items are strictly necessary (other than not using -dontpreverify as previously mentioned), but most of these make sense to me as items that need to be there if you have an Activity class extension in the library you are exporting.
I use an indirect way to generate a exported android obfuscate jar, my way is:
export a signed apk use eclipse
unzip the apk, find the classes.dex
use dex2jar.bat ,change the classes.dex to a jar
unzip the jar and delete the class you do not need,then zip it and
change the file name to XXX.jar
Then you use this jar in other project,or give it to customer, it
is obfuscate!
I am sure this will help you! Enjoy it!
java -jar proguard.jar #yourconfig.pro
yourconfig.pro (extended from http://proguard.sourceforge.net/index.html#manual/examples.html):
-injars yourjar.jar
-outjars yourjar_out.jar
-libraryjars 'C:\android\sdk\platforms\android-10\android.jar'
-printmapping mapping.txt
-verbose
-dontoptimize
-dontpreverify
-dontshrink
-dontskipnonpubliclibraryclassmembers
-dontusemixedcaseclassnames
-keepparameternames
-renamesourcefileattribute SourceFile
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,
SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
-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>;
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private 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();
}
Result can be verified with jd-gui
The way to invoke ProGuard is fairly straightforward:
Add the line proguard.config=proguard.cfg to project.properties
Export the application package
A default proguard.cfg file should have been automatically created by the new project wizard.
Do not obfuscated your pure Java Jar. Skip that phase completely while producing the Jar (whether manually in Eclipse or via Ant build from command line).
Instead, setup and perform proper obfuscation in the client project, the one using the Jar, where you add the library as external Jar. Proguard will be able to obfuscate code within the Jar too.
I stumbled upon this issue, and ended up successfully as I described here.
My project is working perfectly on android device and emulator.
But, If i export and taken the .apk file after enabled with proguard application getting struck, I cant install this .apk file with proguard.
My assumption, Service is not called while installing the .apk file and i did't get any error on my log.
Please kindly share your ideas.
Here is my proguard file.
-optimizationpasses 5
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-dontpreverify
-verbose
-dontoptimize
# -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-libraryjars /usr/local/android-sdk/add-ons/google_apis-7_r01/libs/maps.jar
-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.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-keepattributes JavascriptInterface
-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.app.Activity {
public void *(android.view.View);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
-keep class mypackage.MyCallbackClass {
void myCallbackMethod(java.lang.String);
}
-dontwarn android.support.**
-dontwarn org.w3c.dom.bootstrap.DOMImplementationRegistry
and my ** project.properties file**
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
proguard.config=${sdk.dir}\\tools\\proguard\\proguard-android.txt:proguard-project.txt
#proguard.config=proguard.cfg
# Project target.
target=Google Inc.:Google APIs:11
android.library.reference.1=../Library1
android.library.reference.2=../Library2
Please kindly share your ideas.
Thank You.
I suppose you are signing this version with a release key.
If you have an older installation on your phone(with a debug key),please uninstall it first.(You can't have the same app with two different signatures on your device)
FAILED BINDER TRANSACTION usually occurs when you have overflowed the Binder process. If you are not using large bitmaps on your splash page (which is the most common reason for a failed binder transaction) then it might be a ParcelFormatException, since I notice you're trying to use a Parcelable in your apk.
Assuming you're keeping ADT up to date..
If you're building the release version of your application using Eclipse export, it will load Proguard settings from the file specified by the proguard.config property in project.properties.
If you are using ant release, it will load the Proguard settings from the file specified by the proguard.config property in ant.properties.
That being said, are you getting any kind of errors or warnings during your build? These are especially helpful when diagnosing Proguard since it's purpose is to remove classes and methods that it doesn't think are being used by your application.
I uninstall my apps using:
adb shell pm uninstall -k com.*example*.*app*
And reinstall using:
adb install App-release.apk
If it gives an error about compatability, I discard the previous application data by excluding the -k switch from the uninstall command:
adb shell pm uninstall com.*example*.*app*
I have seen many posts about how to obfuscate an Android application (.apk file) using ProGuard in Eclipse. Also see http://developer.android.com/guide/developing/tools/proguard.html:
"When you build your application in release mode, either by running ant release or by using the Export Wizard in Eclipse, the build system automatically checks to see if the proguard.config property is set. If it is, ProGuard automatically processes the application's bytecode before packaging everything into an .apk file."
But in case of exporting an Android project in a .jar file using Eclipse Export Wizard, following the described steps (of creating a file proguard.cfg, configuring proguard.config property to proguard.cfg in the file default.properties, using Export Wizard etc.) does not seem to work - I see no obfuscation of class names, etc. in the resulting jar file. I also have the following settings in my proguard.cfg file, but I don't see any output files in my project directory or in the proguard directory (that directory is not even created).
-dump class_files.txt
-printseeds seeds.txt
-printusage unused.txt
-printmapping mapping.txt
I have even created a file project.properties in my project directory with the following line but that did not seem to entice ProGuard into action:
proguard.config=proguard.cfg
There are no activities defined in this project. I am using Android 2.3.1 and Eclipse Galileo 3.5.2 on Windows. Same results with Android 3.0. Seems like the obfuscation step has to be somehow interjected explicitly in the Eclipse Export Wizard. I will appreciate any help or insight. Thanks.
as suggested in the comments to one of the answers above (but which i didn't notice at first because it was buried amongst one of the "additional comments") …
we simply run progruard on the command line (see the first block below) on the library outside of eclipse with the parameters in the second block below in our our proguard.cfg file (and definitely do not use -dontpreverify, or projects that use your project as an android library won't be able to properly be obfuscated due to StackMapTable problems from your project.jar).
command line:
$ java -jar $ANDROID_SDK/tools/proguard/lib/proguard.jar \
-libraryjars $ANDROID_SDK/platforms/android-18/android.jar #proguard.cfg
-outjars /tmp/project.jar -verbose
proguard.cfg:
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontwarn our.company.project.R*
-injars bin/project.jar
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-keep class org.apache.3rdparty.stuff.**
-keep public class our.company.project.ProjectAPI
-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.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keepclassmembers public class our.company.project.ProjectAPI {
public static <fields>;
}
-keepclasseswithmembernames class * {
native <methods>;
}
-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.app.Activity {
public void *(android.view.View);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
it's possible not all of the parameters and -keep items are strictly necessary (other than not using -dontpreverify as previously mentioned), but most of these make sense to me as items that need to be there if you have an Activity class extension in the library you are exporting.
I use an indirect way to generate a exported android obfuscate jar, my way is:
export a signed apk use eclipse
unzip the apk, find the classes.dex
use dex2jar.bat ,change the classes.dex to a jar
unzip the jar and delete the class you do not need,then zip it and
change the file name to XXX.jar
Then you use this jar in other project,or give it to customer, it
is obfuscate!
I am sure this will help you! Enjoy it!
java -jar proguard.jar #yourconfig.pro
yourconfig.pro (extended from http://proguard.sourceforge.net/index.html#manual/examples.html):
-injars yourjar.jar
-outjars yourjar_out.jar
-libraryjars 'C:\android\sdk\platforms\android-10\android.jar'
-printmapping mapping.txt
-verbose
-dontoptimize
-dontpreverify
-dontshrink
-dontskipnonpubliclibraryclassmembers
-dontusemixedcaseclassnames
-keepparameternames
-renamesourcefileattribute SourceFile
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,
SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
-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>;
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private 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();
}
Result can be verified with jd-gui
The way to invoke ProGuard is fairly straightforward:
Add the line proguard.config=proguard.cfg to project.properties
Export the application package
A default proguard.cfg file should have been automatically created by the new project wizard.
Do not obfuscated your pure Java Jar. Skip that phase completely while producing the Jar (whether manually in Eclipse or via Ant build from command line).
Instead, setup and perform proper obfuscation in the client project, the one using the Jar, where you add the library as external Jar. Proguard will be able to obfuscate code within the Jar too.
I stumbled upon this issue, and ended up successfully as I described here.
I've been trying to see ProGuard in action with my test Android app. Do I need to register as an Android developer and have a key to do that? I know app needs to be built in release mode. I read these instructions several times on Android site among other things, it talks about what ProGuard does but not how to achieve it obfuscation in Android properly. Found another blog that shows how to do it with Ant, but not with Eclipse.
No, you do not need to register as an Android developper to try the Proguard obfuscation. You just need to have Proguard installed and properly configured for your app.
Since a few month, the Android SDK comes with a distribution of Proguard directly integrated. Open your <android-home>\tools directory and check whether you find a directory called proguard in it. If it is not the case, the best is to upgrade your SDK.
Using Proguard is very simple with the integrated version of the Android SDK: you just have to declare what follows in the file default.properties of your project:
# ProGuard
proguard.config=proguard.cfg
Then, you have to write your proguard.cfg if it does not already exist. The Android SDK writes this file for you for any new project you create since it integrates Proguard, but if your project was created with a former version of the SDK this file won't exist. The following file is suitable for most Android projects:
-printmapping proguard.map
-renamesourcefileattribute ProGuard
-keepattributes SourceFile,LineNumberTable
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-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 com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
When you compile in debug mode, there is no obfuscation. To obfuscate your code, you have to:
1- Ensure that your manifest file sets the debug mode to false:
<application android:icon="#drawable/icon"
android:label="#string/app_name"
android:debuggable="false">
2- Export your APK using the "File/Export" menu of Eclipse (provided you are using Eclipse, but who doesn't? :-) ). There will be no obfuscation by just using the "Run" function as this is actually debugging.
Once done the obfuscation, you will find a proguard directory in your project's root directory. It will contain files that will allow you to inspect the obfuscated code, see what was obfuscated and what wasn't, etc. The Proguard's documentation will help you on that, that's pretty simple.