Once you have build your Android application with DexGuard, you should verify
that it still works and that it is suitably protected.
Functionality
First of all, you should make sure the application functions properly. If the
obfuscated application doesn't work, you may have to add some custom
configuration to dexguard-project.txt. The most common issues on
the Android platform:
ClassNotFoundException: the application tries to access a class by
means of reflection, but DexGuard has removed or obfuscated it. You should
explicitly preserve the class. For example:
-keep class mypackage.MyClass
NoSuchMethodException: the application tries to access a method by
means of reflection (for a WebView, for instance), but DexGuard has
removed or obfuscated it. You should explicitly preserve the method. For
example:
-keepclassmembers class mypackage.MyClass {
void myMethod(java.lang.String);
}
You can look at the generated files bin/proguard/seeds.txt and
bin/proguard/usage.txt to check which classes and class members
DexGuard has explicitly kept (due to the configuration), or removed (because
they appeared unused).
Please consult the
extensive troubleshooting section if you
encounter other issues.
Static Protection: Obfuscation and Encryption
To check whether your application has been obfuscated properly, you can apply
the same tools that a hacker typically uses:
dexdump (Android SDK): disassembles Dalvik bytecode to a readable
text format.
aapt (Android SDK): disassembles binary resource XML files to a
readable text format.
baksmali (open source): disassembles Dalvik bytecode to a readable
source format.
smali (open source): assembles this source format to Dalvik bytecode
again.
apktool (open source): disassembles and assembles entire
applications: bytecode, Android manifest files, resource files, and
assets.
dex2jar (open source): converts Dalvik byte code to Java
bytecode.
jad (free): decompiles Java bytecode to Java source
code.
Disassemble your processed bytecode
Although all Dalvik bytecode can be disassembled by definition, DexGuard makes
it much more difficult to interpret. Even if you don't understand the bytecode,
you can quickly check if your processed code contains sensitive strings, class
names, field names, or method names, by inspecting the output of
dexdump:
dexdump -d -f -t dexdump.tmp MyApp-release.apk
On Linux, you can pipe its output through less
or grep to quickly find strings.
View your processed Android manifest file and resource XML files
The Android build process converts resource XML files to more compact binary
versions, but you can still view them in a text form with aapt:
Although the output format is readable, you may prefer the original XML format
that apktool can deliver, as discussed next.
Disassemble your processed application
You can inspect the entire processed application, including the Android
manifest file and the resource XML files in their original XML format, with
apktool:
apktool d MyApp-release.apk
Decompile your processed bytecode
As a final step, you can check how well the code can be decompiled, with the
combination of dex2jar and jad:
dex2jar MyApp-release.apk
jar -xf MyApp-release-dex2jar.jar
jad mypackage/MyClass.class .....
At the very least, non-public identifiers should have obfuscated names that
cause all kinds of problems. Non-trivial optimized code is typically hard to
decompile and difficult to read. The decompiler also gets thoroughly confused
by encryption code.
Dynamic Protection: Tamper Detection
Tamper detection is illustrated in the sample in
samples/TamperDetection. It is essentially a call to a method of
the DexGuard utility library to check whether the generated apk archive has
been modified in any way. Your application can then act accordingly.
To verify that the detection really works, you can tamper with the generated
apk archive yourself. The slightest modification will set off the
detector, so you can use tools like jar, zip,
jarsigner, or even zipalign. For instance: