Android ProGuard always gives ParseException - android

I'm trying to obfuscate my code using ProGuard, but I still get error even using default proguard-rules.txt:
I really could not find anything about this. Since I'm new to ProGuard, can you help me solving this issue?
My gradle.build file is the following:
buildTypes {
release {
debuggable false
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
debug {
debuggable true
minifyEnabled false
shrinkResources false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
And the proguard-rules.txt:
# 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 always use *.pro for proguard files. Try to change *.txt to *.pro.
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

Looking at the logs pointed me to the right direction.
The problem was a silent error in XML layout, in fact I had a button with android:onClick="" attribute and the argument was empty.
I think ProGuard generated a method with empty method name and this caused the problem.

Related

Proguard is not obfuscating classes in project correctly

I am trying to using Proguard to obfuscate classes in my project. After building project, I decompile the Apk and check whether the classes are obfuscated successfully. However, I find out that almost all the classes are not renamed except some library classes. Here is the screenshot:
Screenshot
The following is a part of my build.gradle file:
android {
signingConfigs {
sign {
storeFile file(KEYSTORE_FILE)
storePassword KEYSTORE_PASSWORD
keyAlias KEYSTORE_ALIAS
keyPassword KEYSTORE_ALIAS_PASSWORD
}
}
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "com.findata.gcool"
minSdkVersion 19
targetSdkVersion 23
versionCode 20
versionName "1.1.7"
multiDexEnabled true
}
buildTypes {
debug {
applicationIdSuffix ".debug"
}
release {
signingConfig signingConfigs.sign
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
shrinkResources true
zipAlignEnabled true
}
}
}
And proguard-rules.pro:
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/doris_yang/Library/Android/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
-keep class com.findata.gcool.bean.** { *; }
-keep class com.findata.gcool.bean.json.** { *; }
-keep class com.findata.gcool.http.** { *; }
-keep class com.findata.gcool.widget.custom_view.** { *; }
# Retain generic type information for use by reflection by converters and adapters.
-keepattributes Signature
# Retain declared checked exceptions for use by a Proxy instance.
-keepattributes Exceptions
# For using GSON #Expose annotation
-keepattributes *Annotation*
##---------- Gson from official ----------
# Gson specific classes
-keep class sun.misc.Unsafe { *; }
#---------- Retrofit 2.X from official ----------
## https://square.github.io/retrofit/ ##
# Platform calls Class.forName on types which do not exist on Android to determine platform.
-dontnote retrofit2.Platform
# Platform used when running on RoboVM on iOS. Will not be used at runtime.
-dontnote retrofit2.Platform$IOS$MainThreadExecutor
# Platform used when running on Java 8 VMs. Will not be used at runtime.
-dontwarn retrofit2.Platform$Java8
#---------- EventBus------------------
-keepclassmembers class ** {
#org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
# Only required if you use AsyncExecutor
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
<init>(java.lang.Throwable);
}
#-----------Crahslytics-----------
-keepattributes SourceFile,LineNumberTable
#---------- Other ----------
-dontwarn okio.**
-dontwarn com.squareup.okhttp.**
-dontwarn com.roughike.bottombar.**
Even if I remove all the rules except -dontwarn rules(can't build without them), the result is still the same. It seems that Proguard is working but not working correctly on my project files. I have no idea why it happens :(
Thanks for reviewing my problem!

Android: Proguard configuration to obfuscate class names and methods

As I know there are some classes which should not be obfuscated and also their names must persisted like 'Activities'. However I want other classes and packages inside my code be renamed.
here is build.gradle inside app folder:
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "apt.eve.good.morning"
minSdkVersion 14
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
compile 'com.android.support:support-v4:23.4.0'
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:design:23.4.0'
}
I use this proguard configuration for my application (app\proguard-rules.pro):
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-useuniqueclassmembernames
-verbose
-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*();
}
-allowobfuscations class *
# 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>(...);
}
It do optimization but as I checked inside my classses.dex all class names remained unchanged. So I want to know what I missed in my configuration file which is not obfuscating class/method names?
P.S.1 I have searched several questions but I can't imagine what's wrong here.
P.S.2 I have properly configured my android studio and changes on proguard configuration applies without no problem on my released .apk file.
Make sure you check the obfuscated .dex files.
With common gradle build script the build/** folders may contain several unobfuscated versions of .dex/.class files.
Ultimately the resulting .apk/.aar should be obfuscated, so if you are unzipping that one, and the the classes are not obfuscated, then something doesn't work as expected.
As OP noted, it's also important to verify your [disassembly] tools work correctly.
Viewing binary form of .dex from .apk is usually enough to spot [un]obfuscated symbols (try with unobfuscated .class, the symbols are easily readable even in text editor, in obfuscated .dex the chain of symbols like "aa", "ab", ... is often well visible too).
Also running gradle proguard task manually with verbose option on may help to identify if the proguard was run and upon what files.
Based on your gradle file (minifyEnabled=true) and proguard config. You appear to be in good shape already.
To quickly confirm that your app obfuscating your classes, check the resulting mapping.txt file when you make release builds. This file "provides a translation between the original and obfuscated class, method, and field names."
Here is an example of a mapping.txt that obsfucates a hockeyapp library :
net.hockeyapp.android.tasks.AttachmentDownloader -> net.hockeyapp.android.d.a:
java.util.Queue queue -> a
boolean downloadRunning -> b
67:67:net.hockeyapp.android.tasks.AttachmentDownloader getInstance() -> a
Lots more info can be found in the "Shrink Your Code and Resources" article here : https://developer.android.com/studio/build/shrink-code.html
Do you already changed
minifyEnabled=true
Inside app -> build.gradle?
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}

Proguard not minifying when debuggable set to true

I am trying to test my app which has passed the 64K limit.
I have set minify on but it doesn't work when debuggable is enabled. However, if I build a version with debuggable off then it shrinks it by 2/3!
Am I missing something? This is the relevant part of my Gradle file:
buildTypes {
release {
minifyEnabled true
debuggable false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
minifyEnabled true
debuggable true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
proguard-rules.pro:
-keep class .R
-keep class **.R$* {
<fields>;
}
-keepattributes *Annotation*
-keepclassmembers class ** {
#org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
<init>(java.lang.Throwable);
}
-dontwarn com.google.**
-dontwarn com.squareup.picasso.**
-dontnote com.google.**
-dontnote com.squareup.picasso.**
With proguard enabled your code gets obfuscated and debugging will not be possible. That is why when you want to debug and set the flag true, proguard does not activate and that is why you do not see the minification of your apk.
Check this post. It has a similar question and will help you understand the conditions better.

How to obfuscate UiAutomator code?

I have a test project developed in UiAutomator, which is not specific for one app, i.e., I don't even have any application associated to my test. My main folder only has the AndroidManifest, my code is all in the test folder.
I want to make my code available but ofuscated. So I want to obtain an APK of my code obfuscated.
My build.gradle contains
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
testProguardFiles('proguard-rules.pro')
}
debug{
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
testProguardFiles('proguard-rules.pro')
debuggable true
}
}
and proguard-rules.pro file is:
-keep public class * extends android.test.InstrumentationTestCase
-keep public class * extends junit.framework.TestCase
-keep public class * implements junit.framework.TestCase
-keep class android.support.** { *;}
-keep interface android.support.** { *;}
-keep public class junit.framework.** { *;}
-keep class android.uiautomator.** { *;}
-keep class com.impactToolTester.utility.Constants
-keepclasseswithmembernames class *{
public <init>(java.lang.Class,android.support.test.internal.util.AndroidRunnerParams);
}
-dontnote android.support.test.internal.runner.listener.CoverageListener
-dontwarn android.test.**
-dontnote org.junit.**
-dontnote junit.runner.*
-dontnote junit.framework.*
-dontnote android.net.**
-dontnote org.apache.http.**
When I run gradlew assembleAndroidTest the app-debug-androidTest-unaligned.apk is created in build/outputs/apk.
However, when I decompile the apk I realise it's not obfuscated at all. I know the proguard file is read because I started with several errors when I first run it.
I have the minifyEnabled in both debug and release because I'm not sure which is run with assembleAndroidTest.
I'm a real newbie when it comes to proguard and obfuscation in general so any help would be much appreciated.

Android Build with Gradle and ProGuard : "The output jar must be specified after an input jar, or it will be empty"

I'm creating a build with different flavors with Gradle. It used to run quite good until now, until I wanted to enable Proguard. I enabled minifyEnabled for my Release Build and now I'm having an exception saying :
"Caused by: org.gradle.internal.UncheckedException: java.io.IOException: The output jar [.../app/build/intermediates/multi-dex/dev/release/componentClasses.jar] must be specified after an input jar, or it will be empty."
Does anybody know what is causing this exception ? I basically want to enable ProGuard before I release my application. Here is my Gradle file below.
lintOptions {
abortOnError false
}
dexOptions{
incremental true
javaMaxHeapSize "4g"
}
defaultConfig {
applicationId "..."
minSdkVersion 14
targetSdkVersion 22
versionCode 1
versionName "1.0"
multiDexEnabled true
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
debug {
minifyEnabled false
shrinkResources false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.debug
}
}
ProGuard Rules file.
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/osayilgan/Development/Android/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
-keepnames public class * extends io.realm.RealmObject
-keep class io.realm.** { *; }
-dontwarn javax.**
-dontwarn io.realm.**
And Here is the proguard-android file. This is the default one from Android SDK.
# 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);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$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.**
It took quite a while for me to figure it out but, as I had guessed, it was all about Proguard configuration.
I started to dig through the Warnings in the Console and realized that some of the References couldn't be found by Proguard. So adding them as -dontwarn to proguard configuration file solved the problem.
In my case, I had to ignore packages below;
-dontwarn java.lang.invoke**
-dontwarn org.apache.lang.**
-dontwarn org.apache.commons.**
-dontwarn com.nhaarman.**
-dontwarn se.emilsjolander.**

Categories

Resources