Skip to content

Instantly share code, notes, and snippets.

@neKuehn
Created February 27, 2019 20:29
Show Gist options
  • Save neKuehn/f8eb14b226d42cda73ce173c0cdb2970 to your computer and use it in GitHub Desktop.
Save neKuehn/f8eb14b226d42cda73ce173c0cdb2970 to your computer and use it in GitHub Desktop.
#This script was modified from the one created by Nolirium to create the new image file but not include the extra utilities (https://nolirium.blogspot.com/2016/12/android-on-chrome-os-rooting-shell.html)
#!/bin/sh
#This script was modified from the one created by Nolirium to create the new image file but not include the extra utilities
#https://nolirium.blogspot.com/2016/12/android-on-chrome-os-rooting-shell.html
# Main functions:
check_if_root() {
if [ $(id -u) != 0 ]; then
echo
echo "Error!"
echo "This script should be run as root."
exit 1
fi
}
check_writeable_rootfs() {
if [ -e /etc/aroc_writable_test ]; then
rm /etc/aroc_writable_test
fi
touch /etc/aroc_writable_test 2> /dev/null
if [ ! -e /etc/aroc_writable_test ]; then
echo "Error!"
echo "Unable to modify system!"
echo "You can disable rootfs verification by running the following command, then rebooting."
echo "sudo /usr/share/vboot/bin/make_dev_ssd.sh --remove_rootfs_verification --partitions $(( $(rootdev -s | sed -r 's/.*(.)$/\1/') - 1))"
echo "Please run the "remove_rootfs_verification" command now, then reboot and run this script again."
exit 1
fi
rm /etc/aroc_writable_test
}
detect_architecture() {
# TODO: Test/improve this function
#if [ -z "$ANDROID_ARCH" ]; then
ARCH="`uname -m`"
#fi
case "$ARCH" in
x86 | i?86) ANDROID_ARCH="x86";;
x86_64 | amd64) ANDROID_ARCH="x86";;
armel) ANDROID_ARCH="armel";;
arm64 | aarch64) ANDROID_ARCH="armv7";;
arm*) ANDROID_ARCH="armv7";;
*) error 2 "Invalid architecture '$ARCH'.";;
esac
}
modify_cros_files() {
# Just changing two environment variables for Android here.
# In CrOS v70, the writeable container and debug flags have moved (again); they are now in "/usr/share/arc-setup/config.json"
# (Older versions of CrOS have/had Android envs in arc-setup-env).
# (Even older versions had envs in the .conf files.)
mkdir -p /usr/local/Backup
# As of CrOS v70, we need to modify the two values in /usr/share/arc-setup/config.json
if [ -e /usr/share/arc-setup/config.json ]; then
mkdir -p /usr/local/Backup/arc-setup
echo "Copying usr/share/arc-setup/config.json to /usr/local/Backup/arc-setup/config.json.old"
cp -a /usr/share/arc-setup/config.json /usr/local/Backup/arc-setup/config.json.old
cp -a /usr/share/arc-setup/config.json /usr/share/arc-setup/config.json.old
echo "Setting '"ANDROID_DEBUGGABLE": true' and '"WRITABLE_MOUNT": true' in /usr/share/arc-setup/config.json"
sed -i 's/"ANDROID_DEBUGGABLE": false/"ANDROID_DEBUGGABLE": true/g' /usr/share/arc-setup/config.json 2>/dev/null
sed -i 's/"WRITABLE_MOUNT": false/"WRITABLE_MOUNT": true/g' /usr/share/arc-setup/config.json 2>/dev/null
fi
# In CrOS v6x, the two flags we want to change are within /etc/init/arc-setup-env
if [ -e /etc/init/arc-setup-env ]; then
echo "Copying /etc/init/arc-setup-env to /usr/local/Backup"
sleep 1
echo "Setting 'export WRITABLE_MOUNT=1', 'export ANDROID_DEBUGGABLE=1' and (if variable exists) 'export SHARE_FONTS=0' in /etc/init/arc-setup-env"
sed -i 's/export WRITABLE_MOUNT=0/export WRITABLE_MOUNT=1/g' /etc/init/arc-setup-env 2>/dev/null
sed -i 's/export ANDROID_DEBUGGABLE=0/export ANDROID_DEBUGGABLE=1/g' /etc/init/arc-setup-env 2>/dev/null
# NOTE The below line (disabling shared fonts) is no longer needed as of recent CrOS versions.
sed -i 's/export SHARE_FONTS=1/export SHARE_FONTS=0/g' /etc/init/arc-setup-env 2>/dev/null
fi
# In CrOS circa v55-60, we had to change the .confs directly:
if [ ! -e /usr/share/arc-setup/config.json ] && [ ! -e /etc/init/arc-setup-env ]; then
echo "Copying /etc/init/arc-setup.conf and /etc/init/arc-system-mount.conf to /usr/local/Backup"
sleep 0.2
echo "Setting 'env WRITABLE_MOUNT=1' in /etc/init/arc-setup.conf and/or /etc/init/arc-system-mount.conf"
cp -a /etc/init/arc-system-mount.conf /usr/local/Backup/arc-system-mount.conf.old
cp -a /etc/init/arc-system-mount.conf /etc/init/arc-system-mount.conf.old
cp -a /etc/init/arc-setup.conf /usr/local/Backup/arc-setup.conf.old
cp -a /etc/init/arc-setup.conf /etc/init/arc-setup.conf.old
sed -i 's/env WRITABLE_MOUNT=0/env WRITABLE_MOUNT=1/g' /etc/init/arc-setup.conf
sed -i 's/env WRITABLE_MOUNT=0/env WRITABLE_MOUNT=1/g' /etc/init/arc-system-mount.conf
echo "Setting 'env ANDROID_DEBUGGABLE=1' in arc-setup.conf"
sed -i 's/env ANDROID_DEBUGGABLE=0/env ANDROID_DEBUGGABLE=1/g' /etc/init/arc-setup.conf
fi
}
create_image() {
# Creates a blank ext4 image.
# Make some working directories if they don't already exist.
mkdir -p /usr/local/Android_Images
mkdir -p /usr/local/Android_Images/Mounted
mkdir -p /usr/local/Android_Images/Original
echo
echo "Creating new Android system image at /usr/local/Android_Images/system.raw.expanded.img"
# Make the image.
# For arm, the unsquashed image needs to be at least~ 1GB (~800MB for Marshmallow).
# For x86, the unsquashed image needs to be at least ~1.4GB (~1GB for Marshmallow).
# Since the raw rootfs has increased in size lately, create a blank 2GB image, make it sparse so it takes only as much space on disk as required.
# If /usr/local/Android_Images/system.raw.expanded.img already exists, delete it.
rm -rf /usr/local/Android_Images/system.raw.expanded.img
# Previous version of file creation used dd
# It's much faster if we use fallocate and starts off sparse, so uses only as much space on disk as necessary.
if [ $ANDROID_ARCH=armv7 ]; then
cd /usr/local/Android_Images
# dd if=/dev/zero of=system.raw.expanded.img count=2000000 bs=1024 status=progress
fallocate -l 1.7G /usr/local/Android_Images/system.raw.expanded.img
else
if [ $ANDROID_ARCH=x86 ]; then
cd /usr/local/Android_Images
# dd if=/dev/zero of=system.raw.expanded.img count=2000000 bs=1024 status=progress
fallocate -l 2.2G /usr/local/Android_Images/system.raw.expanded.img
else
echo "Error!"
echo "Unable to detect correct architecture!"
echo
exit 1
fi
#
fi
#fallocate -l 2G /usr/local/Android_Images/system.raw.expanded.img
sleep 0.001
echo "Formatting system.raw.expanded.img as ext4 filesystem"
echo
# After we create an image with fallocate, mkfs.ext4 complains about the geometry/cylinders when we format it
# Here, we ignore this complaint, sending it 2>/dev/null
mkfs ext4 -F /usr/local/Android_Images/system.raw.expanded.img 2>/dev/null
}
# Functions end
main() {
check_if_root
echo "Test Rooting scripts for Android on Chrome OS"
sleep 0.2
echo
echo
echo "Version 0.27.1"
sleep 0.2
echo
echo "Unofficial scripts to create a rooted Android system image on Chrome OS"
sleep 0.2
echo
sleep 1
echo
echo "In order to modify system files, the Chrome OS system partition needs to have been mounted writeable."
echo "If you haven't already disabled rootfs verification, you will need to do so before proceeding with this script."
echo
echo "You should be able to disable rootfs verification by running the following command, then rebooting."
echo
echo
echo
echo
echo "sudo /usr/share/vboot/bin/make_dev_ssd.sh --remove_rootfs_verification --partitions $(( $(rootdev -s | sed -r 's/.*(.)$/\1/') - 1))"
sleep 1
echo
echo
echo
echo
echo "Alternatively, run the command below, then follow the prompt."
echo
echo
echo "sudo /usr/share/vboot/bin/make_dev_ssd.sh --remove_rootfs_verification"
sleep 1
echo
echo
echo "Press Ctrl+C to cancel if you still need to do the above."
sleep 2
echo
echo "Be aware that modifying the system partition could cause automatic updates to fail, may result in having to powerwash or restore from USB potentially causing loss of data! Please make sure important files are backed up."
echo
echo
check_writeable_rootfs
# Remount the Chrome OS root drive as writeable
mount -o remount,rw / 2> /dev/null
# Modify the two/three envs in /etc/init
modify_cros_files
# Make a new writeable Android rootfs image, symlink it in place of the original, and copy our files to it.
# First, check if symlink already exists.
if [ -L /opt/google/containers/android/system.raw.img ]; then
echo "The file at /opt/google/containers/android/system.raw.img is already a symlink!"
# If the file is already a symlink, we need to check if a backup of the original system.raw.img exists.
if [ ! -f /home/chronos/user/Downloads/system.raw.img ]; then
if [ ! -f /opt/google/containers/android/system.raw.img.bk ]; then
echo
echo "Error!"
echo "System.raw.img not found"
echo
exit 1
fi
fi
echo "Removing symlink"
rm -rf /opt/google/containers/android/system.raw.img
fi
if [ ! -e /opt/google/containers/android/system.raw.img ]; then
if [ -f /opt/google/containers/android/system.raw.img.bk ]; then
echo "Using /opt/google/containers/android/system.raw.img.bk"
else
if [ -f /home/chronos/user/Downloads/system.raw.img ]; then
echo "Using /home/chronos/user/Downloads/system.raw.img"
else
echo
echo "Error!"
echo "System.raw.img not found"
echo
exit 1
fi
fi
fi
# Unmount any previous instances
umount -l /usr/local/Android_Images/system.raw.expanded.img 2>/dev/null
umount -l /usr/local/Android_Images/system.raw.expanded.img 2>/dev/null
umount -l /usr/local/Android_Images/Original 2>/dev/null
umount -l /usr/local/Android_Images/Mounted 2>/dev/null
detect_architecture
create_image
echo "Mounting system.raw.expanded.img"
if [ -e /opt/google/containers/android/system.raw.img ]; then
if [ -L /opt/google/containers/android/system.raw.img ]; then
if [ -e /opt/google/containers/android/system.raw.img.bk ]; then
umount -l /usr/local/Android_Images/Original 2>/dev/null
mount -o loop,rw,sync /opt/google/containers/android/system.raw.img.bk /usr/local/Android_Images/Original 2>/dev/null
else
if [ -e /home/chronos/user/Downloads/system.raw.img ]; then
umount -l /usr/local/Android_Images/Original 2>/dev/null
mount -o loop,rw,sync /home/chronos/user/Downloads/system.raw.img /usr/local/Android_Images/Original 2>/dev/null
else
echo
echo "Error!"
echo "System.raw.img not found"
echo
exit 1
fi
fi
fi
fi
if [ ! -L /opt/google/containers/android/system.raw.img ]; then
if [ -e /opt/google/containers/android/system.raw.img ]; then
umount -l /usr/local/Android_Images/Original 2>/dev/null
mount -o loop,rw,sync /opt/google/containers/android/system.raw.img /usr/local/Android_Images/Original 2>/dev/null
else
if [ -e /opt/google/containers/android/system.raw.img.bk ]; then
umount -l /usr/local/Android_Images/Original 2>/dev/null
mount -o loop,rw,sync /opt/google/containers/android/system.raw.img.bk /usr/local/Android_Images/Original 2>/dev/null
else
if [ -e /home/chronos/user/Downloads/system.raw.img ]; then
echo "Mounting /home/chronos/user/Downloads/system.raw.img and copying files"
umount -l /usr/local/Android_Images/Original 2>/dev/null
mount -o loop,rw,sync /home/chronos/user/Downloads/system.raw.img /usr/local/Android_Images/Original 2>/dev/null
else
echo
echo "Error!"
echo "System.raw.img not found"
echo
exit 1
fi
fi
fi
fi
#ORIGINAL_ANDROID_ROOTFS=/opt/google/containers/android/rootfs/root
ANDROID_ROOTFS=/usr/local/Android_Images/Original
# We want to set SELinux to 'Permissive' so we can copy rootfs files with their original contexts without encountering errors.
# At one point, the ability to 'setenforce' was removed in an OS update. (it was later restored in another update).
setenforce 0
# Check if it worked
SE=$(getenforce)
if SE="Permissive"
then
echo "SELinux successfully set to 'Permissive' temporarily"
echo "Copying Android system files"
mount -o loop,rw,sync /usr/local/Android_Images/system.raw.expanded.img /usr/local/Android_Images/Mounted
cp -a -r $ANDROID_ROOTFS/. /usr/local/Android_Images/Mounted
else
# In case we can't set SE Linux to 'Permissive', the following is a workaround to copy files with correct contexts in 'Enforcing' mode.
echo "Copying Android system files"
# We should be able to copy files/dirs in 'Enforcing' mode by mounting with -o fscontext.
# Directories mounted with special contexts:
#u:object_r:cgroup:s0 acct
#u:object_r:device:s0 dev
#u:object_r:tmpfs:s0 mnt
#u:object_r:oemfs:s0 oem
#u:object_r:sysfs:s0 sys
mount -o loop,rw,sync,fscontext=u:object_r:cgroup:s0 /usr/local/Android_Images/system.raw.expanded.img /usr/local/Android_Images/Mounted
cp -a -r $ANDROID_ROOTFS/acct /usr/local/Android_Images/Mounted/acct
umount -l /usr/local/Android_Images/Mounted
mount -o loop,rw,sync,fscontext=u:object_r:device:s0 /usr/local/Android_Images/system.raw.expanded.img /usr/local/Android_Images/Mounted
cp -a -r $ANDROID_ROOTFS/dev /usr/local/Android_Images/Mounted/dev
umount -l /usr/local/Android_Images/Mounted
mount -o loop,rw,sync,fscontext=u:object_r:tmpfs:s0 system.raw.expanded.img /usr/local/Android_Images/Mounted
cp -a -r $ANDROID_ROOTFS/mnt /usr/local/Android_Images/Mounted/mnt
umount -l /usr/local/Android_Images/Mounted
mount -o loop,rw,sync,fscontext=u:object_r:oemfs:s0 /usr/local/Android_Images/system.raw.expanded.img /usr/local/Android_Images/Mounted
cp -a -r $ANDROID_ROOTFS/oem /usr/local/Android_Images/Mounted/oem
umount -l /usr/local/Android_Images/Mounted
mount -o loop,rw,sync,fscontext=u:object_r:sysfs:s0 /usr/local/Android_Images/system.raw.expanded.img /usr/local/Android_Images/Mounted
cp -a -r $ANDROID_ROOTFS/sys /usr/local/Android_Images/Mounted/sys
umount -l /usr/local/Android_Images/Mounted
mount -o loop,rw,sync /usr/local/Android_Images/system.raw.expanded.img /usr/local/Android_Images/Mounted
cp -a -r $ANDROID_ROOTFS/storage /usr/local/Android_Images/Mounted/storage
umount -l /usr/local/Android_Images/Mounted
# Copying rootfs files
mount -o loop,rw,sync,fscontext=u:object_r:rootfs:s0 /usr/local/Android_Images/system.raw.expanded.img /usr/local/Android_Images/Mounted
cp -a -r $ANDROID_ROOTFS/. /usr/local/Android_Images/Mounted
fi
# If we were copying files from the original Android rootfs, unmount it now we've finished..
if [ -f /opt/google/containers/android/system.raw.img ]; then
umount -l /opt/google/containers/android/system.raw.img > /dev/null 2>&1 || /bin/true
fi
# Unmount the new rootfs too, so we can mount it again without special context later
umount -l /usr/local/Android_Images/system.raw.expanded.img 2>/dev/null
# If the original rootfs exists, before replacing it with a symlink, make a backup.
# In the event of errors, re-running the script, or post-powerwash, the original may be restored by reversing the 'mv' command.
# i.e. mv /opt/google/containers/android/system.raw.img.bk /opt/google/containers/android/system.raw.img.
if [ -e /opt/google/containers/android/system.raw.img ]; then
if [ ! -L /opt/google/containers/android/system.raw.img ]; then
echo "Moving original Android rootfs image to /opt/google/containers/android/system.raw.img.bk"
mv /opt/google/containers/android/system.raw.img /opt/google/containers/android/system.raw.img.bk
# Make the symlink from the original pathname to our writeable rootfs image
echo "Replacing original Android rootfs image path with symlink to /usr/local/Android_Images/system.raw.expanded.img"
ln -s /usr/local/Android_Images/system.raw.expanded.img /opt/google/containers/android/system.raw.img
fi
else
if [ -e /usr/local/Android_Images/system.raw.expanded.img ]; then
echo "Creating symlink to /usr/local/Android_Images/system.raw.expanded.img at original Android rootfs image file path"
ln -s /usr/local/Android_Images/system.raw.expanded.img /opt/google/containers/android/system.raw.img
fi
fi
cd /usr/local/Android_Images
mkdir -p /usr/local/Android_Images/Mounted
# Mount our new Android rootfs
mount -o loop,rw,sync /usr/local/Android_Images/system.raw.expanded.img /usr/local/Android_Images/Mounted 2>/dev/null
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment