6

I have been involved in disassembling Android apps using baksmali and dexpler. Whenever I disassemble an app, I find the packages and package hierarchy (that would have been available in development scenario) intact. For instance, when I disassemble a task manager app (MD5: 3377f8527479ab4e72bf9fa5eec62abe), I get the package hierarchy as shown in the figure below.enter image description here.

In this context, I have the following questions,

  1. Will this hierarchy of Java packages be preserved and retained while building apps. When we develop apps, of course, we use many packages and we put them in a hierarchy while we build the app. But, all the code written by developers will be converted into a single classes.dex file. Will the packages and package hierarchy information be retained in this classes.dex file or any other part of the apk file (like META-INF)?
  2. If this information is not available from .dex, where does this come from? How does every disassembling/ decompiling tool manages to extract this package hierarchy?
  3. Where to find documentation/ literature relevant to packages and package hierarchy in the app building process? I tried skimming thro' Android documentation in vain.

2 Answers 2

4

Yes, the package hierarchy is preserved in the dex file. To be more precise, if a class was named foo.bar.baz.foo.Myclass in the sourcecode, it's name will be foo.bar.baz.foo.Myclass in the .dex as well. Any "package hierarchy" will be derived from those class names.

If you want to know more about the .dex file format, the Dalvik Executable Format Reference should contain everything you need.

2
  • Thanks for the link and answer. In the dex documentation, I happen to see that "A FullClassName is a fully-qualified class name, including an optional package specifier followed by a required name". It seems like including the name of the package is NOT mandatory? May 12, 2014 at 14:42
  • Also, it is mentioned in that document that the fully qualified class name is proceeded by the character 'L'. Is it correct to assume that's why we see 'Landroid/support/v4/widget' in the .smali file when the actual classes referred is android/support/v4/widget ? May 12, 2014 at 14:44
3

The fast answer is that in Java, the fully qualified name of the class is the actual name of the class concatenated with its package. To the classloader, com.foo.Annamalai is the name it will load at runtime. This is also, subsequently why you can't have two classes of the same name in the same package.

This will be a (semi) contrived instance, but lets pretend your app has two different logging frameworks, and you need to support both.

import java.util.logging.Logger;
import org.apache.log4j.Logger;

If you try this, your compiler should barf, complaining that you have two classes with the same name. Well, this version will work:

org.apache.log4j.Logger logger4j = org.apache.log4j.Logger.getLogger(DeleteMe.class);
java.util.logging.Logger loggingLogger = java.util.logging.Logger.getLogger(DeleteMe.class.getName());

Because of this package/class naming convention, it is trivial to extract the file structure of the application for reverse-engineering purposes, because in java the package name is specified to correlate to a file structure.

In a comment you asked about NOT using a package, well, if you did that then you would NEVER be able to use two classes of the same name--the compiler would never allow it.

The above example would turn into this:

Logger logger4j = Logger.getLogger(DeleteMe.class.getName());
Logger loggingLogger = Logger.getLogger(DeleteMe.class.getName());

Which Logger is the compiler going to pick if you have two on the classpath without package names?

3
  • 1
    Thanks for the explanation. I get the perspective clearly now. it is trivial to extract the file structure of the application for reverse-engineering purposes, because in java the package name is specified to correlate to a file structure - The same applies when reversing Android apps (even when they contain native code)? Correct me if I am wrong. May 12, 2014 at 16:41
  • Yeah, Google still has to follow the JLS or Oracle will sue them.
    – avgvstvs
    May 12, 2014 at 17:04
  • 2
    One more thing which I didn't note, the biggest reason not to put everything in the "default" package (which means NO package name) is that it makes it possible to accidentally write a class that has the same name as another class in library code. Meaning you'd get weird Exceptions and without reversing every library, may not figure out why, so package names buy you quite a bit of utility.
    – avgvstvs
    May 13, 2014 at 12:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.