I am testing the obfuscation capabilities of Proguard for the first time. To that end I did the following
- Downloaded the Cordova Hello World plugin
- Modified it by adding the string
" This is top secret"
to the greeting message it issues - Created a simple Cordova Hello World project
cordova create ...
- Added the Cordova Proguard plugin
- Added the plugin from local sources to this project
- Modified the
platforms\android\project.properties
file by appendingproguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-custom.txt
- Built the apk
cordova build --release
I have left the proguard-custom.txt
file mostly untouched. Its contents are shown below
-keepclassmembers class * {@android.webkit.JavascriptInterface <methods>;}
#AddedThis
-adaptresourcefilenames **.json,**.gif,**.jpg
-adaptresourcefilecontents **.json,META-INF/MANIFEST.MF
-keep class com.android.vending.licensing.ILicensingService
-keepattributes *Annotation*
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keepattributes InnerClasses
-keep class **.R
-keep class **.R$* {<fields>;}
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable
-keep class org.apache.cordova.** { *; }
-keep public class * extends org.apache.cordova.CordovaPlugin
-keep class org.apache.cordova.CordovaBridge
{org.apache.cordova.PluginManager pluginManager; }
-keep class org.apache.cordova.CordovaInterfaceImpl
{org.apache.cordova.PluginManager pluginManager; }
-keep class org.apache.cordova.CordovaResourceApi
{org.apache.cordova.PluginManager pluginManager; }
-keep class org.apache.cordova.CordovaWebViewImpl
{org.apache.cordova.PluginManager pluginManager; }
-keep class org.apache.cordova.ResumeCallback
{org.apache.cordova.PluginManager pluginManager; }
-keep class org.apache.cordova.engine.SystemWebViewEngine
{org.apache.cordova.PluginManager pluginManager; }
-keep class com.google.gson.internal.UnsafeAllocator { ** theUnsafe; }
-dontnote org.apache.harmony.xnet.provider.jsse.NativeCrypto
-dontnote sun.misc.Unsafe
-keep class com.worklight.androidgap.push.** { *; }
-keep class com.worklight.wlclient.push.** { *; }
-keep class com.google.** { *; }
-dontwarn com.google.common.**
-dontwarn com.google.ads.**
-optimizations
!class/merging/vertical*,!class/merging/horizontal*,
!code/simplification/arithmetic,!field/*,!code/allocation/variable
-keep class net.sqlcipher.** { *; }
-dontwarn net.sqlcipher.**
-keep class org.codehaus.** { *; }
-keepattributes *Annotation*,EnclosingMethod
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-assumenosideeffects class android.util.Log {
public static *** d(...);
}
-dontwarn com.worklight.common.internal.WLTrusteerInternal*
-dontwarn com.worklight.jsonstore.**
-dontwarn org.codehaus.jackson.map.ext.*
-dontwarn com.worklight.androidgap.push.GCMIntentService
-dontwarn com.worklight.androidgap.plugin.WLInitializationPlugin
-dontwarn android.support.v4.**
-dontwarn android.net.SSLCertificateSocketFactory
-dontwarn android.net.http.*
Proguard goes through all the motions as expected. For instance, I see
Obfuscating...
Printing mapping to
[buildpath\outputs\mapping\release\mapping.txt]...
Preverifying...
Writing output...
Preparing output jar
[buildpath\intermediates\transforms\proguard\release\0.jar]
Copying resources from program jar
[buildpath\intermediates\transforms\desugar\release\0.jar]
(filtered)
Copying resources from program directory
[buildpath\intermediates\transforms\desugar\release\1]
(filtered)
Copying resources from program jar
[buildpath\intermediates\transforms\mergeJavaRes\release\0.jar]
(filtered)
and the APK is generated as expected. I ran this APK through this Java decompiler and downloaded the output. Browsing to Hello.java
in that download I find the complete original source code
package com.example.plugin;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONArray;
public class Hello extends CordovaPlugin
{
public boolean execute(String str,JSONArray jSONArray,
CallbackContext callbackContext)
{
if (!str.equals("greet")) return false;
callbackContext.success("Hello, " + jSONArray.getString(0) +
" This is a secret!");
return true;
}
}
It is as though Proguard went through all the motions but then absolutely nothing at all. I am clearly missing out on a key step here but it is not clear to me what that might be. I'd be most grateful to anyone who might be able to put me on the right track.