Unpacking and repacking U-Boot images part 2
Scripts for working with uImage files
I’ve created a set of python scripts for working with U-Boot image files when phone-hacking. The first script is similar to the U-Boot mkimage tool, only it adds the ability to extract data from existing images.
The next two scripts are particularly for WebOS and meta doctor. These scripts are similar to diff and patch, but they are intended to distribute change instructions for ramdisk image files. More than just a binary patch, these utilities introduce what I call a copy-patch. A copy-patch contains instructions for merging one binary file into another without actually containing the contents of either file. This allows the patch to be distributed without violating the IP rights of the owners of the binary files.
Downloads
Usage examples
Words often don’t explain as well as examples, so I’ll show an example of updating the TP and A6 firmware in a WebOS 2.1.2 image. Note that the patch file does not contain the firmware, so I will have to supply the patch tool with the location of the files I intend to graft into the root file system ramdisk image.
uImage.py usage and listing image information:
# python uImage.py -h Usage: uImage.py -l image uImage.py -c [options] image uImage.py -x image uImage.py -h Options: -h, --help show this help message and exit -l list image contents -c create new image -x extract image contents Creation Options: -c -A arch -O os -T type -C comp -a addr -e ep -n name -d data_file[:data_file...] image -A ARCHITECTURE set architecture to 'arch' -O OSTYPE set operating system to 'os' -T IMAGETYPE set image type to 'type' -C COMPRESSION set compression to 'comp' -a LOADADDR iset load address to 'addr' -e ENTRYADDR iset entry point to 'ep' -n IMAGENAME set image name to 'name' -d FILESPEC image data from 'datafile' # # python uImage.py -l nova-installer-image-broadway.uImage Image name: nova-installer-image-broadway-43 Created: Wed Dec 31 16:00:00 1969 Image type: ARM Linux Multi-File (uncompressed) Data size: 12566392 Bytes Load Address: 0x000000 Entry Point: 0x000000 Header CRC: 0xcf936b92 ... OK Data CRC: 0x2defc1cd Contents: Image 0: 2610004 bytes Image 1: 9956376 bytes Multi-File Image 0: Header -------------------------- Image name: Linux-2.6.29-palm-shank Created: Wed Dec 31 16:00:00 1969 Image type: ARM Linux Kernel (uncompressed) Data size: 2609940 Bytes Load Address: 0x208000 Entry Point: 0x208000 Header CRC: 0xfd901980 ... OK Data CRC: 0xffbe63e6 Multi-File Image 1: Header -------------------------- Image name: ramdisk Created: Wed Dec 31 16:00:00 1969 Image type: ARM Linux RAMDisk (uncompressed) Data size: 9956312 Bytes Load Address: 0x000000 Entry Point: 0x000000 Header CRC: 0xccd15a95 ... OK Data CRC: 0xa6d2f9e9
Extracting images:
# python uImage.py -x nova-installer-image-broadway.uImage Linux-2.6.29-palm-shank.uImage Linux-2.6.29-palm-shank ramdisk.uImage ramdisk
Notice that there were 4 files extracted. Let me explain: The main uImage file is a multi-file type that contains two files: A kernel uImage and a ramdisk uImage. Each of these two files is also a uImage, so uImage.py extracted their contents as well. We are left with 4 files: the ones with .uImage extensions have uImage headers. The other two are the raw data contents.
Now let’s verify that the ramdisk file is a gzipped EXT2 image and then apply the copy-patch:
# file ramdisk ramdisk: gzip compressed data, was "nova-installer-image-broadway-4", from Unix, last modified: Fri Apr 15 12:01:11 2011, max compression # zcat ramdisk > nova-installer-image-broadway-4 # file nova-installer-image-broadway-4 nova-installer-image-broadway-4: Linux rev 0.0 ext2 filesystem data # python ramdiskpatch.py nova-installer-image-broadway-4 2.2.4/usr/lib/ipkg/info/a6-firmware.control 2.2.4/usr/lib/ipkg/info/a6-firmware.md5sums 2.2.4/usr/lib/ipkg/info/pma6updater.control 2.2.4/usr/lib/ipkg/info/pma6updater.md5sums 2.2.4/usr/lib/ipkg/info/pmtpupdater.control 2.2.4/usr/lib/ipkg/info/pmtpupdater.md5sums 2.2.4/usr/lib/ipkg/info/pmtpupdater.list 2.2.4/lib/firmware/a6_firmware.txt 2.2.4/lib/firmware/cy8ctma300e.fw 2.2.4/lib/firmware/cy8ctma300e.ver 2.2.4/usr/bin/PmTpUpdater 2.2.4/usr/bin/PmTpWhich 2.2.4/usr/bin/PmA6Updater 2.2.4/usr/bin/catnip < ramdisk.copyPatch Patching-in "2.2.4/usr/lib/ipkg/info/a6-firmware.control" .Done. Patching-in "2.2.4/usr/lib/ipkg/info/a6-firmware.md5sums" .Done. Patching-in "2.2.4/usr/lib/ipkg/info/pma6updater.control" .Done. Patching-in "2.2.4/usr/lib/ipkg/info/pma6updater.md5sums" .Done. Patching-in "2.2.4/usr/lib/ipkg/info/pmtpupdater.control" .Done. Patching-in "2.2.4/usr/lib/ipkg/info/pmtpupdater.md5sums" .Done. Patching-in "2.2.4/usr/lib/ipkg/info/pmtpupdater.list" .Done. Patching-in "2.2.4/lib/firmware/a6_firmware.txt" ..............................................Done. Patching-in "2.2.4/lib/firmware/cy8ctma300e.fw" ....................................................Done. Patching-in "2.2.4/lib/firmware/cy8ctma300e.ver" .Done. Patching-in "2.2.4/usr/bin/PmTpUpdater" ......Done. Patching-in "2.2.4/usr/bin/PmA6Updater" .............Done. Patching-in "2.2.4/usr/bin/PmTpWhich" .Done. Patching-in "2.2.4/usr/bin/catnip" .........................................................................................Done. Performing binary patches to file system structure .............................................................................................................................................................................................................................................................................................................................................................................................................................................................. Patch successful! md5: 1cdb4f76aeacc0ba1760cc6496137e61
Now we’ll re-compress the ramdisk, and make it into a uImage:
# gzip nova-installer-image-broadway-4 # python uImage.py -c -A arm -T ramdisk -C none -n ramdisk -d nova-installer-image-broadway-4.gz ramdisk.uImage Image name: ramdisk Created: Sun Jun 24 04:01:21 2012 Image type: ARM Linux RAMDisk (uncompressed) Data size: 10051920 Bytes Load Address: 0x000000 Entry Point: 0x000000 Header CRC: 0x1cf594e7 ... OK Data CRC: 0xcf80cb73
Now we re-combine the extracted kernel uImage and the ramdisk uImage:
# python uImage.py -c -A arm -T multi -C none -n Linux-2.6.29-palm-shank -d Linux-2.6.29-palm-shank.uImage:ramdisk.uImage my-install-image.uImage Image name: Linux-2.6.29-palm-shank Created: Sun Jun 24 04:04:59 2012 Image type: ARM Linux Multi-File (uncompressed) Data size: 12662000 Bytes Load Address: 0x000000 Entry Point: 0x000000 Header CRC: 0x71281fb4 ... OK Data CRC: 0x9f1b4262 Contents: Image 0: 2610004 bytes Image 1: 10051984 bytes Multi-File Image 0: Header -------------------------- Image name: Linux-2.6.29-palm-shank Created: Wed Dec 31 16:00:00 1969 Image type: ARM Linux Kernel (uncompressed) Data size: 2609940 Bytes Load Address: 0x208000 Entry Point: 0x208000 Header CRC: 0xfd901980 ... OK Data CRC: 0xffbe63e6 Multi-File Image 1: Header -------------------------- Image name: ramdisk Created: Sun Jun 24 04:01:21 2012 Image type: ARM Linux RAMDisk (uncompressed) Data size: 10051920 Bytes Load Address: 0x000000 Entry Point: 0x000000 Header CRC: 0x1cf594e7 ... OK Data CRC: 0xcf80cb73
And that’s it!
[…] Short update with the finished uImage.py script that can extract and build uImage files: Unpacking and repacking U-Boot images part 2 […]
How to extract U-Boot image that LZMA compressed, and digitally signed?