Unpack android boot image

Modifying an Android boot image

After my old nook reader died, I bought a Tolino Vision 4 HD ebook reader. It is usable without registration — as opposed to Kobo readers which you have to register. It is water proof enough to drop it into the bath tub, and it has thesauri and translation dictionaries. For 140€ I bought it at buecher.de. ​

The reader is based on Android 4.4.2, and it is rootable. Unfortunately the root patch is for firmware version 1.9.0, while I updated already to 12.2.0. ​

For the firmware update, I let it once into my wifi. During that time it also downloaded the latest recommendations from the buecher.de store, which it now shows on the home screen — taking the lower half of it — and after I finish reading a book: ​

I wanted to get rid of this unsolicited advertisements, and asked support how to do so. They replied with «cannot be disabled» :/ ​

I thought I could simply clear that cached recommendation data on my own but found that I could not simply plug the micro USB cable and run adb shell — the Tolino does not have adbd running :/ ​

Activating adb without developer settings GUI​

In a standard Android user interface I would open settings, tap seven times on the build number, and then activate ADB debugging in the now visible developer options. ​

The Tolino has its own GUI, and their settings UI has no ADB checkbox. ​

There is an alternative: Setting some properties in the boot image’s default.prop file, which is what the ADB checkbox in the normal developer options does. ​

The standard USB config for the Tolino was «mass_storage», so I only added «,adb» to it. ​

Now I needed to modify my Tolino’s default.prop file. ​

Building my own boot image​

I did not create a boot image from scratch, I only modified an existing one. ​

The Tolino Vision 4 update website had a .zip file for updating from 11.2.0 to 12.2.0, so I fetched and extracted that. Among others, it contained a 4.5 MiB boot.img file. ​

Unpacking boot.img​

At first I tried sophiehuiberts/Bootimg-scripts but found out that the extracted kernel file does not have the correct size. ​

The Android core git repository up to commit a6abd821d contained two files in the mkbootimg directory: unpack_bootimg.py and mkbootimg.py, which I used in the end. ​

When extracting the boot image, the unpack script shows important meta data: ​

Before actually modifying something, I rebuilt it until my repacked image was bit for bit equal to the original one. ​

With the help of the meta data above, I ended up with the following parameters for repacking: ​

Flashing the boot image​

I flashed my rebuilt boot image onto the Tolino to see if it works at all. ​

The Tolino must be in fastboot mode for flashing, and I got to there that way: ​

  1. Connect it via USB to your computer.​
  2. Power off by holding the power button until the shutdown options appear and shut it down. ​
  3. The power button has its own white LED. Wait until it is off (

5 seconds after the screen is off), because only then it is really powered off. ​
Hold the light button and then also press the power button. Wait

