2020-03-20 07:44:08 -03:00
############################################
2017-06-19 00:15:44 +08:00
# Magisk General Utility Functions
2020-03-20 07:44:08 -03:00
############################################
2017-06-19 00:15:44 +08:00
2019-02-24 02:11:11 -05:00
#MAGISK_VERSION_STUB
2019-02-11 17:14:07 -05:00
###################
# Helper Functions
###################
2017-07-11 01:54:11 +08:00
2019-02-11 17:14:07 -05:00
ui_print( ) {
2020-11-29 20:35:34 -04:00
if $BOOTMODE ; then
echo " $1 "
else
echo -e " ui_print $1 \nui_print " >> /proc/self/fd/$OUTFD
fi
2019-02-11 17:14:07 -05:00
}
2018-01-01 16:46:28 +08:00
2019-02-11 17:14:07 -05:00
toupper( ) {
echo " $@ " | tr '[:lower:]' '[:upper:]'
}
2017-09-28 00:54:01 +08:00
2019-02-11 17:14:07 -05:00
grep_cmdline( ) {
local REGEX = " s/^ $1 =//p "
2021-11-02 20:25:14 +08:00
local CL = $( cat /proc/cmdline 2>/dev/null)
POSTFIX = $( [ $( expr $( echo " $CL " | tr -d -c '"' | wc -m) % 2) = = 0 ] && echo -n '' || echo -n '"' )
{ eval " for i in $CL $POSTFIX ; do echo \$i; done " ; cat /proc/bootconfig 2>/dev/null | sed 's/[[:space:]]*=[[:space:]]*\(.*\)/=\1/g' | sed 's/"//g' ; } | sed -n " $REGEX " 2>/dev/null
2019-02-11 17:14:07 -05:00
}
grep_prop( ) {
local REGEX = " s/^ $1 =//p "
shift
local FILES = $@
[ -z " $FILES " ] && FILES = '/system/build.prop'
2021-01-22 02:28:53 -08:00
cat $FILES 2>/dev/null | dos2unix | sed -n " $REGEX " | head -n 1
2019-02-11 17:14:07 -05:00
}
2021-04-06 03:56:39 -07:00
grep_get_prop( ) {
local result = $( grep_prop $@ )
if [ -z " $result " ] ; then
# Fallback to getprop
getprop " $1 "
else
echo $result
fi
}
2019-02-11 17:14:07 -05:00
getvar( ) {
local VARNAME = $1
2020-04-05 01:27:07 -07:00
local VALUE
local PROPPATH = '/data/.magisk /cache/.magisk'
2021-03-21 19:34:33 -03:00
[ ! -z $MAGISKTMP ] && PROPPATH = " $MAGISKTMP /config $PROPPATH "
2020-04-05 01:27:07 -07:00
VALUE = $( grep_prop $VARNAME $PROPPATH )
2021-03-21 19:34:33 -03:00
[ ! -z $VALUE ] && eval $VARNAME = \$ VALUE
2019-02-11 17:14:07 -05:00
}
is_mounted( ) {
2021-01-22 02:28:53 -08:00
grep -q " $( readlink -f $1 ) " /proc/mounts 2>/dev/null
2019-02-11 17:14:07 -05:00
return $?
}
abort( ) {
ui_print " $1 "
$BOOTMODE || recovery_cleanup
2021-03-21 19:34:33 -03:00
[ ! -z $MODPATH ] && rm -rf $MODPATH
2020-03-22 00:08:04 -07:00
rm -rf $TMPDIR
2019-02-11 17:14:07 -05:00
exit 1
}
resolve_vars( ) {
MAGISKBIN = $NVBASE /magisk
2019-02-12 02:14:57 -05:00
POSTFSDATAD = $NVBASE /post-fs-data.d
SERVICED = $NVBASE /service.d
2019-02-11 17:14:07 -05:00
}
2020-03-08 22:25:06 -07:00
print_title( ) {
2021-10-20 17:06:45 -03:00
local len line1len line2len bar
2020-04-21 20:14:18 -03:00
line1len = $( echo -n $1 | wc -c)
line2len = $( echo -n $2 | wc -c)
2020-11-29 20:35:34 -04:00
len = $line2len
[ $line1len -gt $line2len ] && len = $line1len
2020-03-08 22:25:06 -07:00
len = $(( len + 2 ))
2021-10-20 17:06:45 -03:00
bar = $( printf " % ${ len } s " | tr ' ' '*' )
ui_print " $bar "
2020-03-08 22:25:06 -07:00
ui_print " $1 "
2020-04-21 20:14:18 -03:00
[ " $2 " ] && ui_print " $2 "
2021-10-20 17:06:45 -03:00
ui_print " $bar "
2020-03-08 22:25:06 -07:00
}
2019-02-11 17:14:07 -05:00
######################
# Environment Related
######################
2017-10-31 17:05:24 +08:00
2018-08-28 22:03:12 -04:00
setup_flashable( ) {
2019-02-24 02:11:11 -05:00
ensure_bb
$BOOTMODE && return
2018-07-07 17:48:05 +08:00
if [ -z $OUTFD ] || readlink /proc/$$ /fd/$OUTFD | grep -q /tmp; then
2018-06-21 10:53:49 +08:00
# We will have to manually find out OUTFD
2018-07-07 17:48:05 +08:00
for FD in ` ls /proc/$$ /fd` ; do
if readlink /proc/$$ /fd/$FD | grep -q pipe; then
2020-02-04 15:55:03 -04:00
if ps | grep -v grep | grep -qE " 3 $FD |status_fd= $FD " ; then
2017-07-10 00:17:34 +08:00
OUTFD = $FD
break
fi
fi
done
fi
2021-01-22 02:28:53 -08:00
recovery_actions
2017-07-10 00:17:34 +08:00
}
2019-02-24 02:11:11 -05:00
ensure_bb( ) {
2020-03-19 03:48:23 -07:00
if set -o | grep -q standalone; then
# We are definitely in busybox ash
set -o standalone
return
fi
2020-03-08 22:25:06 -07:00
# Find our busybox binary
2020-03-19 03:48:23 -07:00
local bb
2020-03-08 22:25:06 -07:00
if [ -f $TMPDIR /busybox ] ; then
2020-03-19 03:48:23 -07:00
bb = $TMPDIR /busybox
2020-03-08 22:25:06 -07:00
elif [ -f $MAGISKBIN /busybox ] ; then
2020-03-19 03:48:23 -07:00
bb = $MAGISKBIN /busybox
2019-02-11 17:14:07 -05:00
else
2020-03-08 22:25:06 -07:00
abort "! Cannot find BusyBox"
2019-02-11 17:14:07 -05:00
fi
2020-03-19 03:48:23 -07:00
chmod 755 $bb
2020-12-28 00:24:03 -08:00
# Busybox could be a script, make sure /system/bin/sh exists
if [ ! -f /system/bin/sh ] ; then
umount -l /system 2>/dev/null
mkdir -p /system/bin
ln -s $( command -v sh) /system/bin/sh
fi
export ASH_STANDALONE = 1
2020-03-19 03:48:23 -07:00
# Find our current arguments
# Run in busybox environment to ensure consistent results
# /proc/<pid>/cmdline shall be <interpreter> <script> <arguments...>
2020-12-28 00:24:03 -08:00
local cmds = " $( $bb sh -c "
2020-03-20 08:02:48 -03:00
for arg in \$ ( tr '\0' '\n' < /proc/$$ /cmdline) ; do
2020-03-19 03:48:23 -07:00
if [ -z \" \$ cmds\" ] ; then
# Skip the first argument as we want to change the interpreter
2020-12-28 00:24:03 -08:00
cmds = \" sh\"
2020-03-19 03:48:23 -07:00
else
cmds = \" \$ cmds '\$arg' \"
fi
done
2020-10-14 10:42:26 +02:00
echo \$ cmds")"
2020-03-08 22:25:06 -07:00
# Re-exec our script
2020-03-19 03:48:23 -07:00
echo $cmds | $bb xargs $bb
exit
2017-06-19 00:15:44 +08:00
}
2019-02-11 17:14:07 -05:00
recovery_actions( ) {
2020-01-11 17:48:21 -04:00
# Make sure random won't get blocked
2019-02-11 17:14:07 -05:00
mount -o bind /dev/urandom /dev/random
# Unset library paths
OLD_LD_LIB = $LD_LIBRARY_PATH
OLD_LD_PRE = $LD_PRELOAD
2019-02-24 02:11:11 -05:00
OLD_LD_CFG = $LD_CONFIG_FILE
2019-02-11 17:14:07 -05:00
unset LD_LIBRARY_PATH
unset LD_PRELOAD
2019-02-24 02:11:11 -05:00
unset LD_CONFIG_FILE
2019-02-11 17:14:07 -05:00
}
recovery_cleanup( ) {
2020-02-04 15:55:03 -04:00
local DIR
2019-02-11 17:14:07 -05:00
ui_print "- Unmounting partitions"
2020-01-11 17:48:21 -04:00
( umount_apex
2020-02-04 15:55:03 -04:00
if [ ! -d /postinstall/tmp ] ; then
umount -l /system
umount -l /system_root
fi
2020-01-11 17:48:21 -04:00
umount -l /vendor
umount -l /persist
2020-11-02 23:20:38 -08:00
umount -l /metadata
2020-02-04 15:55:03 -04:00
for DIR in /apex /system /system_root; do
if [ -L " ${ DIR } _link " ] ; then
rmdir $DIR
mv -f ${ DIR } _link $DIR
fi
done
2020-01-11 17:48:21 -04:00
umount -l /dev/random) 2>/dev/null
2019-12-27 17:53:27 +08:00
[ -z $OLD_LD_LIB ] || export LD_LIBRARY_PATH = $OLD_LD_LIB
[ -z $OLD_LD_PRE ] || export LD_PRELOAD = $OLD_LD_PRE
[ -z $OLD_LD_CFG ] || export LD_CONFIG_FILE = $OLD_LD_CFG
2018-06-21 01:37:08 +08:00
}
2019-02-11 17:14:07 -05:00
#######################
# Installation Related
#######################
2020-02-08 03:26:39 -08:00
# find_block [partname...]
2018-06-21 01:37:08 +08:00
find_block( ) {
2020-04-21 14:56:04 -03:00
local BLOCK DEV DEVICE DEVNAME PARTNAME UEVENT
2018-07-03 02:57:57 +08:00
for BLOCK in " $@ " ; do
2020-04-21 14:56:04 -03:00
DEVICE = ` find /dev/block \( -type b -o -type c -o -type l \) -iname $BLOCK | head -n 1` 2>/dev/null
2018-07-03 02:57:57 +08:00
if [ ! -z $DEVICE ] ; then
readlink -f $DEVICE
return 0
fi
done
# Fallback by parsing sysfs uevents
2020-04-21 14:56:04 -03:00
for UEVENT in /sys/dev/block/*/uevent; do
DEVNAME = ` grep_prop DEVNAME $UEVENT `
PARTNAME = ` grep_prop PARTNAME $UEVENT `
2018-12-24 21:36:37 +08:00
for BLOCK in " $@ " ; do
2020-04-21 14:56:04 -03:00
if [ " $( toupper $BLOCK ) " = " $( toupper $PARTNAME ) " ] ; then
2018-06-21 01:37:08 +08:00
echo /dev/block/$DEVNAME
return 0
fi
done
done
2020-04-21 14:56:04 -03:00
# Look just in /dev in case we're dealing with MTD/NAND without /dev/block devices/links
for DEV in " $@ " ; do
DEVICE = ` find /dev \( -type b -o -type c -o -type l \) -maxdepth 1 -iname $DEV | head -n 1` 2>/dev/null
if [ ! -z $DEVICE ] ; then
readlink -f $DEVICE
return 0
fi
done
2018-06-21 01:37:08 +08:00
return 1
}
2020-02-08 03:26:39 -08:00
# setup_mntpoint <mountpoint>
setup_mntpoint( ) {
2020-02-04 15:55:03 -04:00
local POINT = $1
[ -L $POINT ] && mv -f $POINT ${ POINT } _link
if [ ! -d $POINT ] ; then
rm -f $POINT
mkdir -p $POINT
fi
}
2020-02-08 03:26:39 -08:00
# mount_name <partname(s)> <mountpoint> <flag>
2019-12-27 17:53:27 +08:00
mount_name( ) {
2019-04-30 17:35:58 -04:00
local PART = $1
2019-12-27 17:53:27 +08:00
local POINT = $2
local FLAG = $3
2020-02-08 03:26:39 -08:00
setup_mntpoint $POINT
2019-04-30 17:35:58 -04:00
is_mounted $POINT && return
2019-12-27 17:53:27 +08:00
# First try mounting with fstab
mount $FLAG $POINT 2>/dev/null
2019-04-30 17:35:58 -04:00
if ! is_mounted $POINT ; then
2020-11-02 23:20:38 -08:00
local BLOCK = $( find_block $PART )
mount $FLAG $BLOCK $POINT || return
2019-04-30 17:35:58 -04:00
fi
2020-11-02 23:20:38 -08:00
ui_print " - Mounting $POINT "
2019-12-27 17:53:27 +08:00
}
2020-02-08 03:26:39 -08:00
# mount_ro_ensure <partname(s)> <mountpoint>
2019-12-27 17:53:27 +08:00
mount_ro_ensure( ) {
# We handle ro partitions only in recovery
$BOOTMODE && return
2020-01-11 17:48:21 -04:00
local PART = $1
local POINT = $2
mount_name " $PART " $POINT '-o ro'
2019-04-30 17:35:58 -04:00
is_mounted $POINT || abort " ! Cannot mount $POINT "
}
2017-09-13 04:07:25 +08:00
mount_partitions( ) {
# Check A/B slot
2018-06-21 01:37:08 +08:00
SLOT = ` grep_cmdline androidboot.slot_suffix`
if [ -z $SLOT ] ; then
2019-04-30 17:35:58 -04:00
SLOT = ` grep_cmdline androidboot.slot`
[ -z $SLOT ] || SLOT = _${ SLOT }
2017-11-11 01:33:50 +08:00
fi
2018-06-21 01:37:08 +08:00
[ -z $SLOT ] || ui_print " - Current boot slot: $SLOT "
2018-01-01 16:46:28 +08:00
2019-12-27 17:53:27 +08:00
# Mount ro partitions
2020-11-08 18:40:18 +05:30
if is_mounted /system_root; then
umount /system 2& >/dev/null
umount /system_root 2& >/dev/null
fi
2020-01-11 17:48:21 -04:00
mount_ro_ensure " system $SLOT app $SLOT " /system
2020-04-20 19:18:19 +08:00
if [ -f /system/init -o -L /system/init ] ; then
2018-06-17 17:59:24 +08:00
SYSTEM_ROOT = true
2020-02-08 03:26:39 -08:00
setup_mntpoint /system_root
2020-03-09 06:38:47 +01:00
if ! mount --move /system /system_root; then
umount /system
umount -l /system 2>/dev/null
mount_ro_ensure " system $SLOT app $SLOT " /system_root
fi
2017-09-13 04:07:25 +08:00
mount -o bind /system_root/system /system
2019-04-30 17:35:58 -04:00
else
2020-11-29 20:35:34 -04:00
SYSTEM_ROOT = false
grep ' / ' /proc/mounts | grep -qv 'rootfs' || grep -q ' /system_root ' /proc/mounts && SYSTEM_ROOT = true
2017-09-13 04:07:25 +08:00
fi
2020-05-01 17:43:45 -03:00
# /vendor is used only on some older devices for recovery AVBv1 signing so is not critical if fails
[ -L /system/vendor ] && mount_name vendor$SLOT /vendor '-o ro'
2019-05-01 01:22:37 -04:00
$SYSTEM_ROOT && ui_print "- Device is system-as-root"
2019-12-27 17:53:27 +08:00
2020-01-11 17:48:21 -04:00
# Allow /system/bin commands (dalvikvm) on Android 10+ in recovery
$BOOTMODE || mount_apex
2017-09-13 04:07:25 +08:00
}
2020-02-08 03:26:39 -08:00
# loop_setup <ext4_img>, sets LOOPDEV
loop_setup( ) {
unset LOOPDEV
local LOOP
local MINORX = 1
[ -e /dev/block/loop1 ] && MINORX = $( stat -Lc '%T' /dev/block/loop1)
local NUM = 0
while [ $NUM -lt 64 ] ; do
LOOP = /dev/block/loop$NUM
[ -e $LOOP ] || mknod $LOOP b 7 $(( NUM * MINORX))
if losetup $LOOP " $1 " 2>/dev/null; then
LOOPDEV = $LOOP
break
fi
NUM = $(( NUM + 1 ))
done
}
2020-01-11 17:48:21 -04:00
mount_apex( ) {
2020-02-08 03:26:39 -08:00
$BOOTMODE || [ ! -d /system/apex ] && return
local APEX DEST
setup_mntpoint /apex
2021-01-22 02:28:53 -08:00
mount -t tmpfs tmpfs /apex -o mode = 755
local PATTERN = 's/.*"name":[^"]*"\([^"]*\).*/\1/p'
2020-01-11 17:48:21 -04:00
for APEX in /system/apex/*; do
2020-02-08 03:26:39 -08:00
if [ -f $APEX ] ; then
# APEX APKs, extract and loop mount
unzip -qo $APEX apex_payload.img -d /apex
2021-01-23 16:09:30 -08:00
DEST = $( unzip -qp $APEX apex_manifest.pb | strings | head -n 1)
[ -z $DEST ] && DEST = $( unzip -qp $APEX apex_manifest.json | sed -n $PATTERN )
2021-01-22 02:28:53 -08:00
[ -z $DEST ] && continue
2021-01-23 16:09:30 -08:00
DEST = /apex/$DEST
2021-01-22 02:28:53 -08:00
mkdir -p $DEST
loop_setup /apex/apex_payload.img
2020-02-08 03:26:39 -08:00
if [ ! -z $LOOPDEV ] ; then
ui_print " - Mounting $DEST "
mount -t ext4 -o ro,noatime $LOOPDEV $DEST
fi
2021-01-22 02:28:53 -08:00
rm -f /apex/apex_payload.img
2020-02-08 03:26:39 -08:00
elif [ -d $APEX ] ; then
# APEX folders, bind mount directory
2021-01-22 02:28:53 -08:00
if [ -f $APEX /apex_manifest.json ] ; then
DEST = /apex/$( sed -n $PATTERN $APEX /apex_manifest.json)
elif [ -f $APEX /apex_manifest.pb ] ; then
2021-02-20 02:49:31 -08:00
DEST = /apex/$( strings $APEX /apex_manifest.pb | head -n 1)
2021-01-22 02:28:53 -08:00
else
continue
fi
mkdir -p $DEST
2020-02-08 03:26:39 -08:00
ui_print " - Mounting $DEST "
mount -o bind $APEX $DEST
fi
2020-01-11 17:48:21 -04:00
done
export ANDROID_RUNTIME_ROOT = /apex/com.android.runtime
export ANDROID_TZDATA_ROOT = /apex/com.android.tzdata
2021-01-22 02:28:53 -08:00
export ANDROID_ART_ROOT = /apex/com.android.art
export ANDROID_I18N_ROOT = /apex/com.android.i18n
local APEXJARS = $( find /apex -name '*.jar' | sort | tr '\n' ':' )
local FWK = /system/framework
export BOOTCLASSPATH = ${ APEXJARS } \
$FWK /framework.jar:$FWK /ext.jar:$FWK /telephony-common.jar:\
$FWK /voip-common.jar:$FWK /ims-common.jar:$FWK /telephony-ext.jar
2020-01-11 17:48:21 -04:00
}
umount_apex( ) {
[ -d /apex ] || return
2021-01-22 02:28:53 -08:00
umount -l /apex
for loop in /dev/block/loop*; do
losetup -d $loop 2>/dev/null
2020-01-11 17:48:21 -04:00
done
unset ANDROID_RUNTIME_ROOT
unset ANDROID_TZDATA_ROOT
2021-01-22 02:28:53 -08:00
unset ANDROID_ART_ROOT
unset ANDROID_I18N_ROOT
2020-01-11 17:48:21 -04:00
unset BOOTCLASSPATH
}
2018-06-18 01:40:56 +08:00
get_flags( ) {
# override variables
getvar KEEPVERITY
getvar KEEPFORCEENCRYPT
2018-12-25 01:08:46 +08:00
getvar RECOVERYMODE
2018-06-18 01:40:56 +08:00
if [ -z $KEEPVERITY ] ; then
2018-08-29 00:40:14 -04:00
if $SYSTEM_ROOT ; then
KEEPVERITY = true
2019-03-03 06:35:25 -05:00
ui_print "- System-as-root, keep dm/avb-verity"
2018-08-29 00:40:14 -04:00
else
KEEPVERITY = false
fi
2018-06-18 01:40:56 +08:00
fi
2020-09-28 04:45:56 -07:00
ISENCRYPTED = false
grep ' /data ' /proc/mounts | grep -q 'dm-' && ISENCRYPTED = true
[ " $( getprop ro.crypto.state) " = "encrypted" ] && ISENCRYPTED = true
2018-06-18 01:40:56 +08:00
if [ -z $KEEPFORCEENCRYPT ] ; then
2018-10-20 17:10:35 -04:00
# No data access means unable to decrypt in recovery
2020-09-23 04:40:44 -07:00
if $ISENCRYPTED || ! $DATA ; then
2018-06-18 01:40:56 +08:00
KEEPFORCEENCRYPT = true
2019-03-03 06:35:25 -05:00
ui_print "- Encrypted data, keep forceencrypt"
2018-06-18 01:40:56 +08:00
else
KEEPFORCEENCRYPT = false
fi
fi
2018-12-25 01:08:46 +08:00
[ -z $RECOVERYMODE ] && RECOVERYMODE = false
2018-06-18 01:40:56 +08:00
}
2018-06-21 01:37:08 +08:00
find_boot_image( ) {
BOOTIMAGE =
2019-03-30 00:49:48 -04:00
if $RECOVERYMODE ; then
2020-04-21 14:56:04 -03:00
BOOTIMAGE = ` find_block recovery_ramdisk$SLOT recovery$SLOT sos`
2021-03-21 19:34:33 -03:00
elif [ ! -z $SLOT ] ; then
2018-12-24 21:36:37 +08:00
BOOTIMAGE = ` find_block ramdisk$SLOT recovery_ramdisk$SLOT boot$SLOT `
2018-06-21 01:37:08 +08:00
else
2020-04-21 14:56:04 -03:00
BOOTIMAGE = ` find_block ramdisk recovery_ramdisk kern-a android_boot kernel bootimg boot lnx boot_a`
2018-06-21 01:37:08 +08:00
fi
2018-07-03 18:28:44 +08:00
if [ -z $BOOTIMAGE ] ; then
# Lets see what fstabs tells me
2020-03-31 14:13:06 -03:00
BOOTIMAGE = ` grep -v '#' /etc/*fstab* | grep -E '/boot(img)?[^a-zA-Z]' | grep -oE '/dev/[a-zA-Z0-9_./-]*' | head -n 1`
2018-07-03 18:28:44 +08:00
fi
2018-06-21 01:37:08 +08:00
}
2018-08-10 18:59:14 +08:00
flash_image( ) {
2017-09-26 20:21:43 +08:00
case " $1 " in
2021-01-22 02:28:53 -08:00
*.gz) CMD1 = " gzip -d < ' $1 ' 2>/dev/null " ; ;
2019-02-11 17:14:07 -05:00
*) CMD1 = " cat ' $1 ' " ; ;
2017-09-26 20:21:43 +08:00
esac
2018-02-10 03:34:13 +08:00
if $BOOTSIGNED ; then
2019-02-11 17:14:07 -05:00
CMD2 = " $BOOTSIGNER -sign "
2019-11-02 00:26:53 -03:00
ui_print "- Sign image with verity keys"
2018-02-10 03:34:13 +08:00
else
2019-02-11 17:14:07 -05:00
CMD2 = "cat -"
2018-08-10 18:59:14 +08:00
fi
if [ -b " $2 " ] ; then
2020-12-19 14:12:12 -08:00
local img_sz = $( stat -c '%s' " $1 " )
local blk_sz = $( blockdev --getsize64 " $2 " )
[ " $img_sz " -gt " $blk_sz " ] && return 1
blockdev --setrw " $2 "
local blk_ro = $( blockdev --getro " $2 " )
[ " $blk_ro " -eq 1 ] && return 2
eval " $CMD1 " | eval " $CMD2 " | cat - /dev/zero > " $2 " 2>/dev/null
2020-03-11 16:57:52 -03:00
elif [ -c " $2 " ] ; then
2020-06-01 02:08:13 -07:00
flash_eraseall " $2 " >& 2
2020-12-19 14:12:12 -08:00
eval " $CMD1 " | eval " $CMD2 " | nandwrite -p " $2 " - >& 2
2018-08-10 18:59:14 +08:00
else
2020-03-11 16:57:52 -03:00
ui_print "- Not block or char device, storing image"
2020-12-19 14:12:12 -08:00
eval " $CMD1 " | eval " $CMD2 " > " $2 " 2>/dev/null
2018-02-10 03:34:13 +08:00
fi
2018-08-11 15:56:12 +08:00
return 0
2017-09-06 16:13:23 +08:00
}
2019-12-27 17:53:27 +08:00
# Common installation script for flash_script.sh and addon.d.sh
2020-01-01 14:02:44 +08:00
install_magisk( ) {
2019-11-02 00:26:08 -03:00
cd $MAGISKBIN
2021-04-09 21:29:42 -07:00
if [ ! -c $BOOTIMAGE ] ; then
2020-04-20 22:12:14 -07:00
eval $BOOTSIGNER -verify < $BOOTIMAGE && BOOTSIGNED = true
$BOOTSIGNED && ui_print "- Boot image is signed with AVB 1.0"
fi
2019-11-02 22:50:33 -03:00
2019-11-02 00:26:08 -03:00
# Source the boot patcher
2020-01-01 14:02:44 +08:00
SOURCEDMODE = true
2019-11-02 00:26:08 -03:00
. ./boot_patch.sh " $BOOTIMAGE "
ui_print "- Flashing new boot image"
2020-12-19 14:12:12 -08:00
flash_image new-boot.img " $BOOTIMAGE "
case $? in
1)
abort "! Insufficient partition size"
; ;
2)
abort " ! $BOOTIMAGE is read only "
; ;
esac
2019-11-02 00:26:08 -03:00
./magiskboot cleanup
rm -f new-boot.img
2020-01-01 14:02:44 +08:00
run_migrations
2019-11-02 00:26:08 -03:00
}
2017-09-06 16:13:23 +08:00
sign_chromeos( ) {
2017-10-07 22:08:10 +08:00
ui_print "- Signing ChromeOS boot image"
2017-09-06 16:13:23 +08:00
2017-10-07 22:08:10 +08:00
echo > empty
2018-05-06 01:48:24 +08:00
./chromeos/futility vbutil_kernel --pack new-boot.img.signed \
2017-09-06 16:13:23 +08:00
--keyblock ./chromeos/kernel.keyblock --signprivate ./chromeos/kernel_data_key.vbprivk \
--version 1 --vmlinuz new-boot.img --config empty --arch arm --bootloader empty --flags 0x1
rm -f empty new-boot.img
mv new-boot.img.signed new-boot.img
}
2017-06-19 00:15:44 +08:00
remove_system_su( ) {
if [ -f /system/bin/su -o -f /system/xbin/su ] && [ ! -f /su/bin/su ] ; then
2018-08-28 22:03:12 -04:00
ui_print "- Removing system installed root"
2020-04-20 01:20:19 -03:00
blockdev --setrw /dev/block/mapper/system$SLOT 2>/dev/null
2017-06-19 00:15:44 +08:00
mount -o rw,remount /system
# SuperSU
if [ -e /system/bin/.ext/.su ] ; then
mv -f /system/bin/app_process32_original /system/bin/app_process32 2>/dev/null
mv -f /system/bin/app_process64_original /system/bin/app_process64 2>/dev/null
mv -f /system/bin/install-recovery_original.sh /system/bin/install-recovery.sh 2>/dev/null
cd /system/bin
if [ -e app_process64 ] ; then
ln -sf app_process64 app_process
2019-02-12 12:18:33 +05:30
elif [ -e app_process32 ] ; then
2017-06-19 00:15:44 +08:00
ln -sf app_process32 app_process
fi
fi
rm -rf /system/.pin /system/bin/.ext /system/etc/.installed_su_daemon /system/etc/.has_su_daemon \
/system/xbin/daemonsu /system/xbin/su /system/xbin/sugote /system/xbin/sugote-mksh /system/xbin/supolicy \
/system/bin/app_process_init /system/bin/su /cache/su /system/lib/libsupol.so /system/lib64/libsupol.so \
/system/su.d /system/etc/install-recovery.sh /system/etc/init.d/99SuperSUDaemon /cache/install-recovery.sh \
/system/.supersu /cache/.supersu /data/.supersu \
2020-01-11 17:48:21 -04:00
/system/app/Superuser.apk /system/app/SuperSU /cache/Superuser.apk
elif [ -f /cache/su.img -o -f /data/su.img -o -d /data/adb/su -o -d /data/su ] ; then
ui_print "- Removing systemless installed root"
umount -l /su 2>/dev/null
rm -rf /cache/su.img /data/su.img /data/adb/su /data/adb/suhide /data/su /cache/.supersu /data/.supersu \
/cache/supersu_install /data/supersu_install
2017-06-19 00:15:44 +08:00
fi
}
2017-07-02 21:36:09 +08:00
api_level_arch_detect( ) {
2021-04-06 03:56:39 -07:00
API = $( grep_get_prop ro.build.version.sdk)
2021-05-13 00:21:04 -07:00
ABI = $( grep_get_prop ro.product.cpu.abi)
if [ " $ABI " = "x86" ] ; then
ARCH = x86
ABI32 = x86
IS64BIT = false
elif [ " $ABI " = "arm64-v8a" ] ; then
ARCH = arm64
ABI32 = armeabi-v7a
IS64BIT = true
elif [ " $ABI " = "x86_64" ] ; then
ARCH = x64
ABI32 = x86
IS64BIT = true
else
ARCH = arm
ABI = armeabi-v7a
ABI32 = armeabi-v7a
IS64BIT = false
fi
2017-07-02 21:36:09 +08:00
}
2018-06-26 22:41:03 +08:00
check_data( ) {
DATA = false
DATA_DE = false
if grep ' /data ' /proc/mounts | grep -vq 'tmpfs' ; then
# Test if data is writable
touch /data/.rw && rm /data/.rw && DATA = true
2021-03-14 00:32:30 +08:00
# Test if data is decrypted
2018-06-26 22:41:03 +08:00
$DATA && [ -d /data/adb ] && touch /data/adb/.rw && rm /data/adb/.rw && DATA_DE = true
2020-12-09 20:11:23 +08:00
$DATA_DE && [ -d /data/adb/magisk ] || mkdir /data/adb/magisk || DATA_DE = false
2018-06-26 22:41:03 +08:00
fi
2020-11-29 20:35:34 -04:00
NVBASE = /data
$DATA || NVBASE = /cache/data_adb
2019-02-11 17:14:07 -05:00
$DATA_DE && NVBASE = /data/adb
resolve_vars
2018-06-26 22:41:03 +08:00
}
2021-03-21 19:25:56 -03:00
find_magisk_apk( ) {
2020-11-29 20:48:29 -04:00
local DBAPK
2019-11-02 00:26:08 -03:00
[ -z $APK ] && APK = /data/adb/magisk.apk
2019-02-11 17:14:07 -05:00
[ -f $APK ] || APK = /data/magisk/magisk.apk
[ -f $APK ] || APK = /data/app/com.topjohnwu.magisk*/*.apk
2021-04-22 12:49:03 +02:00
[ -f $APK ] || APK = /data/app/*/com.topjohnwu.magisk*/*.apk
2019-02-11 17:14:07 -05:00
if [ ! -f $APK ] ; then
2020-11-29 20:48:29 -04:00
DBAPK = $( magisk --sqlite "SELECT value FROM strings WHERE key='requester'" 2>/dev/null | cut -d= -f2)
2021-04-22 12:55:15 +02:00
[ -z $DBAPK ] && DBAPK = $( strings /data/adb/magisk.db | grep -oE 'requester..*' | cut -c10-)
2019-11-02 00:26:08 -03:00
[ -z $DBAPK ] || APK = /data/user_de/*/$DBAPK /dyn/*.apk
2019-11-02 00:41:51 -04:00
[ -f $APK ] || [ -z $DBAPK ] || APK = /data/app/$DBAPK */*.apk
2021-04-22 12:49:03 +02:00
[ -f $APK ] || [ -z $DBAPK ] || APK = /data/app/*/$DBAPK */*.apk
2017-08-12 16:44:58 +08:00
fi
2021-03-21 19:25:56 -03:00
[ -f $APK ] || ui_print "! Unable to detect Magisk app APK for BootSigner"
2017-07-02 21:36:09 +08:00
}
2020-01-01 14:02:44 +08:00
run_migrations( ) {
local LOCSHA1
local TARGET
# Legacy app installation
local BACKUP = /data/adb/magisk/stock_boot*.gz
if [ -f $BACKUP ] ; then
cp $BACKUP /data
rm -f $BACKUP
fi
# Legacy backup
for gz in /data/stock_boot*.gz; do
[ -f $gz ] || break
LOCSHA1 = ` basename $gz | sed -e 's/stock_boot_//' -e 's/.img.gz//' `
[ -z $LOCSHA1 ] && break
mkdir /data/magisk_backup_${ LOCSHA1 } 2>/dev/null
mv $gz /data/magisk_backup_${ LOCSHA1 } /boot.img.gz
done
# Stock backups
LOCSHA1 = $SHA1
2020-04-14 12:24:02 +08:00
for name in boot dtb dtbo dtbs; do
2020-01-01 14:02:44 +08:00
BACKUP = /data/adb/magisk/stock_${ name } .img
[ -f $BACKUP ] || continue
if [ $name = 'boot' ] ; then
LOCSHA1 = ` $MAGISKBIN /magiskboot sha1 $BACKUP `
mkdir /data/magisk_backup_${ LOCSHA1 } 2>/dev/null
fi
TARGET = /data/magisk_backup_${ LOCSHA1 } /${ name } .img
cp $BACKUP $TARGET
rm -f $BACKUP
gzip -9f $TARGET
done
}
2020-11-02 23:20:38 -08:00
copy_sepolicy_rules( ) {
# Remove all existing rule folders
2020-11-13 02:31:54 -08:00
rm -rf /data/unencrypted/magisk /cache/magisk /metadata/magisk /persist/magisk /mnt/vendor/persist/magisk
2020-11-02 23:20:38 -08:00
# Find current active RULESDIR
local RULESDIR
local active_dir = $( magisk --path) /.magisk/mirror/sepolicy.rules
2021-03-18 15:08:44 +08:00
if [ -L $active_dir ] ; then
2021-03-28 04:43:10 -07:00
RULESDIR = $( readlink $active_dir )
2021-04-27 23:28:31 +08:00
[ " ${ RULESDIR : 0 : 1 } " != "/" ] && RULESDIR = " $( magisk --path) /.magisk/mirror/ $RULESDIR "
2021-01-15 02:23:53 -08:00
elif [ -d /data/unencrypted ] && ! grep ' /data ' /proc/mounts | grep -qE 'dm-|f2fs' ; then
2020-11-02 23:20:38 -08:00
RULESDIR = /data/unencrypted/magisk
elif grep -q ' /cache ' /proc/mounts; then
RULESDIR = /cache/magisk
elif grep -q ' /metadata ' /proc/mounts; then
RULESDIR = /metadata/magisk
elif grep -q ' /persist ' /proc/mounts; then
RULESDIR = /persist/magisk
elif grep -q ' /mnt/vendor/persist ' /proc/mounts; then
RULESDIR = /mnt/vendor/persist/magisk
else
2021-07-27 17:37:22 +08:00
ui_print "- Unable to find sepolicy rules dir"
return 1
fi
if [ -d ${ RULESDIR %/magisk } ] ; then
ui_print " - Sepolicy rules dir is ${ RULESDIR %/magisk } "
else
ui_print " - Sepolicy rules dir ${ RULESDIR %/magisk } not found "
return 1
2020-11-02 23:20:38 -08:00
fi
# Copy all enabled sepolicy.rule
for r in /data/adb/modules*/*/sepolicy.rule; do
[ -f " $r " ] || continue
local MODDIR = ${ r %/* }
[ -f $MODDIR /disable ] && continue
[ -f $MODDIR /remove ] && continue
local MODNAME = ${ MODDIR ##*/ }
mkdir -p $RULESDIR /$MODNAME
cp -f $r $RULESDIR /$MODNAME /sepolicy.rule
done
}
2019-02-11 17:14:07 -05:00
#################
# Module Related
#################
2017-07-10 00:17:34 +08:00
set_perm( ) {
2018-02-10 03:34:13 +08:00
chown $2 :$3 $1 || return 1
chmod $4 $1 || return 1
2021-10-20 17:01:51 -03:00
local CON = $5
2019-02-12 02:14:57 -05:00
[ -z $CON ] && CON = u:object_r:system_file:s0
chcon $CON $1 || return 1
2017-07-10 00:17:34 +08:00
}
set_perm_recursive( ) {
find $1 -type d 2>/dev/null | while read dir; do
set_perm $dir $2 $3 $4 $6
done
2017-07-31 03:03:52 +08:00
find $1 -type f -o -type l 2>/dev/null | while read file; do
2017-07-10 00:17:34 +08:00
set_perm $file $2 $3 $5 $6
done
}
mktouch( ) {
2017-07-31 03:03:52 +08:00
mkdir -p ${ 1 %/* } 2>/dev/null
[ -z $2 ] && touch $1 || echo $2 > $1
2017-07-10 00:17:34 +08:00
chmod 644 $1
}
request_size_check( ) {
2019-02-12 02:14:57 -05:00
reqSizeM = ` du -ms " $1 " | cut -f1`
2017-07-10 00:17:34 +08:00
}
2017-08-12 23:15:39 +08:00
request_zip_size_check( ) {
2018-06-22 06:18:06 +08:00
reqSizeM = ` unzip -l " $1 " | tail -n 1 | awk '{ print int(($1 - 1) / 1048576 + 1) }' `
2017-08-12 23:15:39 +08:00
}
2019-02-24 02:11:11 -05:00
boot_actions( ) { return ; }
2019-02-11 17:14:07 -05:00
2020-03-15 00:22:40 -07:00
# Require ZIPFILE to be set
is_legacy_script( ) {
unzip -l " $ZIPFILE " install.sh | grep -q install.sh
return $?
}
# Require OUTFD, ZIPFILE to be set
install_module( ) {
2020-03-19 03:53:01 -07:00
rm -rf $TMPDIR
mkdir -p $TMPDIR
2021-01-24 20:58:30 -08:00
cd $TMPDIR
2020-03-19 03:53:01 -07:00
2020-03-15 00:22:40 -07:00
setup_flashable
mount_partitions
api_level_arch_detect
# Setup busybox and binaries
2020-11-29 20:35:34 -04:00
if $BOOTMODE ; then
boot_actions
else
recovery_actions
fi
2020-03-15 00:22:40 -07:00
# Extract prop file
unzip -o " $ZIPFILE " module.prop -d $TMPDIR >& 2
[ ! -f $TMPDIR /module.prop ] && abort "! Unable to extract zip file!"
2020-11-29 20:35:34 -04:00
local MODDIRNAME = modules
$BOOTMODE && MODDIRNAME = modules_update
2020-03-22 00:08:04 -07:00
local MODULEROOT = $NVBASE /$MODDIRNAME
2020-03-15 00:22:40 -07:00
MODID = ` grep_prop id $TMPDIR /module.prop`
MODNAME = ` grep_prop name $TMPDIR /module.prop`
2020-04-21 20:14:18 -03:00
MODAUTH = ` grep_prop author $TMPDIR /module.prop`
MODPATH = $MODULEROOT /$MODID
2020-03-15 00:22:40 -07:00
# Create mod paths
2020-11-02 23:20:38 -08:00
rm -rf $MODPATH
2020-03-15 00:22:40 -07:00
mkdir -p $MODPATH
if is_legacy_script; then
unzip -oj " $ZIPFILE " module.prop install.sh uninstall.sh 'common/*' -d $TMPDIR >& 2
# Load install script
. $TMPDIR /install.sh
# Callbacks
print_modname
on_install
[ -f $TMPDIR /uninstall.sh ] && cp -af $TMPDIR /uninstall.sh $MODPATH /uninstall.sh
$SKIPMOUNT && touch $MODPATH /skip_mount
$PROPFILE && cp -af $TMPDIR /system.prop $MODPATH /system.prop
cp -af $TMPDIR /module.prop $MODPATH /module.prop
$POSTFSDATA && cp -af $TMPDIR /post-fs-data.sh $MODPATH /post-fs-data.sh
$LATESTARTSERVICE && cp -af $TMPDIR /service.sh $MODPATH /service.sh
ui_print "- Setting permissions"
set_permissions
else
2020-04-21 20:14:18 -03:00
print_title " $MODNAME " " by $MODAUTH "
2020-03-15 00:22:40 -07:00
print_title "Powered by Magisk"
unzip -o " $ZIPFILE " customize.sh -d $MODPATH >& 2
if ! grep -q '^SKIPUNZIP=1$' $MODPATH /customize.sh 2>/dev/null; then
ui_print "- Extracting module files"
unzip -o " $ZIPFILE " -x 'META-INF/*' -d $MODPATH >& 2
# Default permissions
set_perm_recursive $MODPATH 0 0 0755 0644
2021-10-20 17:01:51 -03:00
set_perm_recursive $MODPATH /system/bin 0 2000 0755 0755
set_perm_recursive $MODPATH /system/xbin 0 2000 0755 0755
set_perm_recursive $MODPATH /system/system_ext/bin 0 2000 0755 0755
set_perm_recursive $MODPATH /system/vendor/bin 0 2000 0755 0755 u:object_r:vendor_file:s0
2020-03-15 00:22:40 -07:00
fi
# Load customization script
[ -f $MODPATH /customize.sh ] && . $MODPATH /customize.sh
fi
# Handle replace folders
for TARGET in $REPLACE ; do
ui_print " - Replace target: $TARGET "
mktouch $MODPATH $TARGET /.replace
done
if $BOOTMODE ; then
2021-03-21 19:25:56 -03:00
# Update info for Magisk app
2020-03-15 00:22:40 -07:00
mktouch $NVBASE /modules/$MODID /update
2021-05-26 23:19:00 +08:00
rm -rf $NVBASE /modules/$MODID /remove 2>/dev/null
rm -rf $NVBASE /modules/$MODID /disable 2>/dev/null
2020-03-15 00:22:40 -07:00
cp -af $MODPATH /module.prop $NVBASE /modules/$MODID /module.prop
fi
# Copy over custom sepolicy rules
2020-11-02 23:20:38 -08:00
if [ -f $MODPATH /sepolicy.rule ] ; then
ui_print "- Installing custom sepolicy rules"
copy_sepolicy_rules
2020-03-15 00:22:40 -07:00
fi
2021-03-21 20:36:03 -03:00
# Remove stuff that doesn't belong to modules and clean up any empty directories
2020-03-15 00:22:40 -07:00
rm -rf \
$MODPATH /system/placeholder $MODPATH /customize.sh \
2020-11-02 23:20:38 -08:00
$MODPATH /README.md $MODPATH /.git*
2021-03-21 20:36:03 -03:00
rmdir -p $MODPATH
2020-03-15 00:22:40 -07:00
cd /
$BOOTMODE || recovery_cleanup
rm -rf $TMPDIR
ui_print "- Done"
}
2019-12-27 17:53:27 +08:00
##########
# Presets
##########
# Detect whether in boot mode
[ -z $BOOTMODE ] && ps | grep zygote | grep -qv grep && BOOTMODE = true
[ -z $BOOTMODE ] && ps -A 2>/dev/null | grep zygote | grep -qv grep && BOOTMODE = true
[ -z $BOOTMODE ] && BOOTMODE = false
NVBASE = /data/adb
2020-03-22 00:08:04 -07:00
TMPDIR = /dev/tmp
2019-12-27 17:53:27 +08:00
# Bootsigner related stuff
2021-01-26 07:27:21 -08:00
BOOTSIGNERCLASS = com.topjohnwu.signing.SignBoot
2020-03-22 00:08:04 -07:00
BOOTSIGNER = '/system/bin/dalvikvm -Xnoimage-dex2oat -cp $APK $BOOTSIGNERCLASS'
2019-12-27 17:53:27 +08:00
BOOTSIGNED = false
2019-02-11 17:14:07 -05:00
resolve_vars