Hacking an image file + Mounting devices with labels - LINUX

So I’ve been modifying the image file for almost a month and I would like to share with you how to customize an already built image (mostly stables ones).
Since I don’t have Windows, I will share how to do all these procedures with Linux, so here we go:

So, create a working directory and, once you have the image file, you can extract its content with unzip:

Code: 
mkdir work && cd work
unzip /path/to/your/update.img

Remove the certificates and manifest files as the signature procedure will create new ones later on:

Code: 
rm META-INF/CERT.* && rm META-INF/*.MANIFEST.MF

I added tons of stuff to system/opt to have amule, a torrent client and some commands that I normally use on my desktop computer.
I also removed usbmount to create my own version of this script to use labels as mountpoints and also removed all the content of /media (if you leave empty directories like in my case, create a .empty file in that location). I wrote this version of usbmount which is simpler and does what I want:

Code: 
#!/bin/sh

MOUNT_BASE=”/media”
MOUNTOPTS=”dirsync,nodev,noatime,nodiratime”
FILESYSTEMS=’ hfsplus vfat ext2 ext3 ext4 exfat ntfs xfs ‘

case $1 in
    “add”)

        # Get the device information
        DEVINFO=$(/sbin/blkid -p $DEVNAME)
        FSTYPE=$(echo “$DEVINFO” | sed ‘s/.*[[:blank:]]TYPE=”\([^”]*\)”.*/\1/g; s/[[:blank:]]*//g;’)
        USAGE=$(echo “$DEVINFO”  | sed ‘s/.*[[:blank:]]USAGE=”\([^”]*\)”.*/\1/g; s/[[:blank:]]*//g;’)
        LABEL=$(echo “$DEVINFO”  | sed ‘s/.*[[:blank:]]LABEL=”\([^”]*\)”.*/\1/g; s/[[:blank:]]*//g;’)

        # Check if it’s already mounted
        if [ “`grep “^$DEVNAME” /proc/mounts`” != “” ]; then
            logger info “$DEVNAME already mounted”
            exit 1
        fi

        # Check if it’s actually a block device containing a filesystem
        if ! echo $USAGE | egrep -q “(filesystem|disklabel)”; then
            logger info “$DEVNAME does not contain a filesystem or disklabel”
            exit 1
        fi

        # Check if it has a valid filesystem
        if [ “`echo $FILESYSTEMS | grep ” ${FSTYPE} “`” = “” ]; then
            logger info “$DEVNAME contains an unsuported filesystem: [${FSTYPE}]”
            exit 1
        fi

        # If it has no label, use the device name as mountpoint
        if [ -z “${LABEL}” ]; then
            logger info “$DEVNAME has no label, using the device name as mountpoint”
            LABEL=`basename ${DEVNAME}`
        fi

        # Create the mountpoint and mount the device in that location
        mkdir -p ${MOUNT_BASE}/${LABEL}
        logger info “executing command: mount -t${FSTYPE} “$DEVNAME” ${MOUNT_BASE}/${LABEL}”
        mount -t${FSTYPE} -o${MOUNTOPTS} “$DEVNAME” ${MOUNT_BASE}/${LABEL}

    ;;
    “remove”)

        # If it is mounted, umount it
        if [ “`grep “^$DEVNAME ${MOUNT_BASE}/” /proc/mounts`” != “” ]; then
            logger info “executing command: umount -l ${MOUNT_BASE}/${LABEL}”
            umount -l ${MOUNT_BASE}/${LABEL}
        fi

    ;;
    *)
        logger err “Wrong option [$1]”
    ;;
esac

That way, directories in /media will be auto created when a new device will be added with the label of the device or, if it has no label, it will use the device name (so instead of /media/usb0 I have /media/Memory and if no labels where set I would have /media/sda1 instead of the devices moving around).

The /usr directory in the image is just a squash filesystem, so the best way to make modifications in it is to “unsquash it”, make the modifications/replacements and then re-create the filesystem again (you need squashfs-tools for this), this is how you can replace the usbmount file:

Code: 
unsquashfs system/usr.sqsh -d usr