3-4 seconds until the LEDs on the power button and the home button are on. ​

  • Release the buttons. ​
  • The reader is in fastboot mode now and shows an empty screen only. The mode can be verified by listing the fastboot devices: ​

    Flashing is easy now: ​

    If the Tolino starts up normally, then the rebuilt boot image works. ​

    The Tolino Shine 2 HD needs the command fastboot flash:raw boot ...

    Unpacking ramdisk​

    The rebuilt boot image uses the original kernel and boot image files. default.prop is inside the ramdisk, so I had to extract it: ​

    This gave me a directory full of files: ​

    I went the safe route and did not modify anything at this stage. I only re-packed the directory back to a ramdisk file: ​

    Then I re-built the boot.img as shown above with the new ramdisk file, flashed it onto the reader and booted it up. All fine. ​

    Enabling adb​

    Now that I knew that the whole boot image building process worked, I actually modified default.prop in the ramdisk folder and added the two lines: ​

    After building, flashing and booting my adb-enabled boot image I was finally able to use adb: ​

    .. or not. I first had to add a new udev rule: ​

    Then I unplugged and replugged the USB cable, and it finally worked: ​

    How I got root access is a different story. ​

    Источник

    Unpacking and repacking recovery or boot image

    The CWM recovery image is in the changer_files directory in Uberizer’s main program directory. I wanted to see if it was possible to unpack it, have a look inside and/or change anything, then repack it and reflash it to the device. I got started on this because I was trying to figure out how to decipher the /dev/graphics/fb0 framebuffer when booted into CWM, and I wanted to replace CWM’s stock background image by red, green, blue colours to help figure out how the framebuffer is represented.

    This procedure also applies to the boot image (located in /dev/block/nandc).

    There are various pages on the web on how to do this. However, some instructions didn’t work for me (resulted in a non-bootable recovery image). I’ll go through each step on this page and explain what did work. Uberizer version is v1.3 26th Dec 2012. The CWM version is 6.0.1.2.

    Important note: The image file produced by the unpacking + repacking process may be smaller than the original image. However, this should not be a problem, provided the contents are the same. For example, I unpacked and repacked the boot image — the original image was 33554432 bytes long and the re-packed image was only 10315776 bytes long. This is because there are actually only 10315776 bytes of relevant data present — the remaining bytes in the original image were just filled with 0xFF. So, if you do get a different file size, check the files in a hex editor — the data should still be the same.

    Structure of image file

    According to the likes of http://forum.xda-developers.com/showthread.php?t=443994, the image consists of a 2k header, followed by a gzipped kernel, followed by a ramdisk, followed by a second stage loader (?). Representation nicked from that site:

    I don’t know about the kernel so don’t ask.

    The steps required are these:

    1. Split image file into kernel and ramdisk parts
    2. Decompress ramdisk into real files
    3. (Optional) make any alterations to the files
    4. Compress the files back into a ramdisk
    5. Combine the new ramdisk with the original kernel and make a bootable image
    6. Flash to device and test

    Steps in detail below. All require a Linux box — I’m using Ubuntu 12.04.

    References

    Here are several links which are referred to on this page.

    1. Split image file into kernel and ramdisk parts

    We start with the recovery image file (recovery.img) from Uberizer’s changer_files directory. On the Linux machine, make a folder on the desktop (I called mine «recovery«) and copy recovery.img into it.

    Now get hold of some tools. First, download Linux image tools to this folder. This contains a set of tools for extracting and building images. It is described on this page. Extract it. Next, download unmkbootimg.gz. It’s described on this page. Extract it as well. Delete the original .gz archives, we don’t need them. Your folder should now look like:

    We can now use either split_bootimg.pl (in the tools folder) or unmkbootimg to split up the image into the kernel and ramdisk. Both produce exactly the same results (with different filenames), but unmkbootimg is slightly more useful because it works out the base address to use when reassembling the image, and shows exactly what command to use. We’ll use it.

    Open up a terminal and navigate to the directory on the desktop:

    (or whatever you called yours). Next run unmkbootimg:

    (You may have to go into the permissions for unmkbootimg (right click, properties, permissions) and tick «Allow executing file as program»). The «./» is required since we’re in the same directory as unmkbootimg. The output from umkbootimg is piped into the file output.txt, so you can copy the command used to reassemble the image later. Here’s the output from the unmkbootimg command:

    The directory will now look like this:

    The kernel is zImage and the ramdisk is initramfs.cpio.gz. Have a look at the files sizes:

    See how the file sizes match those specified in the output of unmkbootimg.

    2. Decompress ramdisk into real files

    The ramdisk format is a bit odd. The files have first been concatenated into an archive using cpio (this means the files are all strung together into one single big file, but not compressed), then compressed using gzip. So, to undo all this, we need to first gunzip the ramdisk and then use cpio to extract the files from the archive. This is mentioned, for example, here.

    So, make a new directory called ramdisk. cd into it. Then use a combination of gunzip and cpio to extract the initramfs.cpio.gz file. Here’s the commands:

    The -c switch on gunzip makes it send its output to the standard output (i.e. the terminal). This is then piped (the | symbol) to cpio. The -i switch with cpio makes it work in copy-in mode — it copies files in from an archive, and outputs them as real files. Now have a look at the contents of the ramdisk directory:

    This is where all the interesting stuff is.

    3. (Optional) make any alterations to the files

    I was originally interested in replacing the background image with one of my own. The images used in CWM are located in res/images — see below.

    The background image is called stitch.png and is a 350×735 pixel, 72dpi, 24-bit PNG image. I simply overwrite this with an image of my own, of the same dimensions and format:

    4. Compress the files back into a ramdisk

    This is where confusion arose. According to the Miniand website, I should use the mkbootfs tool inside the tools directory, along with gzip, to turn the files inside the ramdisk directory back into a proper ramdisk image. The command would be (executed from within the recovery directory):

    However, when carried through to completion, this does not result in a bootable image. I don’t know what mkbootfs does, but it seems irrelevant — why not just reverse the action of gunzip and cpio to get back to a ramdisk file? In fact, this is exactly what’s described here. While still in the ramdisk directory, run the following:

    This consists of three parts. find . spits out (to the terminal) a list of all filenames in the current (ramdisk) directory, including files in sub-directories. This is piped to cpio. It uses the switches -o for copy-out mode, so it combines files from find . into an archive, and -H newc to specify the output format. This is then piped to gzip which compresses the output from cpio into a final, new ramdisk file, called newramdisk.cpio.gz. Here’s the resulting files in the recovery directory now:

    (If you’re interested, compare the file sizes of the ramdisk files produced by mkbootfs and the other command — they are different, which probably explains why the final image doesn’t boot. On mine, mkbootfs produced a file 2035130 bytes in size, while the find . | cpio -o -H newc | gzip > ../newramdisk.cpio.gz command produced 2033625 bytes.)

    5. Combine new ramdisk with original kernel to form bootable image

    If you’re still awake, we now need to recombine the kernel and ramdisk back into a bootable image (exactly the reverse of splitting them up in step 1). To do this, we use the mkbootimg tool in the tools directory. Remember the output from unmkbootimg in step 1? It specified the format of the mkbootimg command to use. First cd back up to the recovery directory, then execute the command as below.

    The output from this is a file new_recovery.img which is the new bootable recovery image (you hope!).

    6. Flash to device and test

    This is flashed in the same way as the recovery image is normally (see elsewhere). Copy the new_recovery.img into the Uberizer program directory on your Windows machine (or wherever ADB is run from). Boot up the tablet into Android and connect it via USB. Open a DOS command prompt and run the following:

    This first pushes new_recovery.img to the internal sdcard of the tablet (/sdcard/), then uses cat to write the entire contents of the image file to /dev/block/nandg, which is the recovery partition on the tablet.

    To check it works, shut down the tablet manually. Wait 20s or so to make sure it’s shut down. Boot into recovery mode by pressing & holding Vol +, and then pressing & holding Power until the screen lights up. Hopefully this will now boot into CWM recovery with a modified background image, like this:

    Источник

    imjtool (formerly known as imgtool)

    The imjtool utility is another one of the tools I’m including in my book, this time to accompany the chapter about the Boot process. I deal a lot with the internal format of images there, and realized I needed a quick extractor. This became more important when I started to deal with the L preview, and Google Glass system images I used for research. Over time, as I’ve encountered more and more proprietary image formats, I’ve had to extend the tool to support them all. I’ve also had to change the name (from imgtool to imjtool , as of March 2020) since it turns out the former it taken up by MAME..

    By any name, you can get the tool
    👉right here 👈

    Just unpack the tar. There are macOS (Intel), Linux x86_64 and Android ARM64 images (remember they might need chmod +x to run, and prefix with ./). As usual, you might want to check out the RSS feed, or follow my company’s Twitter for more updates.

    Why should I care?

    Well, most users wouldn’t. But if you need a quick tool to unpack Android images, this is useful. Think of it as the inverse of mkbootimg (from the AOSP), coupled with simg2img (the sparse image extractor). Another bonus feature it provides is unpacking the Linux bzimage kernels.

    Another reason — If you’re downloading a rooting tool — and you want to avoid getting malware. I just downloaded An NVIDIA Shield root image, for example — which is really nothing more than a bootimg. So it was trivial to run this tool to extract it — specifically, get to the ramdisk, then cpio -ivd and make sure I can have a peek at it before installing.

    What if it doesn’t work on _________ (some image or file)?

    So how do I use it?

    To obtain an Android system image, you can either get it from a zip (e.g. Google’s update, Amazon’s update.bin, etc), or by dd ‘ing for a device, then copying it over. Note that some devices (e.g. the HTC One M8) may need a bit of processing, in this case stripping the 256 header HBoot uses:

    If you’re using the Google images, it’s easier:

    You can also use it to extract the filesystem image (basically, do what simg2img does:

    Lastly, you can use it for imgdata extraction as well (as the file format there is derived from that of the boot image:

    ChangeLog

    Version 0.2 Changes

    • Supports offset= (for HTC and other boot.imgs where ANDROID! is wrapped)
    • Supports cmdline= (to override kernel command line)

    Version 0.3-0.4 Changes

    • Supports making images (similar functionality to mkbootimg) with the «make» argument

    Version 0.5 Changes

    Version 0.6 Changes

    Version 0.7 Changes

    Version 0.8 Changes

    Version 0.85 Changes

    Version 1.0 Changes

    I generally recurse when I can detect layering, but — you might need to run this tool more than once since many images have multiple layers of encapsulation:

    Version 1.2 Changes

    • Supports super.img images (liblp logical partitions)
    • Supports DTBO
    • Supports Samsung TOC
    • Supports Brotli compressed (. new.br) block based images. For now, work with me and supply the number of blocks by getting them from the . transfer.list (second line):

    Shameless plug for the book, and RFC

    Still working on Volume II of Android Internals. Haven’t forgotten y’all. And there’s full coverage of all these esoteric formats, etc. in the update to Volume I that I am preparing.

    If you want to learn all about Android Internals — please check out the Android Internals & Reverse Engineering Training course my company, Technologeeks, offers.

    The next training opens in DC, June 1 st , 2020 (Barring any COVID-19 imposed delays..) Come join me!

    Volume II — covering the deep internals of the frameworks and the runtime — will be out LATER IN 2020 (one good thing to come out of social distancing, I guess..). In the interim, I encourage you to try out the tool (as well as the even more powerful Dextra, and the simple but useful bindump) and, of course — JTrace. Shoot me an email (to j@) if you’ve any questions. Or comments. Or in general. All are welcome.

    Источник

    Читайте также:  Как удаленно отключить android
    Оцените статью