UBFI images are the firmware images that Puma5 and some Puma6 modems use.
Before we can unpack these, first let's learn exactly what goes into these images.
A standard UBFI image is actually two files concatenated together:
If we check out the file format in Binwalk, we see basically that:
Unpacking images
To unpack UBFI images, we're going to use a hex editor and copy the data out by hand.
Start by opening your UBFI image in a hex editor.
Boot Script
To extract the boot script, identify the first character in your boot script. It should be visible very early.
So, 4 bytes before the first character in our boot script is the length of the boot script, it is 2300.
Now, use your hex editor's block select feature to select the block starting at our first character, with a length of 2300.
Copy and paste into a new file, and check it out to make sure it looks right!
At the end of our boot script, we see some null bytes:
These can safely be deleted. It is an artifact from padding, and normally these are ignored.
zImage Kernel and Squashfs
To find the kernel, we're actually going to use binwalk. It will save us time.
We easily locate the starting positions of the zImage and the Squashfs:
2394 and FD800.
Now navigate to 2394 with Goto, then go 4 bytes before...what do we see?
So, 4 bytes before the zImage (just like for the boot script), we find the lengths of the files in the image.
Since this is a multi-image file, and there is two files, there's two lengths. Each length is separated with 1 byte.
First come first serve, the zImage is our first length and the Squashfs is our second length.
So, our zImage length is FB46C and our Squashfs length is 400C00.
So, block select from 2394 with a length of FB46C.
You should be able to see the beginning of the Squashfs immediately after your selection.
Copy+paste, save and you've got the zImage!
The exact same process is used to extract the Squashfs: block select from FD800 with a length of 400C00.
Unpacking Squashfs
To make changes to the root filesystem, you will have to unpack the Squashfs. This is extremely simple!
You can install unsquashfs by installing squashfs-tools on Debian/Ubuntu, refer to Google for other distros.
Repacking images
The first thing we have to do is repack the Squashfs back into a Squashfs filesystem. To do this, it's just as simple as unpacking it:
This will repack (and overwrite) our squashfs from all the files in squashfs-root - which is where we extracted it originally.
You may need to tinker with block size and compression algorithms - not all modems support all compression algorithms.
Once this is done, we just need to create new uImages and concatenate them.
But, before we can make new uImages, we're going to need another package: uboot-tools.
Once you have everything ready, run these commands with the appropriate file names:
This will compile bootscriptfilename, zImagefilename, and Squashfsfilename into a working UBFI image.
You should note that the data address and entrypoint may differ on some modems, you can find the correct values from Binwalk:
However, most modems use the same values.
Enjoy!
Before we can unpack these, first let's learn exactly what goes into these images.
A standard UBFI image is actually two files concatenated together:
- A uImage boot script file
- A uImage multi-image file containing the following:
- zImage Linux kernel
- Squashfs root filesystem
If we check out the file format in Binwalk, we see basically that:
Unpacking images
To unpack UBFI images, we're going to use a hex editor and copy the data out by hand.
Start by opening your UBFI image in a hex editor.
Boot Script
To extract the boot script, identify the first character in your boot script. It should be visible very early.
So, 4 bytes before the first character in our boot script is the length of the boot script, it is 2300.
Now, use your hex editor's block select feature to select the block starting at our first character, with a length of 2300.
Copy and paste into a new file, and check it out to make sure it looks right!
At the end of our boot script, we see some null bytes:
These can safely be deleted. It is an artifact from padding, and normally these are ignored.
zImage Kernel and Squashfs
To find the kernel, we're actually going to use binwalk. It will save us time.
We easily locate the starting positions of the zImage and the Squashfs:
2394 and FD800.
Now navigate to 2394 with Goto, then go 4 bytes before...what do we see?
So, 4 bytes before the zImage (just like for the boot script), we find the lengths of the files in the image.
Since this is a multi-image file, and there is two files, there's two lengths. Each length is separated with 1 byte.
First come first serve, the zImage is our first length and the Squashfs is our second length.
So, our zImage length is FB46C and our Squashfs length is 400C00.
So, block select from 2394 with a length of FB46C.
You should be able to see the beginning of the Squashfs immediately after your selection.
Copy+paste, save and you've got the zImage!
The exact same process is used to extract the Squashfs: block select from FD800 with a length of 400C00.
Unpacking Squashfs
To make changes to the root filesystem, you will have to unpack the Squashfs. This is extremely simple!
Code:
unsquashfs -d squashfs-root squashfsfilename
You can install unsquashfs by installing squashfs-tools on Debian/Ubuntu, refer to Google for other distros.
Repacking images
The first thing we have to do is repack the Squashfs back into a Squashfs filesystem. To do this, it's just as simple as unpacking it:
Code:
mksquashfs squashfs-root squashfsfilename -noappend -comp xz
This will repack (and overwrite) our squashfs from all the files in squashfs-root - which is where we extracted it originally.
You may need to tinker with block size and compression algorithms - not all modems support all compression algorithms.
Once this is done, we just need to create new uImages and concatenate them.
But, before we can make new uImages, we're going to need another package: uboot-tools.
Once you have everything ready, run these commands with the appropriate file names:
Code:
mkimage -A powerpc -O linux -T script -a 0 -e 0 -C none -n "Boot Script File" -d bootscriptfilename BootScriptuImage
mkimage -A arm -O linux -T multi -a 0xA00000 -e 0xA00000 -C none -n "Multi Image File" -d zImagefilename:Squashfsfilename KernelFileSystemuImage
cat BootScriptuImage KernelFileSystemuImage > UBFI
You should note that the data address and entrypoint may differ on some modems, you can find the correct values from Binwalk:
However, most modems use the same values.
Enjoy!