Obfuscating resource strings that may give away too much information about programming logic

Mark picture Mark · Jun 22, 2012 · Viewed 8.3k times · Source

I currently use a combination of LVL and Proguard as a first line of defence against piracy.

However, what about the resource strings? For example, if there is a resource string like "License check failed" then doesn't the pirate simply need to trace that resource id back to where it was used in the code? In fact, this is also true if the string is something generic like "Please contact dev".

What is the best approach?

Answer

Eric Lafortune picture Eric Lafortune · Jun 24, 2012

If you define a resource string, you will probably define or use it in:

  • the string resource file res/values/strings.xml,
  • layout files res/layout/*.xml,
  • the generated resource file R.java,
  • your java code src/**.java.

After compilation, the resource string, its name, and its integer code end up in:

  • the resource file resources.arsc (string, name, and code),
  • the resource class R$string.class (name, code),
  • your compiled code **.class (inlined code).

ProGuard will remove R$string.class entirely, but Android decompilers can reconstruct all information from resources.arsc. It still takes a bit of work, but the strings may indeed hint at the purpose of the code (along with certain API calls).

You can improve on this by encrypting/obfuscating the strings in your code and by using reflection to access certain APIs, as suggested in Google's presentation Evading Pirates and Stopping Vampires.

ProGuard's closed-source sibling for Android DexGuard can encrypt strings for you (along with API calls and entire classes), probably more effectively than you could achieve manually, and without burdening the source code.

(I am the developer of ProGuard and DexGuard)