Assembly 101 on Android Dalvik Code

Recently, I have been meddling with Android theme resources to modify the theme for my Android-based Galaxy Tab. It was yet another great learning process,  which involves manipulating the graphic resources, replacing the de-compiled XMLs that control the layouts and styling of the interface, etc. Just as I thought I had enough of them, I fumbled on a theming problem which seemed so impossible to fix. I pinpointed the offending code, created the right “answer” to the problem,  but it just didn’t work!

Almost giving up, I decided to trace the source code of the module. It turns out that the code explicitly sets the color of the text (the theming “bug”), and thus all the layout and style modification attempts would not have any effect at all.

   if (entry.label != null) {
            holder.appName.setText(entry.label);
            holder.appName.setTextColor(getResources().getColorStateList(
            entry.info.enabled ? android.R.color.primary_text_dark : android.R.color.secondary_text_dark));
   }

Instead of going back to source codes for changes, I contemplated reverse-engineering. Thankfully with the help of smali, an assembler/disassembler tool for Android apk,  I could correct the problem on the executable directly. Addictive Tips  gave a good overview of an Android application in ODEX and DEODEX format,

WHAT IS AN ODEX FILE?

In Android file system, applications come in packages with the extension .apk. These application packages, or APKs contain certain .odex files whose supposed function is to save space. These ‘odex’ files are actually collections of parts of an application that are optimized before booting. Doing so speeds up the boot process, as it preloads part of an application. On the other hand, it also makes hacking those applications difficult because a part of the coding has already been extracted to another location before execution.

THEN COMES DEODEX

Deodexing is basically repackaging of these APKs in a certain way, such that they are reassembled intoclasses.dex files. By doing that, all pieces of an application package are put together back in one place, thus eliminating the worry of a modified APK conflicting with some separate odexed parts.

In summary, Deodexed ROMs (or APKs) have all their application packages put back together in one place, allowing for easy modification such as theming. Since no pieces of code are coming from any external location, custom ROMs or APKs are always deodexed to ensure integrity.

So before I could attempt the “hack”, the application must be DEODEX’ed, so that we have the complete executable for disassembly. The executable in Android system is in .dex format, or Dalvik Executable, and is stored as classes.dex within the Android Package (.apk) along with other application resources (graphic resources, layout binaries, etc). I extracted out the classes.dex, and do a disassembly.

java -jar baksmali.jar -o out  classes.dex

This will disassemble the executable classes.dex into assembly codes in the folder named out. This step can be skipped if you have previously used APK Tool to decompile Android package to access to the XML codes. The latter however would not assemble the assembly codes when you compile using the tool, so the subsequent steps would still be required if you have made changes to the assembly code.

In my case, the offending code is ManageApplications$ApplicationsAdapter, and the section of the code matches the

    invoke-virtual {v3, v4}, Landroid/content/res/Resources;->getColorStateList(I)Landroid/content/res/ColorStateList;

    move-result-object v3

    invoke-virtual {v2, v3}, Landroid/widget/TextView;->setTextColor(Landroid/content/res/ColorStateList;)V

I simply commented off the third line in the above section of the code, which effectively eliminates the set color instruction. I proceeded to re-assemble the codes,

 java -jar smali.jar -o  classes.dex  out

The output of the assembler is a modified classes.dex, which I then re-package it to the original APK (Settings.apk).

Android UI resource framework for Galaxy Tab

This slideshow requires JavaScript.

A while back I ventured into kernel programming when I tried to meddle with the kernel for my Samsung Galaxy S.  (although in reality, it’s more of modifying the kernel)  I thought I would have stopped my venturing but I guess (geek) habit dies hard. Having spent some time recently to modify the otherwise boring UI of my Galaxy Tablet, I had thought about doing a write up, on  how Android manages its UI resources, i.e. framework-res.apk.

However, time is not at my end, as recent office workload shifts have basically stolen all my  time from my hobby. So I am just going to share what I have created (only applicable for Samsung Galaxy Tablet), and if there is anybody who want to know I do it, I can always try to capture bits by bits of what I have learnt and share whatever I know.

It took me awhile to figure out the intricacies of the framework-res, so I hope you will appreciate/like the latest work!

The mod can be downloaded from this xda thread. The remaining of this article will be updated as and when I have the time, and questions I get about the resource framework.

