1

I'm using Proguard to obfuscate my code. So, I activate it in project.propertise file.

After that I decompiled the APK file by apktool.

There are three items in decompiled file, res, smali and AndroidManifest. In res folder I can see my images clearly :) In smali, It's not easy to understand but I still can find my code. it is something like this:

.method public static u()Ljava/lang/String; .locals 1 const/4 v0, 0x1 packed-switch v0, :pswitch_data_0 const-string v0, "https://uat.somewhere.com/ebroking/wecos/mobiletrader/aboutus.html" :goto_0 return-object v0 :pswitch_0 const-string v0, "https://www2.somewhere.com/ebroking/wecos/mobiletrader/aboutus.html" goto :goto_0 :pswitch_data_0 .packed-switch 0x1 :pswitch_0 .end packed-switch 

If I go to package name (activities), there are several files like a.smali, aa.smali, ab.smali, ac.smali and etc. Also, in this folder I can see all of my activities. For example, in my app I have an activity called MSAboutUs. in smali folder its name is MSAboutUs.smali. When i open it i can see following codes:

 .class public Lcom/pbb/mystock/activities/MSAboutUs; .super Lcom/pbb/mystock/activities/ay; # instance fields .field private j:Landroid/widget/Button; .field private k:Landroid/webkit/WebView; # direct methods .method public constructor <init>()V .locals 0 invoke-direct {p0}, Lcom/pbb/mystock/activities/ay;-><init>()V return-void .end method # virtual methods .method public onCreate(Landroid/os/Bundle;)V .locals 3 invoke-super {p0, p1}, Lcom/pbb/mystock/activities/ay;->onCreate(Landroid/os/Bundle;)V const v0, 0x7f030004 invoke-virtual {p0, v0}, Lcom/pbb/mystock/activities/MSAboutUs;->setContentView(I)V const-string v0, "" const-string v1, "Loading..." const/4 v2, 0x1 invoke-static {p0, v0, v1, v2}, Landroid/app/ProgressDialog;->show(Landroid/content/Context;Ljava/lang/CharSequence;Ljava/lang/CharSequence;Z)Landroid/app/ProgressDialog; move-result-object v0 iput-object v0, p0, Lcom/pbb/mystock/activities/MSAboutUs;->a:Landroid/app/ProgressDialog; const v0, 0x7f060008 invoke-virtual {p0, v0}, Lcom/pbb/mystock/activities/MSAboutUs;->findViewById(I)Landroid/view/View; move-result-object v0 check-cast v0, Landroid/webkit/WebView; iput-object v0, p0, Lcom/pbb/mystock/activities/MSAboutUs;->k:Landroid/webkit/WebView; iget-object v0, p0, Lcom/pbb/mystock/activities/MSAboutUs;->k:Landroid/webkit/WebView; new-instance v1, Lcom/pbb/mystock/activities/a; invoke-direct {v1, p0}, Lcom/pbb/mystock/activities/a;-><init>(Lcom/pbb/mystock/activities/MSAboutUs;)V invoke-virtual {v0, v1}, Landroid/webkit/WebView;->setWebViewClient(Landroid/webkit/WebViewClient;)V iget-object v0, p0, Lcom/pbb/mystock/activities/MSAboutUs;->k:Landroid/webkit/WebView; invoke-static {}, Lcom/pbb/mystock/a/b;->u()Ljava/lang/String; move-result-object v1 invoke-virtual {v0, v1}, Landroid/webkit/WebView;->loadUrl(Ljava/lang/String;)V const v0, 0x7f060007 invoke-virtual {p0, v0}, Lcom/pbb/mystock/activities/MSAboutUs;->findViewById(I)Landroid/view/View; move-result-object v0 check-cast v0, Landroid/widget/Button; iput-object v0, p0, Lcom/pbb/mystock/activities/MSAboutUs;->j:Landroid/widget/Button; iget-object v0, p0, Lcom/pbb/mystock/activities/MSAboutUs;->j:Landroid/widget/Button; new-instance v1, Lcom/pbb/mystock/activities/b; invoke-direct {v1, p0}, Lcom/pbb/mystock/activities/b;-><init>(Lcom/pbb/mystock/activities/MSAboutUs;)V invoke-virtual {v0, v1}, Landroid/widget/Button;->setOnClickListener(Landroid/view/View$OnClickListener;)V const v0, 0x7f060009 invoke-virtual {p0, v0}, Lcom/pbb/mystock/activities/MSAboutUs;->findViewById(I)Landroid/view/View; move-result-object v0 check-cast v0, Landroid/widget/Button; const v1, 0x7f06000a invoke-virtual {p0, v1}, Lcom/pbb/mystock/activities/MSAboutUs;->findViewById(I)Landroid/view/View; move-result-object v1 check-cast v1, Landroid/widget/HorizontalScrollView; invoke-virtual {p0, v0, v1}, Lcom/pbb/mystock/activities/MSAboutUs;->a(Landroid/widget/Button;Landroid/widget/HorizontalScrollView;)V invoke-virtual {p0}, Lcom/pbb/mystock/activities/MSAboutUs;->d()V return-void .end method .method public onKeyDown(ILandroid/view/KeyEvent;)Z .locals 1 const/4 v0, 0x4 if-ne p1, v0, :cond_0 const/high16 v0, 0x7f04 invoke-virtual {p0, v0}, Lcom/pbb/mystock/activities/MSAboutUs;->getString(I)Ljava/lang/String; move-result-object v0 invoke-virtual {p0, v0}, Lcom/pbb/mystock/activities/MSAboutUs;->b(Ljava/lang/String;)V :cond_0 const/4 v0, 0x0 return v0 .end method 