Now you can make all the modifications you want to that filesystem, in my case I replaced the usbmount script. If you want to, you can do it with this:

Code: 
cat << _EOF_ > usr/share/usbmount/usbmount
#!/bin/sh

MOUNT_BASE=”/media”
MOUNTOPTS=”dirsync,nodev,noatime,nodiratime”
FILESYSTEMS=’ hfsplus vfat ext2 ext3 ext4 exfat ntfs xfs ‘

case $1 in
    “add”)

        # Get the device information
        DEVINFO=$(/sbin/blkid -p $DEVNAME)
        FSTYPE=$(echo “$DEVINFO” | sed ‘s/.*[[:blank:]]TYPE=”\([^”]*\)”.*/\1/g; s/[[:blank:]]*//g;’)
        USAGE=$(echo “$DEVINFO”  | sed ‘s/.*[[:blank:]]USAGE=”\([^”]*\)”.*/\1/g; s/[[:blank:]]*//g;’)
        LABEL=$(echo “$DEVINFO”  | sed ‘s/.*[[:blank:]]LABEL=”\([^”]*\)”.*/\1/g; s/[[:blank:]]*//g;’)

        # Check if it’s already mounted
        if [ “`grep “^$DEVNAME” /proc/mounts`” != “” ]; then
            logger info “$DEVNAME already mounted”
            exit 1
        fi

        # Check if it’s actually a block device containing a filesystem
        if ! echo $USAGE | egrep -q “(filesystem|disklabel)”; then
            logger info “$DEVNAME does not contain a filesystem or disklabel”
            exit 1
        fi

        # Check if it has a valid filesystem
        if [ “`echo $FILESYSTEMS | grep ” ${FSTYPE} “`” = “” ]; then
            logger info “$DEVNAME contains an unsuported filesystem: [${FSTYPE}]”
            exit 1
        fi

        # If it has no label, use the device name as mountpoint
        if [ -z “${LABEL}” ]; then
            logger info “$DEVNAME has no label, using the device name as mountpoint”
            LABEL=`basename ${DEVNAME}`
        fi

        # Create the mountpoint and mount the device in that location
        mkdir -p ${MOUNT_BASE}/${LABEL}
        logger info “executing command: mount -t${FSTYPE} “$DEVNAME” ${MOUNT_BASE}/${LABEL}”
        mount -t${FSTYPE} -o${MOUNTOPTS} “$DEVNAME” ${MOUNT_BASE}/${LABEL}

    ;;
    “remove”)

        # If it is mounted, umount it
        if [ “`grep “^$DEVNAME ${MOUNT_BASE}/” /proc/mounts`” != “” ]; then
            logger info “executing command: umount -l ${MOUNT_BASE}/${LABEL}”
            umount -l ${MOUNT_BASE}/${LABEL}
        fi

    ;;
    *)
        logger err “Wrong option [$1]”
    ;;
esac
_EOF_

By doing this, you can remove some extra stuff in system/etc, like usbmount:

Code: Select all
rm -rf system/etc/usbmount*

Now, we have to recreate the squashfs:

Code: 
mksquashfs usr system/usr.sqsh -comp gzip -noappend -all-root

Remember to remove the usr directory created when “unsquashing”:

Code: 
rm -rf usr

If you added any new files (as I did in system/opt, I added irssi, amule, transmission, gnu-sed, vim, a su binary and disabled root ssh access in dropbear -I created a new user editing my hand system/etc/{passwd,shadow} and modified system/etc/init.d/S50dropbear adding — -w to the dropbear call-) you have to modify the updater-script, it is in

Code: 
META-INF/com/google/android/updater-script

You’ll understand how that file is structured. Just take in note that special file permisions (with the set_perm instruction), like setuid are not 4 digits but 5, so permisions like 0644 are ok, but 4755 (for su) would be 04755 (I guess this is a some sort of bug in the android recovery system).

Finally you have to rebuild the image, to do this first compress the new image file with zip:

Code: 
zip -r update-unsigned.img *

And then you have to sign that update-unsigned.img

Code: 
java -Xmx1024m -jar signapk.jar -w testkey.x509.pem testkey.pk8 update-unsigned.img update.img