Learn to root Android using emulator


Introduction

What is rooting actually? How does it work? I tried to figure this out these days. Now, I know how to at least root an Android emulator including creating ROM image. Since I am using emulator only, the following explanation is only applied on emulator. I have not tested on real mobile phone.

Before I begin, the followings are my working environment:

OS: Arch Linux
Packages:
android-2.2 r03-2 – required for the Android platform
android-sdk r16-1 – required for emulator
android-sdk-platform-tools r10-2 – required for adb command

I was trying on Android Froyo (2.2) only.

Superuser (root)

So, to root the Android, first we need to obtain “su” binary for Android. We can get it easily from the internet. Besides that, busybox binary for Android is very useful, this can also be obtained from the internet.

Then, we need to start the emulator by providing extra partition size to /system. This can be done only through command-line, eg

emulator -avd MyAndroid -partition-size 128 -no-snapshot-load

Make sure the AVD “MyAndroid” is already created. The “-no-snapshot-load” option is used if we enabled the snapshot. As a result, we will start the emulator with extra disk space for /system. By this, we can adding extra files to /system later.

Then, we need to use “adb shell” to remount the /system so that we have write access to the /system.

adb shell mount -o rw,remount -t yaffs2 /dev/block/mtdblock0 /system

Then, we can push the su and busybox to the /system/xbin.

adb push su /system/xbin/
adb push busybox /system/xbin/

Now, to actually make the su work properly, we need to chmod it,

adb shell chmod 06755 /system/xbin/su
adb shell chmod 06755 /system/xbin/busybox

Now, we need to install Superuser.apk (which you can get together with “su”). We can install it with “adb install” command. It is required when the other apps request for “su”.

We can try our “su” with Root Checker Basic or Stericson Busybox. We should see the following image.

Android emulator with superuser
Android emulator with superuser

Now, that is rooting. You might feel happy with it. However, if we restart the emulator, without snapshot, all the “su” does not work any more. So, we are going to customise the ROM image. But before this I just want to go through about Android Market first.

Anroid Market

To make the emulator work with Android Market, we need two APKs, Google Services Framework and Market. They are available in internet. The Market package name is com.android.vending and Google Services Framework is com.google.process.gapps

After obtaining the files, then we can push them into /system/app.

adb push GoogleServicesFramework.apk /system/app/
adb push Market.apk /system/app/

Wait a while, then you can see Market app in the emulator.

Besides that, according to this page, we need to remove the /system/app/SdkSetup.apk.

adb shell rm /system/app/SdkSetup.apk

Then, the emulator can run the Android Market, we can sign in with Google Account.

Customise ROM image for emulator

Failures

Now, if we restart the emulator, everything will return to default. No more “su” and Android Market. Why? The reason is because whatever we done to the /system, it will not save to the ROM image.

The /system is actually from the system.img, installed with android-2.2 in my case. This file is mounted in emulator as yaffs2 file system format. In order to customise this ROM image, I have tried several ways.

Using unyaffs, it can only extract the image, but I cannot continue. I can simply pull the /system using adb command without it.

Using yaffs2utils, unyaffs2 produced nothing. And the image built by mkyaffs2 does not allow the emulator to boot.

Using mkyaffsimage, also not work as above.

Some resources mentioned that, we can get the mkyaffs2image utility when building the Android source. But the problem is, to get the source, it requires a lot of disk space and need a long time to download.

So, what is the best way to modify the system.img? I even tried the low level way using dd to extract the /dev/block/mtdblock0, but failed.

Solution

Finally, I tried to solve it with userdata-qemu.img. This is the /data folder that will always modified when we install apps in the emulator. Restarting the emulator does not reset /data. Therefore, we can simply create the ROM image from /data. We can done it simply clean all the /data.

adb shell busybox rm -R /data/*

This will remove everything is /data, except “lost+found” folder.

adb shell busybox ls /data

Check with ls command, make sure only “lost+found” left.

Now, since the /system contains the “su”, “busybox”, Market and Google Services Framework we have done earlier, we need to copy the whole /system to the /data.

adb shell busybox cp -a /system/* /data/
adb shell busybox ls /data

As a result, the /data is identical to the /system.

Now, we have the userdata-qemu.img file in the AVD folder, which is modified. Close the emulator. Then, we can use the userdata-qemu.img file as the system image. We can rename it to system.img, or calling it as the system with “-system” option from the emulator command-line.

Start the emulator with this customised system.img, now, we have busybox by default, and also Android Market.

Missing Market apps problem (added 2012-03-14)

But if we look into the Android Market, we will discover that, a lot of apps are not available, only a few apps are available. To show most of the apps (not all the apps), we need to customise the boot image, namely ramdisk.img. We can get this file from android-2.2 package.  It is together with default system.img.

Unlike system.img, ramdisk.img is actually a cpio gzip file. So, we can extract it with,

mkdir temp #make a folder
cd temp #change to the folder "temp"
gunzip -c ../ramdisk.img | cpio -i #extract the ramdisk.img, 
# where it is located at the parent directory of temp

This will extract all the files to the temp/ folder.

Now, edit the default.prop, modify lines as following,

ro.secure=1
ro.allow.mock.location=0

Optionally, we can also modify ro.build.fingerprint key in /system/build.prop, to bypass regional restriction. But I am not sure what are the value should be used.

After customisation, we need to re-compile the ramdisk.img. In the temp/,

find . | cpio -o -H newc | gzip > ../new-ramdisk.img

This will make a new-ramdisk.img. We can rename it as “ramdisk.img” and put it in AVD folder, so that the emulator will use it be default.

Now, if we find out the apps are still missing after customisation, then we need to stop and clear both cache and data for Google Services Framework and Market. Then restart the emulator (several times), then it can work.

Advertisements