This is same to other activities. I can see login activity EditTexts and buttons. I'm sure with spending some hours its possible to understand what is architecture and then manipulate the code.

So my question is what Progaurd is exactly doing? I thought it change name of clases, methods and variables but it seems nothing is changed.

in prject.properties of application i have added this line:

proguard.config=proguard.cfg 

and proguard.cfg includes these lines:

# 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.** # Remove all logs -assumenosideeffects class android.util.Log { public static *** v(...); public static *** d(...); public static *** i(...); public static *** w(...); public static *** e(...); } -keepattributes JavascriptInterface -keep public class com.pbb.mystock.activities.MSLogin2$MyJavaScriptInterface -keep public class * implements com.pbb.mystock.activities.MSLogin2$JavaScriptInterface -keepclassmembers class com.pbb.mystock.activities.MSLogin2$JavaScriptInterface { void processHTML(***); } 
2
  • Your title asks "...what Proguard exactly does?" and in your question you state "I'm using Proguard to obfuscate my code.". - You have basically answered your own question although I suspect you don't understand the meaning of obfuscation. To obfuscate means "to hide", or "to confuse". In other words, Proguard simply makes it less easy to directly interpret the code in an apk. It doesn't mean it will encrypt it or make it 100% secure. Commented Dec 18, 2012 at 7:19
  • Thanks Squonk, Yes you are right, but i expect when I'm hiding or obfuscating something I don't see it clearly again. That's why I asked what it does. If it's obfuscating therefore I shouldn't see my class names clearly. So, what is it doing??? may be Nikolay's answer is right. Commented Dec 18, 2012 at 7:58

1 Answer 1

4

It does the same thing as it does on other platforms, see the FAQ for details. On Andorid you have to keep the names of Activities, services and other components that are defined in the manifest, because the OS references them by name. Same goes for lifecycle methods such as onCreate(). Resources are not modified in any way. Non-component classes (POJOs) will be renamed, and so will their methods and fields. It ultimately depends on the contents of the config file you use.

As you have noticed, that doesn't perfectly hide your code, nothing does. It just makes it harder to read when decompiled. You can try DexGuard which does a bit more, but ultimately if someone is determined enough, they can revers your code (same goes for native code, etc.)

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.