Steps to modify Framework-res.apk

  1. Decompile the Framework using APKTool.JAR. The command to execute a decompilation is     java -jar apktool.jar d framework-res.apk  <directory-where-decompiled-resources-reside>
  2. Modify the XML resources and/or replace the PNG resource files as you wish
  3. Compile the Framework using APKTool.JAR again. The command to  java -jar apktool.jar b <directory-where-decompiled-resources-reside>
  4. Once the resource is compiled, the newly compiled APK can be found in the dist folder of the framework-res
  5. Before replacing the framework-res.apk in your android device with the newly compiled apk, you need to make sure the newly compiled apk has the META-INF folder and that the AndroidManifest.xml is replaced with the original version. Failure to do so will result in “bootloop”!
  6. For other system apps APK (e.g. Settings.apk), the steps are similiar (i.e. step 1 to 4), except that you do the reverse in step 5.  Instead of copying META-INF folder to your newly compiled APK, copy the res folder and file resource.arsc from the newly compiled APK to the source or original APK. Make sure you copy w/o compressing the files/folder  (i.e. using store mode if you are using WinRAR)

Structure of Res folder in Framework-res.apk

Drawable – controls how the graphics should be rendered under event such as an animation

    •  progress_horizontal.xml – Modify all the color elements to reflect the progress bar
    • stat_sys_battery – Modify the elements to reflect the battery level
    • stat_sys_battery – Modify the elements to reflect the animation of the battery

Drawable-hdpi – Replace the PNGs accordingly for the desirable theme look and feel

    • btn_check_* – for all check buttons design
    • btn_* – for all other type of buttons design
    • ic_* – for all icons used in system wide UI such as menu, etc.
    • menu_* – for the theme design of the menu
    • progressbar_* – to show the indeterminate state of the progress (e.g. in Market, trying to estimate the download size)
    • spinner_* – for the animation of the wait cursor
    • stat_sys_battery* – for the animation and status of battery level
    • stat_sys_* – for icons used in status bar to show status of system services such as signal, wifi, etc
    • stat_* – for all the other icons used in the status bar
    • statusbar_background.9 – for the background theme of the status bar (it’s a .9 png, which means you need to have 1 px border around the original design)
    • status_* – for the interface of the notification window (drop down from the status bar)
    • zzzz_quickpanel_brightness* – for the design of the brightness setting in the quick panel
    • zzzz_quickpanel_icon* – for the design of the icons on the quick panel shortcuts.

Layout – Controls the layout of the UI controls used in Android system wide.

    • preference.xml – Modify the text color of the TextView control, particularly to address the theming needs of the Account Sync screen in “Account & Sync” Settings
    • zzzz_quickpanel_brightness_settings.xml – Modify the text color of the CheckBox control

Values – Configures theme setting such as Colors, Styles, etc 

    •  Styles.xml – Modify the styles to reflect the black theme
      • Theme – “inverse” the color of text
      • Theme.Icon – change the color of the divider (set to dark for dark background)
      • Widget.IconMenu – change the color of the text
      • Widget.TextView.ListSeparator – change the color of the text and background in the separator
      • Theme.ExpandedMenu – change the color of the menu in “More”
      • textColorTertiary – inverse the color

Structure of Res folder in Settings.apk

Drawable-hdpi – Replace the PNGs accordingly for the desirable theme look and feel 

    • ic_settings* – Replace the icons in the setting window according to the desire theme look and feel.
    • ic_wifi* – Replace the icons in the wifi setting window according to the desired theme look and feel

Layout – Controls the layout of the UI controls used in Android system wide.

    • preference_dialog_brightness.xml – change the color of the text in the dialog box (for brightness, contrast and color density setting dialog box)

Values – Configures theme setting such as Colors, Styles, etc

    • style.xml – Modify the whitestyle to use normal or Black theme.

Structure of Res folder in Phone.apk

Values – Configures theme setting such as Colors, Styles, etc

    • style.xml – Modify the whitestyle to use normal or Black theme.

Structure of Res folder in AccountAndSyncSettings.apk

Drawable-hdpi – Replace the PNGs accordingly for the desirable theme look and feel

    • ic_list* – Replace the icons in the setting window according to the desire theme look and feel.

Layout – Controls the layout of the UI controls used in Android system wide.

    • title.xml – change the text color of the Account type and title in “Account Sync Screen”
    • account_sync_screen.xml – change the background of the ListView control (background + colorhintcache)

Values – Configures theme setting such as Colors, Styles, etc

    • style.xml – Modify the whitestyle to use normal or Black theme.