Modifying a custom android ROM

Posted on Fri 19 February 2021 in android

I have an old Samsung Galaxy Note 10.1 (2014) tablet, which is still very usable despite its age. I recently decided to wipe the installed Lineage ROM and do a clean install only to find that there's a bug in the most recent release that causes the Lineage setup wizard to crash, and leaves the tablet in a non-functional state.

I found some instructions to bypass the setup wizard, and in order to apply them I had to find a way to unpack the ROM, modify the setup wizard's apk, and pack it again.

In the end it didn't work out: the wizard dies upon start, making it even worse. I ended up installing the final version of Resurrection Remix instead. Despite the disappointing outcome, I decided to document the repacking procedure because it may be useful in the future.

The first step is to unpack the ROM's zip file.

mkdir custom
unzip -d custom/

We then need to convert the system dat file to an image file. For this we'll need to download sdat2img.

python custom/system.transfer.list custom/ custom/system.img

Next, we mount the image to a directory.

mkdir img_mount
sudo mount -t ext4 -o loop custom/system.img img_mount/

We now have the contents of the system image available for modification. In my case, I used a bash function to edit an XML file inside the wizard's apk to try and bypass most steps as per the previously mentioned instructions.

cd img_mount/priv-app/LineageSetupWizard/
zipedit LineageSetupWizard.apk res/raw/cm_wizard_script.xml
# vim will open and allow us to modify the XML file
cd -

Having modified the contents, it's time to repack. We'll use the make_ext4fs tool to convert the mounted directory back into an image file. Before we can do this, however, we need to convert the file_contexts.bin file of the ROM to a text version. We can do that with the sefcontext tool.

sefcontext -o file_contexts custom/file_contexts.bin

We can now create our image.

sudo make_ext4fs -T 0 -S file_contexts -l 1073741824 -a system system_new.img img_mount/

The next step is to convert the image to a sparse image. For this we need img2simg.

img2simg system_new.img system_new_sparse.img

We then convert the sparse image back to a dat file. For this we use img2sdat (make sure to get all the scripts in the repo as they work together).

python system_new_sparse.img

We now move the newly created system.* files into the new ROM directory, and generate our ROM zip file.

mv system.* custom/
cd custom
zip -r *

And that's pretty much it. There's no ROM signing going on here and my knowledge of Android doesn't allow me to understand what the consequences could be, but since it works I won't be worrying about it too much.