Archive for ‘Dalvik’

October 20, 2013

Dalvik

This is another really big topic 🙂 Many people out there talk about Dalvik but according to many conversations I hold, it is not very clear to them, what exactly it is. The next is the best and more simple definition I found about Dalvik:

Dalvik is Android’s Java virtual machine. It allows Android to run the byte-code generated from Java-based apps and Android’s own system components and provides both with the required hooks and environment to interface with the rest of the system, including native libraries and the rest of the native user-space. – Embedded Android

But there are some differences between Dalvik, from now on DVM, and the Java Virtual Machine, JVM.

Dalvik was design for embedded systems. Those systems would have a small amount of RAM, slow CPU and run an OS without swap space. Also they would be battery powered. As you probably know, if you want to run a Java application, the JVM is loaded with the necessary .class flies via a .jar file. In case of Dalvik there are no such .class files, instead there is a single .dex file which is 50% smaller than the original .jar file. DEX stands for Dalvik Executable. DVM is register-based machine, different from the push-pop stack-based JVM. Another important difference is that DVM includes a Just In Time (JIT) compiler for ARM. This basically means that the code is compiled at run time so that it can run natively in the CPU instead of been interpreted since that is slower. This was already typical in other virtual machines but it makes much more sense in the kind of systems for what Dalvik was design. Traditionally most of the Java code was run in the server side by very powerful machines but as technology evolves we have more code running in the client side and this kind of optimizations are more of a necessity. Another important difference between DVM and JVM is that the JVM relies on the Java Development Kit (JDK), while DVM relies on the Apache Harmony project, which is a Java implementation hosted by the Apache project. The JDK is used in AOSP only for the java compiler at build time but none of those are distributed with Android.

DEX files might look like harder to decompile than the traditional JAR files but it is not. We will check that in later posts on how to decompile Android applications. That topic is very related to this post since we will have the opportunity to go mote into Dalvik internals.

If you go to the Zygote post, you will see that Zygote was in charge of spawning the resources that applications need to run. One of the tasks is to fork an instance of a DVM so that the new application can run on it. Bellow you can see how Zygote forks a new instance of the DVM. This new process is managed by the Activity Manager as we previously saw.

/**
 * Forks a new VM instance. The current VM must have been started
 * with the -Xzygote flag. <b>NOTE: new instance keeps all
 * root capabilities. The new process is expected to call capset()</b>.
 *
 * @param uid the UNIX uid that the new process should setuid() to after
 * fork()ing and and before spawning any threads.
 * @param gid the UNIX gid that the new process should setgid() to after
 * fork()ing and and before spawning any threads.
 * @param gids null-ok; a list of UNIX gids that the new process should
 * setgroups() to after fork and before spawning any threads.
 * @param debugFlags bit flags that enable debugging features.
 * @param rlimits null-ok an array of rlimit tuples, with the second
 * dimension having a length of 3 and representing
 * (resource, rlim_cur, rlim_max). These are set via the posix
 * setrlimit(2) call.
 * @param seInfo null-ok a string specifying SEAndroid information for
 * the new process.
 * @param niceName null-ok a string specifying the process name.
 *
 * @return 0 if this is the child, pid of the child
 * if this is the parent, or -1 on error.
 */
 public static int forkAndSpecialize(int uid, int gid, int[] gids,
         int debugFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName) {
     preFork();
     int pid = nativeForkAndSpecialize(
             uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo, niceName);
     postFork();
     return pid;
 }

If you want and I recommend you to do it, you can check the nativeForkAndSpecialize routine to the native code you can find it in the Google Code here

With all this, there are associated tools supported by the platform and which you can use to play around from an system shell 🙂

  • dalvikvm: Starts a clean DVM with no Android functionality. You can load run .jar files.
  • dvz: Starts a new DVM, but this time with Android functionality. The difference with respect to the way Zygote to it is that this would be a detached process not managed by Activity Manager
  • dexdump: It helps decompiling DEX files. This will be related to future posts on how to decompile Android applications.

And now, if you want to go and check more, here is Dan Bornstein giving a brief on the topic: http://www.youtube.com/watch?v=ptjedOZEXPM