Obfuscating a Cordova Android app with Proguard appears to do nothing
Asked Answered
I

1

9

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 appending proguard.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.

Influential answered 16/12, 2018 at 5:31 Comment(1)
ProGuard doesn't encrypt strings constantsBiologist
M
1

These lines in your proguard-custom.txt file are preventing proguard from obfuscating that file:

-keep class org.apache.cordova.** { *; }
-keep public class * extends org.apache.cordova.CordovaPlugin

If you remove them you should see that the file becomes obfuscated. However that may break your app, since Cordova probably included them for a reason (I'm not very familiar with Cordova).

Maiolica answered 14/6, 2019 at 22:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.