Sunday 16 August 2015

Proguard Observations: bundling assets in assets not raw (since Android Studio)

I love Proguard. For years I stuck religiously to C and C++. After some of my work got loose in the wild I began to appreciate the commercial merits of Java. At the very least in Android.

When your C code tombstones might as well have occurred in some one else's code you are depending on it makes sense to stick with the hurd, that's Java. My mixed mode apps did not focus on making my Java private, I had relied on C and C++ for that. Android Studio abandoned C / C++ development.

Proguard can be made to work very easily in Android Studio. Me saying this and you observing are 2 completely different things so I encourage you to learn about reverse engineering with apktool. You will probably have already used Google's own reverse engineering tools day to day when you view read-only source code from a decompiled library.

Apktool produces smali that is architecturally equivalent to the original obfuscated Java. Obfuscation is Proguard's thing. Smali has the distinct advantage of being amenable to direct recompilation from apktool itself. Apktool is the most frequently updated reverse engineering tool external to Google (developed by iBotPeaches from XDA). Smali is still obscure though. I've seen so little of it in books and tutorials that I wonder just how removed from Java byte code it can actually be. Keep your sanity and relevance, without having to learn smali. Other tools, especially dex2jar and JD-GUI do the business of reverse engineering. Using these I was able to make the following observations about proguard and Android Studio.

Problem

I have an html file in res/raw:

By default res/raw links from generated 'R' files are broken by proguard. Trying the following option doesn't help this

-keep class *.R

Eric Lafortune alluded to there being reasons for Proguard's default behaviour somewhere on SO. The following is needed but it means all aliases from the massive 'R' file are readily accessible to a decompiler:

-keep class *.R
-keepclasseswithmembers class **.R$* {public static <fields>;}

Solution 1: try using res/assets instead of res/raw

myWebView.loadUrl("file:///android_asset/help.html");

This has exactly the same effect. The page doesn't load after proguard. I know I can hard link the HTML string but for now I need to document this bug so I don't return to it later.

To be thorough, I tried just

-keepclasseswithmembers class **.R$* {public static <fields>;}

and using the asset (assets) directory. This time I can see that all the R$* classes are present in the rev-eng'd project. All except the R$raw I'd just obviated. No R$assets? No nothing. I must be doing something wrong, and I was.

Ignoring CommonsWare earlier advice:

I am asking this because if you have a button with an id btnSaveArticle, for a hacker it becomes too easy to grasp what the code around is doing by looking at the name.
Using Hierarchy View, it would take them less than 30 seconds to determine the actual ID of the "Save Article" button, no matter what you name it. And I can envision even faster solutions with a bit of custom tooling.
am I wasting my time?
IMHO, yes.

answered Aug 16 '13 at 12:54
CommonsWare

On a seperate thread his wisdom shone:

Since Android Studio uses the new Gradle-based build system, you should be putting assets/ inside of the source sets (e.g., src/main/assets/), if I understand correctly.
Of course I am still wasting mine and my user's time because placing the html in assets prevents it from accessing other folders, where, for example, icons might be found.

Or they might not.


No comments:

Post a Comment