Repo created
This commit is contained in:
parent
d327c31227
commit
0b2aca0925
638 changed files with 76461 additions and 0 deletions
168
scripts/addon.d.sh
Normal file
168
scripts/addon.d.sh
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
#!/sbin/sh
|
||||
# ADDOND_VERSION=2
|
||||
########################################################
|
||||
#
|
||||
# Magisk Survival Script for ROMs with addon.d support
|
||||
# by topjohnwu and osm0sis
|
||||
#
|
||||
########################################################
|
||||
|
||||
trampoline() {
|
||||
mount /data 2>/dev/null
|
||||
if [ -f $MAGISKBIN/addon.d.sh ]; then
|
||||
exec sh $MAGISKBIN/addon.d.sh "$@"
|
||||
exit $?
|
||||
elif [ "$1" = post-restore ]; then
|
||||
BOOTMODE=false
|
||||
ps | grep zygote | grep -v grep >/dev/null && BOOTMODE=true
|
||||
$BOOTMODE || ps -A 2>/dev/null | grep zygote | grep -v grep >/dev/null && BOOTMODE=true
|
||||
|
||||
if ! $BOOTMODE; then
|
||||
# update-binary|updater <RECOVERY_API_VERSION> <OUTFD> <ZIPFILE>
|
||||
OUTFD=$(ps | grep -v 'grep' | grep -oE 'update(.*) 3 [0-9]+' | cut -d" " -f3)
|
||||
[ -z $OUTFD ] && OUTFD=$(ps -Af | grep -v 'grep' | grep -oE 'update(.*) 3 [0-9]+' | cut -d" " -f3)
|
||||
# update_engine_sideload --payload=file://<ZIPFILE> --offset=<OFFSET> --headers=<HEADERS> --status_fd=<OUTFD>
|
||||
[ -z $OUTFD ] && OUTFD=$(ps | grep -v 'grep' | grep -oE 'status_fd=[0-9]+' | cut -d= -f2)
|
||||
[ -z $OUTFD ] && OUTFD=$(ps -Af | grep -v 'grep' | grep -oE 'status_fd=[0-9]+' | cut -d= -f2)
|
||||
fi
|
||||
ui_print() {
|
||||
if $BOOTMODE; then
|
||||
log -t Magisk -- "$1"
|
||||
else
|
||||
echo -e "ui_print $1\nui_print" >> /proc/self/fd/$OUTFD
|
||||
fi
|
||||
}
|
||||
|
||||
ui_print "***********************"
|
||||
ui_print " Magisk addon.d failed"
|
||||
ui_print "***********************"
|
||||
ui_print "! Cannot find Magisk binaries - was data wiped or not decrypted?"
|
||||
ui_print "! Reflash OTA from decrypted recovery or reflash Magisk"
|
||||
fi
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Always use the script in /data
|
||||
MAGISKBIN=/data/adb/magisk
|
||||
[ "$0" = $MAGISKBIN/addon.d.sh ] || trampoline "$@"
|
||||
|
||||
V1_FUNCS=/tmp/backuptool.functions
|
||||
V2_FUNCS=/postinstall/tmp/backuptool.functions
|
||||
|
||||
if [ -f $V1_FUNCS ]; then
|
||||
. $V1_FUNCS
|
||||
backuptool_ab=false
|
||||
elif [ -f $V2_FUNCS ]; then
|
||||
. $V2_FUNCS
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
|
||||
initialize() {
|
||||
# Load utility functions
|
||||
. $MAGISKBIN/util_functions.sh
|
||||
|
||||
if $BOOTMODE; then
|
||||
# Override ui_print when booted
|
||||
ui_print() { log -t Magisk -- "$1"; }
|
||||
fi
|
||||
OUTFD=
|
||||
setup_flashable
|
||||
}
|
||||
|
||||
main() {
|
||||
if ! $backuptool_ab; then
|
||||
# Restore PREINITDEVICE from previous A-only partition
|
||||
if [ -f config.orig ]; then
|
||||
PREINITDEVICE=$(grep_prop PREINITDEVICE config.orig)
|
||||
rm config.orig
|
||||
fi
|
||||
|
||||
# Wait for post addon.d-v1 processes to finish
|
||||
sleep 5
|
||||
fi
|
||||
|
||||
# Ensure we aren't in /tmp/addon.d anymore (since it's been deleted by addon.d)
|
||||
mkdir -p $TMPDIR
|
||||
cd $TMPDIR
|
||||
|
||||
if echo $MAGISK_VER | grep -q '\.'; then
|
||||
PRETTY_VER=$MAGISK_VER
|
||||
else
|
||||
PRETTY_VER="$MAGISK_VER($MAGISK_VER_CODE)"
|
||||
fi
|
||||
print_title "Magisk $PRETTY_VER addon.d"
|
||||
|
||||
mount_partitions
|
||||
check_data
|
||||
get_flags
|
||||
|
||||
if $backuptool_ab; then
|
||||
# Swap the slot for addon.d-v2
|
||||
if [ ! -z $SLOT ]; then
|
||||
case $SLOT in
|
||||
_a) SLOT=_b;;
|
||||
_b) SLOT=_a;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
|
||||
find_boot_image
|
||||
[ -z $BOOTIMAGE ] && abort "! Unable to detect target image"
|
||||
ui_print "- Target image: $BOOTIMAGE"
|
||||
|
||||
api_level_arch_detect
|
||||
ui_print "- Device platform: $ABI"
|
||||
|
||||
remove_system_su
|
||||
install_magisk
|
||||
|
||||
# Cleanups
|
||||
cd /
|
||||
$BOOTMODE || recovery_cleanup
|
||||
rm -rf $TMPDIR
|
||||
|
||||
ui_print "- Done"
|
||||
exit 0
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
backup)
|
||||
# Stub
|
||||
;;
|
||||
restore)
|
||||
# Stub
|
||||
;;
|
||||
pre-backup)
|
||||
# Back up PREINITDEVICE from existing partition before OTA on A-only devices
|
||||
if ! $backuptool_ab; then
|
||||
initialize
|
||||
RECOVERYMODE=false
|
||||
find_boot_image
|
||||
$MAGISKBIN/magiskboot unpack "$BOOTIMAGE"
|
||||
$MAGISKBIN/magiskboot cpio ramdisk.cpio "extract .backup/.magisk config.orig"
|
||||
$MAGISKBIN/magiskboot cleanup
|
||||
fi
|
||||
;;
|
||||
post-backup)
|
||||
# Stub
|
||||
;;
|
||||
pre-restore)
|
||||
# Stub
|
||||
;;
|
||||
post-restore)
|
||||
initialize
|
||||
if $backuptool_ab; then
|
||||
su=sh
|
||||
$BOOTMODE && su=su
|
||||
exec $su -c "sh $0 addond-v2"
|
||||
else
|
||||
# Run in background, hack for addon.d-v1
|
||||
(main) &
|
||||
fi
|
||||
;;
|
||||
addond-v2)
|
||||
initialize
|
||||
main
|
||||
;;
|
||||
esac
|
||||
250
scripts/app_functions.sh
Normal file
250
scripts/app_functions.sh
Normal file
|
|
@ -0,0 +1,250 @@
|
|||
##################################
|
||||
# Magisk app internal scripts
|
||||
##################################
|
||||
|
||||
# $1 = delay
|
||||
# $2 = command
|
||||
run_delay() {
|
||||
(sleep $1; $2)&
|
||||
}
|
||||
|
||||
# $1 = version string
|
||||
# $2 = version code
|
||||
env_check() {
|
||||
for file in busybox magiskboot magiskinit util_functions.sh boot_patch.sh; do
|
||||
[ -f "$MAGISKBIN/$file" ] || return 1
|
||||
done
|
||||
if [ "$2" -ge 25000 ]; then
|
||||
[ -f "$MAGISKBIN/magiskpolicy" ] || return 1
|
||||
fi
|
||||
if [ "$2" -ge 25210 ]; then
|
||||
[ -b "$MAGISKTMP/.magisk/device/preinit" ] || [ -b "$MAGISKTMP/.magisk/block/preinit" ] || return 2
|
||||
fi
|
||||
grep -xqF "MAGISK_VER='$1'" "$MAGISKBIN/util_functions.sh" || return 3
|
||||
grep -xqF "MAGISK_VER_CODE=$2" "$MAGISKBIN/util_functions.sh" || return 3
|
||||
return 0
|
||||
}
|
||||
|
||||
# $1 = dir to copy
|
||||
# $2 = destination (optional)
|
||||
cp_readlink() {
|
||||
if [ -z $2 ]; then
|
||||
cd $1
|
||||
else
|
||||
cp -af $1/. $2
|
||||
cd $2
|
||||
fi
|
||||
for file in *; do
|
||||
if [ -L $file ]; then
|
||||
local full=$(readlink -f $file)
|
||||
rm $file
|
||||
cp -af $full $file
|
||||
fi
|
||||
done
|
||||
chmod -R 755 .
|
||||
cd /
|
||||
}
|
||||
|
||||
# $1 = install dir
|
||||
fix_env() {
|
||||
# Cleanup and make dirs
|
||||
rm -rf $MAGISKBIN/*
|
||||
mkdir -p $MAGISKBIN 2>/dev/null
|
||||
chmod 700 /data/adb
|
||||
cp_readlink $1 $MAGISKBIN
|
||||
rm -rf $1
|
||||
chown -R 0:0 $MAGISKBIN
|
||||
}
|
||||
|
||||
# $1 = install dir
|
||||
# $2 = boot partition
|
||||
direct_install() {
|
||||
echo "- Flashing new boot image"
|
||||
flash_image $1/new-boot.img $2
|
||||
case $? in
|
||||
1)
|
||||
echo "! Insufficient partition size"
|
||||
return 1
|
||||
;;
|
||||
2)
|
||||
echo "! $2 is read only"
|
||||
return 2
|
||||
;;
|
||||
esac
|
||||
|
||||
rm -f $1/new-boot.img
|
||||
fix_env $1
|
||||
run_migrations
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# $1 = uninstaller zip
|
||||
run_uninstaller() {
|
||||
rm -rf /dev/tmp
|
||||
mkdir -p /dev/tmp/install
|
||||
unzip -o "$1" "assets/*" "lib/*" -d /dev/tmp/install
|
||||
INSTALLER=/dev/tmp/install sh /dev/tmp/install/assets/uninstaller.sh dummy 1 "$1"
|
||||
}
|
||||
|
||||
# $1 = boot partition
|
||||
restore_imgs() {
|
||||
local SHA1=$(grep_prop SHA1 $MAGISKTMP/.magisk/config)
|
||||
local BACKUPDIR=/data/magisk_backup_$SHA1
|
||||
[ -d $BACKUPDIR ] || return 1
|
||||
[ -f $BACKUPDIR/boot.img.gz ] || return 1
|
||||
flash_image $BACKUPDIR/boot.img.gz $1
|
||||
}
|
||||
|
||||
# $1 = path to bootctl executable
|
||||
post_ota() {
|
||||
cd /data/adb
|
||||
cp -f $1 bootctl
|
||||
rm -f $1
|
||||
chmod 755 bootctl
|
||||
if ! ./bootctl hal-info; then
|
||||
rm -f bootctl
|
||||
return
|
||||
fi
|
||||
SLOT_NUM=0
|
||||
[ $(./bootctl get-current-slot) -eq 0 ] && SLOT_NUM=1
|
||||
./bootctl set-active-boot-slot $SLOT_NUM
|
||||
cat << EOF > post-fs-data.d/post_ota.sh
|
||||
/data/adb/bootctl mark-boot-successful
|
||||
rm -f /data/adb/bootctl
|
||||
rm -f /data/adb/post-fs-data.d/post_ota.sh
|
||||
EOF
|
||||
chmod 755 post-fs-data.d/post_ota.sh
|
||||
cd /
|
||||
}
|
||||
|
||||
# $1 = APK
|
||||
# $2 = package name
|
||||
adb_pm_install() {
|
||||
local tmp=/data/local/tmp/temp.apk
|
||||
cp -f "$1" $tmp
|
||||
chmod 644 $tmp
|
||||
su 2000 -c pm install -g $tmp || pm install -g $tmp || su 1000 -c pm install -g $tmp
|
||||
local res=$?
|
||||
rm -f $tmp
|
||||
if [ $res = 0 ]; then
|
||||
appops set "$2" REQUEST_INSTALL_PACKAGES allow
|
||||
fi
|
||||
return $res
|
||||
}
|
||||
|
||||
check_boot_ramdisk() {
|
||||
# Create boolean ISAB
|
||||
ISAB=true
|
||||
[ -z $SLOT ] && ISAB=false
|
||||
|
||||
# If we are A/B, then we must have ramdisk
|
||||
$ISAB && return 0
|
||||
|
||||
# If we are using legacy SAR, but not A/B, assume we do not have ramdisk
|
||||
if $LEGACYSAR; then
|
||||
# Override recovery mode to true
|
||||
RECOVERYMODE=true
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
check_encryption() {
|
||||
if $ISENCRYPTED; then
|
||||
if [ $SDK_INT -lt 24 ]; then
|
||||
CRYPTOTYPE="block"
|
||||
else
|
||||
# First see what the system tells us
|
||||
CRYPTOTYPE=$(getprop ro.crypto.type)
|
||||
if [ -z $CRYPTOTYPE ]; then
|
||||
# If not mounting through device mapper, we are FBE
|
||||
if grep ' /data ' /proc/mounts | grep -qv 'dm-'; then
|
||||
CRYPTOTYPE="file"
|
||||
else
|
||||
# We are either FDE or metadata encryption (which is also FBE)
|
||||
CRYPTOTYPE="block"
|
||||
grep -q ' /metadata ' /proc/mounts && CRYPTOTYPE="file"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
else
|
||||
CRYPTOTYPE="N/A"
|
||||
fi
|
||||
}
|
||||
|
||||
printvar() {
|
||||
eval echo $1=\$$1
|
||||
}
|
||||
|
||||
run_action() {
|
||||
local MODID="$1"
|
||||
cd "/data/adb/modules/$MODID"
|
||||
sh ./action.sh
|
||||
local RES=$?
|
||||
cd /
|
||||
return $RES
|
||||
}
|
||||
|
||||
##########################
|
||||
# Non-root util_functions
|
||||
##########################
|
||||
|
||||
mount_partitions() {
|
||||
[ "$(getprop ro.build.ab_update)" = "true" ] && SLOT=$(getprop ro.boot.slot_suffix)
|
||||
# Check whether non rootfs root dir exists
|
||||
SYSTEM_AS_ROOT=false
|
||||
grep ' / ' /proc/mounts | grep -qv 'rootfs' && SYSTEM_AS_ROOT=true
|
||||
|
||||
LEGACYSAR=false
|
||||
grep ' / ' /proc/mounts | grep -q '/dev/root' && LEGACYSAR=true
|
||||
}
|
||||
|
||||
get_flags() {
|
||||
KEEPVERITY=$SYSTEM_AS_ROOT
|
||||
ISENCRYPTED=false
|
||||
[ "$(getprop ro.crypto.state)" = "encrypted" ] && ISENCRYPTED=true
|
||||
KEEPFORCEENCRYPT=$ISENCRYPTED
|
||||
if [ -n "$(getprop ro.boot.vbmeta.device)" -o -n "$(getprop ro.boot.vbmeta.size)" ]; then
|
||||
PATCHVBMETAFLAG=false
|
||||
elif getprop ro.product.ab_ota_partitions | grep -wq vbmeta; then
|
||||
PATCHVBMETAFLAG=false
|
||||
else
|
||||
PATCHVBMETAFLAG=true
|
||||
fi
|
||||
[ -z $RECOVERYMODE ] && RECOVERYMODE=false
|
||||
[ -z $VENDORBOOT ] && VENDORBOOT=false
|
||||
}
|
||||
|
||||
run_migrations() { return; }
|
||||
|
||||
grep_prop() { return; }
|
||||
|
||||
#############
|
||||
# Initialize
|
||||
#############
|
||||
|
||||
app_init() {
|
||||
mount_partitions >/dev/null
|
||||
RAMDISKEXIST=false
|
||||
check_boot_ramdisk && RAMDISKEXIST=true
|
||||
get_flags >/dev/null
|
||||
run_migrations >/dev/null
|
||||
check_encryption
|
||||
|
||||
# Dump variables
|
||||
printvar SLOT
|
||||
printvar SYSTEM_AS_ROOT
|
||||
printvar RAMDISKEXIST
|
||||
printvar ISAB
|
||||
printvar CRYPTOTYPE
|
||||
printvar PATCHVBMETAFLAG
|
||||
printvar LEGACYSAR
|
||||
printvar RECOVERYMODE
|
||||
printvar KEEPVERITY
|
||||
printvar KEEPFORCEENCRYPT
|
||||
printvar VENDORBOOT
|
||||
}
|
||||
|
||||
export BOOTMODE=true
|
||||
260
scripts/avd.sh
Executable file
260
scripts/avd.sh
Executable file
|
|
@ -0,0 +1,260 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
shopt -s extglob
|
||||
. scripts/test_common.sh
|
||||
|
||||
emu_args_base="-no-window -no-audio -no-boot-anim -gpu swiftshader_indirect -read-only -no-snapshot -cores $core_count"
|
||||
log_args="-show-kernel -logcat '' -logcat-output logcat.log"
|
||||
emu_args=
|
||||
emu_pid=
|
||||
|
||||
atd_min_api=30
|
||||
atd_max_api=36
|
||||
huge_ram_min_api=26
|
||||
|
||||
case $(uname -m) in
|
||||
'arm64'|'aarch64')
|
||||
if [ -n "$FORCE_32_BIT" ]; then
|
||||
echo "! ARM32 is not supported"
|
||||
exit 1
|
||||
fi
|
||||
arch=arm64-v8a
|
||||
;;
|
||||
*)
|
||||
if [ -n "$FORCE_32_BIT" ]; then
|
||||
arch=x86
|
||||
else
|
||||
arch=x86_64
|
||||
fi
|
||||
|
||||
;;
|
||||
esac
|
||||
|
||||
cleanup() {
|
||||
pkill -INT -P $$
|
||||
wait
|
||||
trap - EXIT
|
||||
rm -f magisk_*.img
|
||||
"$avd" delete avd -n test
|
||||
exit 1
|
||||
}
|
||||
|
||||
test_error() {
|
||||
print_error "! An error occurred"
|
||||
cleanup
|
||||
}
|
||||
|
||||
wait_for_boot() {
|
||||
set -e
|
||||
adb wait-for-device
|
||||
while true; do
|
||||
local result="$(adb exec-out getprop sys.boot_completed)"
|
||||
if [ $? -ne 0 ]; then
|
||||
exit 1
|
||||
elif [ "$result" = "1" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
}
|
||||
|
||||
wait_emu() {
|
||||
local which_pid
|
||||
|
||||
timeout $boot_timeout bash -c wait_for_boot &
|
||||
local wait_pid=$!
|
||||
|
||||
# Handle the case when emulator dies earlier than timeout
|
||||
wait -p which_pid -n $emu_pid $wait_pid
|
||||
[ $which_pid -eq $wait_pid ]
|
||||
}
|
||||
|
||||
dump_vars() {
|
||||
local val
|
||||
for name in $@; do
|
||||
eval val=\$$name
|
||||
echo $name=\"$val\"\;
|
||||
done
|
||||
}
|
||||
|
||||
resolve_vars() {
|
||||
local arg_list="$1"
|
||||
local ver=$2
|
||||
local type=$3
|
||||
|
||||
# Determine API level
|
||||
local api
|
||||
case $ver in
|
||||
+([0-9\.])) api=$ver ;;
|
||||
TiramisuPrivacySandbox) api=33 ;;
|
||||
UpsideDownCakePrivacySandbox) api=34 ;;
|
||||
VanillaIceCream) api=35 ;;
|
||||
Baklava) api=36 ;;
|
||||
*CANARY) api=10000 ;;
|
||||
*)
|
||||
print_error "! Unknown system image version '$ver'"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Determine default image type
|
||||
if [ -z $type ]; then
|
||||
if [ $(bc <<< "$api >= $atd_min_api && $api <= $atd_max_api") = 1 ]; then
|
||||
# Use the lightweight ATD images if possible
|
||||
type='aosp_atd'
|
||||
elif [ $(bc <<< "$api > $atd_max_api") = 1 ]; then
|
||||
# Preview/beta release, no AOSP version available
|
||||
type='google_apis'
|
||||
else
|
||||
type='default'
|
||||
fi
|
||||
fi
|
||||
|
||||
# Old Linux kernels will not boot with memory larger than 3GB
|
||||
local memory
|
||||
if [ $(bc <<< "$api < $huge_ram_min_api") = 1 ]; then
|
||||
memory=3072
|
||||
else
|
||||
memory=8192
|
||||
fi
|
||||
|
||||
emu_args="$emu_args_base -memory $memory"
|
||||
|
||||
# System image variable and paths
|
||||
local avd_pkg="system-images;android-$ver;$type;$arch"
|
||||
local sys_img_dir="$ANDROID_HOME/system-images/android-$ver/$type/$arch"
|
||||
local ramdisk="$sys_img_dir/ramdisk.img"
|
||||
|
||||
# Dump variables to output
|
||||
dump_vars $arg_list
|
||||
}
|
||||
|
||||
dl_emu() {
|
||||
local avd_pkg=$1
|
||||
yes | "$sdk" --licenses > /dev/null 2>&1
|
||||
"$sdk" --channel=3 platform-tools emulator $avd_pkg
|
||||
}
|
||||
|
||||
setup_emu() {
|
||||
local avd_pkg=$1
|
||||
dl_emu $avd_pkg
|
||||
echo no | "$avd" create avd -f -n test -k $avd_pkg
|
||||
}
|
||||
|
||||
test_emu() {
|
||||
local variant=$1
|
||||
|
||||
local magisk_args="-ramdisk magisk_${variant}.img -feature -SystemAsRoot"
|
||||
|
||||
if [ -n "$AVD_TEST_LOG" ]; then
|
||||
rm -f logcat.log
|
||||
"$emu" @test $emu_args $log_args $magisk_args > kernel.log 2>&1 &
|
||||
else
|
||||
"$emu" @test $emu_args $magisk_args > /dev/null 2>&1 &
|
||||
fi
|
||||
|
||||
emu_pid=$!
|
||||
wait_emu
|
||||
|
||||
run_setup $variant
|
||||
|
||||
adb reboot
|
||||
wait_emu
|
||||
|
||||
run_tests
|
||||
|
||||
kill -INT $emu_pid
|
||||
wait $emu_pid
|
||||
}
|
||||
|
||||
test_main() {
|
||||
local avd_pkg ramdisk vars
|
||||
vars=$(resolve_vars "emu_args avd_pkg ramdisk" $1 $2)
|
||||
eval $vars
|
||||
|
||||
# Specify an explicit port so that tests can run with other emulators running at the same time
|
||||
local emu_port=5682
|
||||
emu_args="$emu_args -port $emu_port"
|
||||
export ANDROID_SERIAL="emulator-$emu_port"
|
||||
|
||||
setup_emu "$avd_pkg"
|
||||
|
||||
# Restart ADB daemon just in case
|
||||
adb kill-server
|
||||
adb start-server
|
||||
|
||||
# Launch stock emulator
|
||||
print_title "* Launching $avd_pkg"
|
||||
"$emu" @test $emu_args >/dev/null 2>&1 &
|
||||
emu_pid=$!
|
||||
wait_emu
|
||||
|
||||
# Patch images
|
||||
if [ -z "$AVD_TEST_SKIP_DEBUG" ]; then
|
||||
./build.py -v avd_patch "$ramdisk" magisk_debug.img
|
||||
fi
|
||||
if [ -z "$AVD_TEST_SKIP_RELEASE" ]; then
|
||||
./build.py -vr avd_patch "$ramdisk" magisk_release.img
|
||||
fi
|
||||
|
||||
kill -INT $emu_pid
|
||||
wait $emu_pid
|
||||
|
||||
if [ -z "$AVD_TEST_SKIP_DEBUG" ]; then
|
||||
print_title "* Testing $avd_pkg (debug)"
|
||||
test_emu debug
|
||||
fi
|
||||
|
||||
if [ -z "$AVD_TEST_SKIP_RELEASE" ]; then
|
||||
print_title "* Testing $avd_pkg (release)"
|
||||
test_emu release
|
||||
fi
|
||||
|
||||
# Cleanup
|
||||
rm -f magisk_*.img
|
||||
"$avd" delete avd -n test
|
||||
}
|
||||
|
||||
run_main() {
|
||||
local avd_pkg vars
|
||||
vars=$(resolve_vars "emu_args avd_pkg" $1 $2)
|
||||
eval $vars
|
||||
setup_emu "$avd_pkg"
|
||||
print_title "* Launching $avd_pkg"
|
||||
"$emu" @test $emu_args 2>/dev/null
|
||||
}
|
||||
|
||||
dl_main() {
|
||||
local avd_pkg vars
|
||||
vars=$(resolve_vars "avd_pkg" $1 $2)
|
||||
eval $vars
|
||||
print_title "* Downloading $avd_pkg"
|
||||
dl_emu "$avd_pkg"
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
test )
|
||||
shift
|
||||
trap test_error EXIT
|
||||
export -f wait_for_boot
|
||||
set -x
|
||||
test_main "$@"
|
||||
;;
|
||||
run )
|
||||
shift
|
||||
trap cleanup EXIT
|
||||
run_main "$@"
|
||||
;;
|
||||
dl )
|
||||
shift
|
||||
dl_main "$@"
|
||||
;;
|
||||
* )
|
||||
print_error "Unknown argument '$1'"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Exit normally, don't run through cleanup again
|
||||
trap - EXIT
|
||||
269
scripts/boot_patch.sh
Normal file
269
scripts/boot_patch.sh
Normal file
|
|
@ -0,0 +1,269 @@
|
|||
#!/system/bin/sh
|
||||
#######################################################################################
|
||||
# Magisk Boot Image Patcher
|
||||
#######################################################################################
|
||||
#
|
||||
# Usage: boot_patch.sh <bootimage>
|
||||
#
|
||||
# The following environment variables can configure the installation:
|
||||
# KEEPVERITY, KEEPFORCEENCRYPT, PATCHVBMETAFLAG, RECOVERYMODE, LEGACYSAR
|
||||
#
|
||||
# This script should be placed in a directory with the following files:
|
||||
#
|
||||
# File name Type Description
|
||||
#
|
||||
# boot_patch.sh script A script to patch boot image for Magisk.
|
||||
# (this file) The script will use files in its same
|
||||
# directory to complete the patching process.
|
||||
# util_functions.sh script A script which hosts all functions required
|
||||
# for this script to work properly.
|
||||
# magiskinit binary The binary to replace /init.
|
||||
# magisk binary The magisk binary.
|
||||
# magiskboot binary A tool to manipulate boot images.
|
||||
# init-ld binary The library that will be LD_PRELOAD of /init
|
||||
# stub.apk binary The stub Magisk app to embed into ramdisk.
|
||||
# chromeos folder This folder includes the utility and keys to sign
|
||||
# (optional) chromeos boot images. Only used for Pixel C.
|
||||
#
|
||||
#######################################################################################
|
||||
|
||||
############
|
||||
# Functions
|
||||
############
|
||||
|
||||
# Pure bash dirname implementation
|
||||
getdir() {
|
||||
case "$1" in
|
||||
*/*)
|
||||
dir=${1%/*}
|
||||
if [ -z $dir ]; then
|
||||
echo "/"
|
||||
else
|
||||
echo $dir
|
||||
fi
|
||||
;;
|
||||
*) echo "." ;;
|
||||
esac
|
||||
}
|
||||
|
||||
#################
|
||||
# Initialization
|
||||
#################
|
||||
|
||||
if [ -z $SOURCEDMODE ]; then
|
||||
# Switch to the location of the script file
|
||||
cd "$(getdir "${BASH_SOURCE:-$0}")"
|
||||
# Load utility functions
|
||||
. ./util_functions.sh
|
||||
# Check if 64-bit
|
||||
api_level_arch_detect
|
||||
fi
|
||||
|
||||
BOOTIMAGE="$1"
|
||||
[ -e "$BOOTIMAGE" ] || abort "$BOOTIMAGE does not exist!"
|
||||
|
||||
# Dump image for MTD/NAND character device boot partitions
|
||||
if [ -c "$BOOTIMAGE" ]; then
|
||||
nanddump -f boot.img "$BOOTIMAGE"
|
||||
BOOTNAND="$BOOTIMAGE"
|
||||
BOOTIMAGE=boot.img
|
||||
fi
|
||||
|
||||
# Flags
|
||||
[ -z $KEEPVERITY ] && KEEPVERITY=false
|
||||
[ -z $KEEPFORCEENCRYPT ] && KEEPFORCEENCRYPT=false
|
||||
[ -z $PATCHVBMETAFLAG ] && PATCHVBMETAFLAG=false
|
||||
[ -z $RECOVERYMODE ] && RECOVERYMODE=false
|
||||
[ -z $LEGACYSAR ] && LEGACYSAR=false
|
||||
export KEEPVERITY
|
||||
export KEEPFORCEENCRYPT
|
||||
export PATCHVBMETAFLAG
|
||||
|
||||
chmod -R 755 .
|
||||
|
||||
#########
|
||||
# Unpack
|
||||
#########
|
||||
|
||||
CHROMEOS=false
|
||||
VENDORBOOT=false
|
||||
|
||||
ui_print "- Unpacking boot image"
|
||||
./magiskboot unpack "$BOOTIMAGE"
|
||||
|
||||
case $? in
|
||||
0 ) ;;
|
||||
2 )
|
||||
ui_print "- ChromeOS boot image detected"
|
||||
CHROMEOS=true
|
||||
;;
|
||||
3 )
|
||||
ui_print "- Vendor boot image detected"
|
||||
VENDORBOOT=true
|
||||
;;
|
||||
* )
|
||||
abort "! Unable to unpack boot image"
|
||||
;;
|
||||
esac
|
||||
|
||||
#################
|
||||
# Ramdisk Checks
|
||||
#################
|
||||
|
||||
unset RAMDISK
|
||||
for path in ramdisk.cpio vendor_ramdisk/init_boot.cpio vendor_ramdisk/ramdisk.cpio; do
|
||||
if [ -e $path ]; then
|
||||
RAMDISK=$path
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
ui_print "- Checking ramdisk status"
|
||||
if [ -n "$RAMDISK" ]; then
|
||||
./magiskboot cpio $RAMDISK test
|
||||
STATUS=$?
|
||||
SKIP_BACKUP=""
|
||||
else
|
||||
# No ramdisk found, create one from scratch
|
||||
RAMDISK=ramdisk.cpio
|
||||
# Could be stock A only legacy SAR, or some Android 13 GKIs
|
||||
STATUS=0
|
||||
SKIP_BACKUP="#"
|
||||
fi
|
||||
|
||||
case $STATUS in
|
||||
0 )
|
||||
# Stock boot
|
||||
ui_print "- Stock boot image detected"
|
||||
SHA1=$(./magiskboot sha1 "$BOOTIMAGE" 2>/dev/null)
|
||||
cat $BOOTIMAGE > stock_boot.img
|
||||
cp -af $RAMDISK ramdisk.cpio.orig 2>/dev/null
|
||||
;;
|
||||
1 )
|
||||
# Magisk patched
|
||||
ui_print "- Magisk patched boot image detected"
|
||||
./magiskboot cpio $RAMDISK \
|
||||
"extract .backup/.magisk config.orig" \
|
||||
"restore"
|
||||
cp -af $RAMDISK ramdisk.cpio.orig
|
||||
rm -f stock_boot.img
|
||||
;;
|
||||
2 )
|
||||
# Unsupported
|
||||
ui_print "! Boot image patched by unsupported programs"
|
||||
abort "! Please restore back to stock boot image"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -f config.orig ]; then
|
||||
# Read existing configs
|
||||
chmod 0644 config.orig
|
||||
SHA1=$(grep_prop SHA1 config.orig)
|
||||
if ! $BOOTMODE; then
|
||||
# Do not inherit config if not in recovery
|
||||
PREINITDEVICE=$(grep_prop PREINITDEVICE config.orig)
|
||||
fi
|
||||
rm config.orig
|
||||
fi
|
||||
|
||||
##################
|
||||
# Ramdisk Patches
|
||||
##################
|
||||
|
||||
ui_print "- Patching ramdisk"
|
||||
|
||||
$BOOTMODE && [ -z "$PREINITDEVICE" ] && PREINITDEVICE=$(./magisk --preinit-device)
|
||||
|
||||
# Compress to save precious ramdisk space
|
||||
./magiskboot compress=xz magisk magisk.xz
|
||||
./magiskboot compress=xz stub.apk stub.xz
|
||||
./magiskboot compress=xz init-ld init-ld.xz
|
||||
|
||||
echo "KEEPVERITY=$KEEPVERITY" > config
|
||||
echo "KEEPFORCEENCRYPT=$KEEPFORCEENCRYPT" >> config
|
||||
echo "RECOVERYMODE=$RECOVERYMODE" >> config
|
||||
echo "VENDORBOOT=$VENDORBOOT" >> config
|
||||
if [ -n "$PREINITDEVICE" ]; then
|
||||
ui_print "- Pre-init storage partition: $PREINITDEVICE"
|
||||
echo "PREINITDEVICE=$PREINITDEVICE" >> config
|
||||
fi
|
||||
[ -n "$SHA1" ] && echo "SHA1=$SHA1" >> config
|
||||
|
||||
./magiskboot cpio $RAMDISK \
|
||||
"add 0750 init magiskinit" \
|
||||
"mkdir 0750 overlay.d" \
|
||||
"mkdir 0750 overlay.d/sbin" \
|
||||
"add 0644 overlay.d/sbin/magisk.xz magisk.xz" \
|
||||
"add 0644 overlay.d/sbin/stub.xz stub.xz" \
|
||||
"add 0644 overlay.d/sbin/init-ld.xz init-ld.xz" \
|
||||
"patch" \
|
||||
"$SKIP_BACKUP backup ramdisk.cpio.orig" \
|
||||
"mkdir 000 .backup" \
|
||||
"add 000 .backup/.magisk config" \
|
||||
|| abort "! Unable to patch ramdisk"
|
||||
|
||||
rm -f ramdisk.cpio.orig config *.xz
|
||||
|
||||
#################
|
||||
# Binary Patches
|
||||
#################
|
||||
|
||||
for dt in dtb kernel_dtb extra; do
|
||||
if [ -f $dt ]; then
|
||||
if ! ./magiskboot dtb $dt test; then
|
||||
ui_print "! Boot image $dt was patched by old (unsupported) Magisk"
|
||||
abort "! Please try again with *unpatched* boot image"
|
||||
fi
|
||||
if ./magiskboot dtb $dt patch; then
|
||||
ui_print "- Patch fstab in boot image $dt"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -f kernel ]; then
|
||||
PATCHEDKERNEL=false
|
||||
# Remove Samsung RKP
|
||||
./magiskboot hexpatch kernel \
|
||||
49010054011440B93FA00F71E9000054010840B93FA00F7189000054001840B91FA00F7188010054 \
|
||||
A1020054011440B93FA00F7140020054010840B93FA00F71E0010054001840B91FA00F7181010054 \
|
||||
&& PATCHEDKERNEL=true
|
||||
|
||||
# Remove Samsung defex
|
||||
# Before: [mov w2, #-221] (-__NR_execve)
|
||||
# After: [mov w2, #-32768]
|
||||
./magiskboot hexpatch kernel 821B8012 E2FF8F12 && PATCHEDKERNEL=true
|
||||
|
||||
# Disable Samsung PROCA
|
||||
# proca_config -> proca_magisk
|
||||
./magiskboot hexpatch kernel \
|
||||
70726F63615F636F6E66696700 \
|
||||
70726F63615F6D616769736B00 \
|
||||
&& PATCHEDKERNEL=true
|
||||
|
||||
# Force kernel to load rootfs for legacy SAR devices
|
||||
# skip_initramfs -> want_initramfs
|
||||
$LEGACYSAR && ./magiskboot hexpatch kernel \
|
||||
736B69705F696E697472616D667300 \
|
||||
77616E745F696E697472616D667300 \
|
||||
&& PATCHEDKERNEL=true
|
||||
|
||||
# If the kernel doesn't need to be patched at all,
|
||||
# keep raw kernel to avoid bootloops on some weird devices
|
||||
$PATCHEDKERNEL || rm -f kernel
|
||||
fi
|
||||
|
||||
#################
|
||||
# Repack & Flash
|
||||
#################
|
||||
|
||||
ui_print "- Repacking boot image"
|
||||
./magiskboot repack "$BOOTIMAGE" || abort "! Unable to repack boot image"
|
||||
|
||||
# Sign chromeos boot
|
||||
$CHROMEOS && sign_chromeos
|
||||
|
||||
# Restore the original boot partition path
|
||||
[ -e "$BOOTNAND" ] && BOOTIMAGE="$BOOTNAND"
|
||||
|
||||
# Reset any error code
|
||||
true
|
||||
121
scripts/cuttlefish.sh
Executable file
121
scripts/cuttlefish.sh
Executable file
|
|
@ -0,0 +1,121 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -xe
|
||||
. scripts/test_common.sh
|
||||
|
||||
cvd_args="-daemon -enable_sandbox=false -memory_mb=8192 -report_anonymous_usage_stats=n -cpus=$core_count"
|
||||
magisk_args='-init_boot_image=magisk_patched.img'
|
||||
|
||||
cleanup() {
|
||||
print_error "! An error occurred"
|
||||
run_cvd_bin stop_cvd || true
|
||||
rm -f magisk_patched.img*
|
||||
}
|
||||
|
||||
run_cvd_bin() {
|
||||
local exe=$1
|
||||
shift
|
||||
HOME=$CF_HOME $CF_HOME/bin/$exe "$@"
|
||||
}
|
||||
|
||||
setup_env() {
|
||||
curl -LO https://github.com/topjohnwu/magisk-files/releases/download/files/cuttlefish-base_1.2.0_amd64.deb
|
||||
sudo apt-get update
|
||||
sudo dpkg -i ./cuttlefish-base_*_*64.deb || sudo apt-get install -f
|
||||
rm cuttlefish-base_*_*64.deb
|
||||
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
|
||||
sudo udevadm control --reload-rules
|
||||
sudo udevadm trigger
|
||||
sudo usermod -aG kvm,cvdnetwork,render $USER
|
||||
yes | "$sdk" --licenses > /dev/null
|
||||
"$sdk" --channel=3 platform-tools
|
||||
adb kill-server
|
||||
adb start-server
|
||||
}
|
||||
|
||||
download_cf() {
|
||||
local branch=$1
|
||||
local device=$2
|
||||
|
||||
if [ -z $branch ]; then
|
||||
branch='aosp-android-latest-release'
|
||||
fi
|
||||
if [ -z $device ]; then
|
||||
device='aosp_cf_x86_64_only_phone'
|
||||
fi
|
||||
local target="${device}-userdebug"
|
||||
|
||||
local build_id=$(curl -sL https://ci.android.com/builds/branches/${branch}/status.json | \
|
||||
jq -r ".targets[] | select(.name == \"$target\") | .last_known_good_build")
|
||||
local sys_img_url="https://ci.android.com/builds/submitted/${build_id}/${target}/latest/raw/${device}-img-${build_id}.zip"
|
||||
local host_pkg_url="https://ci.android.com/builds/submitted/${build_id}/${target}/latest/raw/cvd-host_package.tar.gz"
|
||||
|
||||
print_title "* Download $target ($build_id) images"
|
||||
curl -L $sys_img_url -o aosp_cf_phone-img.zip
|
||||
curl -LO $host_pkg_url
|
||||
rm -rf $CF_HOME
|
||||
mkdir -p $CF_HOME
|
||||
tar xvf cvd-host_package.tar.gz -C $CF_HOME
|
||||
unzip aosp_cf_phone-img.zip -d $CF_HOME
|
||||
rm -f cvd-host_package.tar.gz aosp_cf_phone-img.zip
|
||||
}
|
||||
|
||||
test_cf() {
|
||||
local variant=$1
|
||||
|
||||
run_cvd_bin stop_cvd || true
|
||||
|
||||
print_title "* Testing $variant builds"
|
||||
timeout $boot_timeout bash -c "run_cvd_bin launch_cvd $cvd_args $magisk_args -resume=false"
|
||||
adb wait-for-device
|
||||
run_setup $variant
|
||||
|
||||
adb reboot
|
||||
sleep 5
|
||||
run_cvd_bin stop_cvd || true
|
||||
|
||||
timeout $boot_timeout bash -c "run_cvd_bin launch_cvd $cvd_args $magisk_args"
|
||||
adb wait-for-device
|
||||
run_tests
|
||||
}
|
||||
|
||||
test_main() {
|
||||
# Launch stock cuttlefish
|
||||
run_cvd_bin launch_cvd $cvd_args -resume=false
|
||||
adb wait-for-device
|
||||
|
||||
# Patch and test debug build
|
||||
./build.py -v avd_patch "$CF_HOME/init_boot.img" magisk_patched.img
|
||||
test_cf debug
|
||||
|
||||
# Patch and test release build
|
||||
./build.py -vr avd_patch "$CF_HOME/init_boot.img" magisk_patched.img
|
||||
test_cf release
|
||||
|
||||
# Cleanup
|
||||
run_cvd_bin stop_cvd || true
|
||||
rm -f magisk_patched.img*
|
||||
}
|
||||
|
||||
if [ -z $CF_HOME ]; then
|
||||
print_error "! Environment variable CF_HOME is required"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
setup )
|
||||
setup_env
|
||||
;;
|
||||
download )
|
||||
download_cf $2 $3
|
||||
;;
|
||||
test )
|
||||
trap cleanup EXIT
|
||||
export -f run_cvd_bin
|
||||
test_main
|
||||
trap - EXIT
|
||||
;;
|
||||
* )
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
101
scripts/flash_script.sh
Normal file
101
scripts/flash_script.sh
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
#MAGISK
|
||||
############################################
|
||||
# Magisk Flash Script (updater-script)
|
||||
############################################
|
||||
|
||||
##############
|
||||
# Preparation
|
||||
##############
|
||||
|
||||
# Default permissions
|
||||
umask 022
|
||||
|
||||
OUTFD=$2
|
||||
COMMONDIR=$INSTALLER/assets
|
||||
CHROMEDIR=$INSTALLER/assets/chromeos
|
||||
|
||||
if [ ! -f $COMMONDIR/util_functions.sh ]; then
|
||||
echo "! Unable to extract zip file!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Load utility functions
|
||||
. $COMMONDIR/util_functions.sh
|
||||
|
||||
setup_flashable
|
||||
|
||||
############
|
||||
# Detection
|
||||
############
|
||||
|
||||
if echo $MAGISK_VER | grep -q '\.'; then
|
||||
PRETTY_VER=$MAGISK_VER
|
||||
else
|
||||
PRETTY_VER="$MAGISK_VER($MAGISK_VER_CODE)"
|
||||
fi
|
||||
print_title "Magisk $PRETTY_VER Installer"
|
||||
|
||||
is_mounted /data || mount /data || is_mounted /cache || mount /cache
|
||||
mount_partitions
|
||||
check_data
|
||||
get_flags
|
||||
find_boot_image
|
||||
|
||||
[ -z $BOOTIMAGE ] && abort "! Unable to detect target image"
|
||||
ui_print "- Target image: $BOOTIMAGE"
|
||||
|
||||
# Detect version and architecture
|
||||
api_level_arch_detect
|
||||
|
||||
[ $API -lt 23 ] && abort "! Magisk only support Android 6.0 and above"
|
||||
|
||||
ui_print "- Device platform: $ABI"
|
||||
|
||||
BINDIR=$INSTALLER/lib/$ABI
|
||||
cd $BINDIR
|
||||
for file in lib*.so; do mv "$file" "${file:3:${#file}-6}"; done
|
||||
cd /
|
||||
cp -af $INSTALLER/lib/$ABI32/libmagisk.so $BINDIR/magisk32 2>/dev/null
|
||||
|
||||
# Check if system root is installed and remove
|
||||
$BOOTMODE || remove_system_su
|
||||
|
||||
##############
|
||||
# Environment
|
||||
##############
|
||||
|
||||
ui_print "- Constructing environment"
|
||||
|
||||
# Copy required files
|
||||
rm -rf $MAGISKBIN 2>/dev/null
|
||||
mkdir -p $MAGISKBIN 2>/dev/null
|
||||
cp -af $BINDIR/. $COMMONDIR/. $BBBIN $MAGISKBIN
|
||||
|
||||
# Remove files only used by the Magisk app
|
||||
rm -f $MAGISKBIN/bootctl $MAGISKBIN/main.jar \
|
||||
$MAGISKBIN/module_installer.sh $MAGISKBIN/uninstaller.sh
|
||||
|
||||
chmod -R 755 $MAGISKBIN
|
||||
|
||||
# addon.d
|
||||
if [ -d /system/addon.d ]; then
|
||||
ui_print "- Adding addon.d survival script"
|
||||
blockdev --setrw /dev/block/mapper/system$SLOT 2>/dev/null
|
||||
mount -o rw,remount /system || mount -o rw,remount /
|
||||
ADDOND=/system/addon.d/99-magisk.sh
|
||||
cp -af $COMMONDIR/addon.d.sh $ADDOND
|
||||
chmod 755 $ADDOND
|
||||
fi
|
||||
|
||||
##################
|
||||
# Image Patching
|
||||
##################
|
||||
|
||||
install_magisk
|
||||
|
||||
# Cleanups
|
||||
$BOOTMODE || recovery_cleanup
|
||||
rm -rf $TMPDIR
|
||||
|
||||
ui_print "- Done"
|
||||
exit 0
|
||||
101
scripts/host_patch.sh
Normal file
101
scripts/host_patch.sh
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
#####################################################################
|
||||
# AVD MagiskInit Setup
|
||||
#####################################################################
|
||||
#
|
||||
# Support API level: 23 - 36
|
||||
#
|
||||
# With an emulator booted and accessible via ADB, usage:
|
||||
# ./build.py avd_patch path/to/booted/avd-image/ramdisk.img
|
||||
#
|
||||
# The purpose of this script is to patch AVD ramdisk.img and do a
|
||||
# full integration test of magiskinit under several circumstances.
|
||||
# After patching ramdisk.img, close the emulator, then select
|
||||
# "Cold Boot Now" in AVD Manager to force a full reboot.
|
||||
#
|
||||
#####################################################################
|
||||
# AVD Init Configurations:
|
||||
#
|
||||
# rootfs w/o early mount: API 23 - 25
|
||||
# rootfs with early mount: API 26 - 27
|
||||
# Legacy system-as-root: API 28
|
||||
# 2 stage init: API 29 - 35
|
||||
#####################################################################
|
||||
|
||||
if [ ! -f /system/build.prop ]; then
|
||||
# Running on PC
|
||||
echo 'Please run `./build.py avd_patch` instead of directly executing the script!'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd /data/local/tmp
|
||||
chmod 755 busybox
|
||||
|
||||
if [ -z "$FIRST_STAGE" ]; then
|
||||
export FIRST_STAGE=1
|
||||
export ASH_STANDALONE=1
|
||||
# Re-exec script with busybox
|
||||
exec ./busybox sh $0 "$@"
|
||||
fi
|
||||
|
||||
TARGET_FILE="$1"
|
||||
OUTPUT_FILE="$1.magisk"
|
||||
|
||||
if echo "$TARGET_FILE" | grep -q 'ramdisk'; then
|
||||
IS_RAMDISK=true
|
||||
else
|
||||
IS_RAMDISK=false
|
||||
fi
|
||||
|
||||
# Extract files from APK
|
||||
unzip -oj magisk.apk 'assets/util_functions.sh' 'assets/stub.apk'
|
||||
. ./util_functions.sh
|
||||
|
||||
api_level_arch_detect
|
||||
|
||||
unzip -oj magisk.apk "lib/$ABI/*" -x "lib/$ABI/libbusybox.so"
|
||||
for file in lib*.so; do
|
||||
chmod 755 $file
|
||||
mv "$file" "${file:3:${#file}-6}"
|
||||
done
|
||||
|
||||
if $IS_RAMDISK; then
|
||||
./magiskboot decompress "$TARGET_FILE" ramdisk.cpio
|
||||
else
|
||||
./magiskboot unpack "$TARGET_FILE"
|
||||
fi
|
||||
cp ramdisk.cpio ramdisk.cpio.orig
|
||||
|
||||
export KEEPVERITY=true
|
||||
export KEEPFORCEENCRYPT=true
|
||||
|
||||
echo "KEEPVERITY=$KEEPVERITY" > config
|
||||
echo "KEEPFORCEENCRYPT=$KEEPFORCEENCRYPT" >> config
|
||||
echo "PREINITDEVICE=$(./magisk --preinit-device)" >> config
|
||||
# For API 28, we also manually disable SystemAsRoot
|
||||
# Explicitly override skip_initramfs by setting RECOVERYMODE=true
|
||||
[ $API = "28" ] && echo 'RECOVERYMODE=true' >> config
|
||||
cat config
|
||||
|
||||
./magiskboot compress=xz magisk magisk.xz
|
||||
./magiskboot compress=xz stub.apk stub.xz
|
||||
./magiskboot compress=xz init-ld init-ld.xz
|
||||
|
||||
./magiskboot cpio ramdisk.cpio \
|
||||
"add 0750 init magiskinit" \
|
||||
"mkdir 0750 overlay.d" \
|
||||
"mkdir 0750 overlay.d/sbin" \
|
||||
"add 0644 overlay.d/sbin/magisk.xz magisk.xz" \
|
||||
"add 0644 overlay.d/sbin/stub.xz stub.xz" \
|
||||
"add 0644 overlay.d/sbin/init-ld.xz init-ld.xz" \
|
||||
"patch" \
|
||||
"backup ramdisk.cpio.orig" \
|
||||
"mkdir 000 .backup" \
|
||||
"add 000 .backup/.magisk config"
|
||||
|
||||
rm -f ramdisk.cpio.orig config *.xz
|
||||
if $IS_RAMDISK; then
|
||||
./magiskboot compress=gzip ramdisk.cpio "$OUTPUT_FILE"
|
||||
else
|
||||
./magiskboot repack "$TARGET_FILE" "$OUTPUT_FILE"
|
||||
./magiskboot cleanup
|
||||
fi
|
||||
177
scripts/live_setup.sh
Executable file
177
scripts/live_setup.sh
Executable file
|
|
@ -0,0 +1,177 @@
|
|||
#####################################################################
|
||||
# AVD Magisk Setup
|
||||
#####################################################################
|
||||
#
|
||||
# Support API level: 23 - 36
|
||||
#
|
||||
# For developing Magisk, just use:
|
||||
# ./build.py emulator
|
||||
#
|
||||
# This script will stop zygote, simulate the Magisk start up process
|
||||
# that would've happened before zygote was started, and finally
|
||||
# restart zygote. This is useful for setting up the emulator for
|
||||
# developing Magisk, testing modules, and developing root apps using
|
||||
# the official Android emulator (AVD) instead of a real device.
|
||||
#
|
||||
# This only covers the "core" features of Magisk. For testing
|
||||
# magiskinit, please checkout avd_patch.sh.
|
||||
#
|
||||
#####################################################################
|
||||
|
||||
mount_tmpfs() {
|
||||
# If a file name 'magisk' is in current directory, mount will fail
|
||||
mv magisk magisk.tmp
|
||||
mount -t tmpfs -o 'mode=0755' magisk $1
|
||||
mv magisk.tmp magisk
|
||||
}
|
||||
|
||||
mount_sbin() {
|
||||
mount_tmpfs /sbin
|
||||
chcon u:object_r:rootfs:s0 /sbin
|
||||
}
|
||||
|
||||
if [ ! -f /system/build.prop ]; then
|
||||
# Running on PC
|
||||
echo 'Please run `./build.py emulator` instead of directly executing the script!'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd /data/local/tmp
|
||||
chmod 755 busybox
|
||||
|
||||
if [ -z "$FIRST_STAGE" ]; then
|
||||
export FIRST_STAGE=1
|
||||
export ASH_STANDALONE=1
|
||||
if [ $(./busybox id -u) -ne 0 ]; then
|
||||
# Re-exec script with root
|
||||
exec /system/xbin/su 0 /data/local/tmp/busybox sh $0
|
||||
else
|
||||
# Re-exec script with busybox
|
||||
exec ./busybox sh $0
|
||||
fi
|
||||
fi
|
||||
|
||||
pm install -r -g $(pwd)/magisk.apk
|
||||
|
||||
# Extract files from APK
|
||||
unzip -oj magisk.apk 'assets/util_functions.sh' 'assets/stub.apk'
|
||||
. ./util_functions.sh
|
||||
|
||||
api_level_arch_detect
|
||||
|
||||
unzip -oj magisk.apk "lib/$ABI/*" -x "lib/$ABI/libbusybox.so"
|
||||
for file in lib*.so; do
|
||||
chmod 755 $file
|
||||
mv "$file" "${file:3:${#file}-6}"
|
||||
done
|
||||
|
||||
if $IS64BIT && [ -e "/system/bin/linker" ]; then
|
||||
unzip -oj magisk.apk "lib/$ABI32/libmagisk.so"
|
||||
mv libmagisk.so magisk32
|
||||
chmod 755 magisk32
|
||||
fi
|
||||
|
||||
# Stop zygote (and previous setup if exists)
|
||||
magisk --stop 2>/dev/null
|
||||
stop
|
||||
if [ -d /debug_ramdisk ]; then
|
||||
umount -l /debug_ramdisk 2>/dev/null
|
||||
fi
|
||||
|
||||
# Make sure boot completed props are not set to 1
|
||||
setprop sys.boot_completed 0
|
||||
|
||||
# Mount /cache if not already mounted
|
||||
if ! grep -q ' /cache ' /proc/mounts; then
|
||||
mount -t tmpfs -o 'mode=0755' tmpfs /cache
|
||||
fi
|
||||
|
||||
MAGISKTMP=/sbin
|
||||
|
||||
# Setup bin overlay
|
||||
if mount | grep -q rootfs; then
|
||||
# Legacy rootfs
|
||||
mount -o rw,remount /
|
||||
rm -rf /root
|
||||
mkdir /root /sbin 2>/dev/null
|
||||
chmod 750 /root /sbin
|
||||
ln /sbin/* /root
|
||||
mount -o ro,remount /
|
||||
mount_sbin
|
||||
ln -s /root/* /sbin
|
||||
elif [ -e /sbin ]; then
|
||||
# Legacy SAR
|
||||
mount_sbin
|
||||
mkdir -p /dev/sysroot
|
||||
block=$(mount | grep ' / ' | awk '{ print $1 }')
|
||||
[ $block = "/dev/root" ] && block=/dev/block/vda1
|
||||
mount -o ro $block /dev/sysroot
|
||||
for file in /dev/sysroot/sbin/*; do
|
||||
[ ! -e $file ] && break
|
||||
if [ -L $file ]; then
|
||||
cp -af $file /sbin
|
||||
else
|
||||
sfile=/sbin/$(basename $file)
|
||||
touch $sfile
|
||||
mount -o bind $file $sfile
|
||||
fi
|
||||
done
|
||||
umount -l /dev/sysroot
|
||||
rm -rf /dev/sysroot
|
||||
else
|
||||
# Android Q+ without sbin
|
||||
MAGISKTMP=/debug_ramdisk
|
||||
mount_tmpfs /debug_ramdisk
|
||||
fi
|
||||
|
||||
# Magisk stuff
|
||||
mkdir -p $MAGISKBIN 2>/dev/null
|
||||
unzip -oj magisk.apk 'assets/*.sh' -d $MAGISKBIN
|
||||
mkdir /data/adb/modules 2>/dev/null
|
||||
mkdir /data/adb/post-fs-data.d 2>/dev/null
|
||||
mkdir /data/adb/service.d 2>/dev/null
|
||||
|
||||
for file in magisk magisk32 magiskpolicy stub.apk; do
|
||||
chmod 755 ./$file
|
||||
cp -af ./$file $MAGISKTMP/$file
|
||||
cp -af ./$file $MAGISKBIN/$file
|
||||
done
|
||||
cp -af ./magiskboot $MAGISKBIN/magiskboot
|
||||
cp -af ./magiskinit $MAGISKBIN/magiskinit
|
||||
cp -af ./busybox $MAGISKBIN/busybox
|
||||
|
||||
ln -s ./magisk $MAGISKTMP/su
|
||||
ln -s ./magisk $MAGISKTMP/resetprop
|
||||
ln -s ./magiskpolicy $MAGISKTMP/supolicy
|
||||
|
||||
mkdir -p $MAGISKTMP/.magisk/device
|
||||
mkdir -p $MAGISKTMP/.magisk/worker
|
||||
mount_tmpfs $MAGISKTMP/.magisk/worker
|
||||
mount --make-private $MAGISKTMP/.magisk/worker
|
||||
touch $MAGISKTMP/.magisk/config
|
||||
|
||||
export MAGISKTMP
|
||||
MAKEDEV=1 $MAGISKTMP/magisk --preinit-device 2>&1
|
||||
|
||||
RULESCMD=""
|
||||
rule="$MAGISKTMP/.magisk/preinit/sepolicy.rule"
|
||||
[ -f "$rule" ] && RULESCMD="--apply $rule"
|
||||
|
||||
# SELinux stuffs
|
||||
if [ -d /sys/fs/selinux ]; then
|
||||
if [ -f /vendor/etc/selinux/precompiled_sepolicy ]; then
|
||||
./magiskpolicy --load /vendor/etc/selinux/precompiled_sepolicy --live --magisk $RULESCMD 2>&1
|
||||
elif [ -f /sepolicy ]; then
|
||||
./magiskpolicy --load /sepolicy --live --magisk $RULESCMD 2>&1
|
||||
else
|
||||
./magiskpolicy --live --magisk $RULESCMD 2>&1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Boot up
|
||||
$MAGISKTMP/magisk --post-fs-data
|
||||
start
|
||||
$MAGISKTMP/magisk --service
|
||||
# Make sure reset nb prop after zygote starts
|
||||
sleep 2
|
||||
$MAGISKTMP/magisk --boot-complete
|
||||
33
scripts/module_installer.sh
Normal file
33
scripts/module_installer.sh
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#!/sbin/sh
|
||||
|
||||
#################
|
||||
# Initialization
|
||||
#################
|
||||
|
||||
umask 022
|
||||
|
||||
# echo before loading util_functions
|
||||
ui_print() { echo "$1"; }
|
||||
|
||||
require_new_magisk() {
|
||||
ui_print "*******************************"
|
||||
ui_print " Please install Magisk v20.4+! "
|
||||
ui_print "*******************************"
|
||||
exit 1
|
||||
}
|
||||
|
||||
#########################
|
||||
# Load util_functions.sh
|
||||
#########################
|
||||
|
||||
OUTFD=$2
|
||||
ZIPFILE=$3
|
||||
|
||||
mount /data 2>/dev/null
|
||||
|
||||
[ -f /data/adb/magisk/util_functions.sh ] || require_new_magisk
|
||||
. /data/adb/magisk/util_functions.sh
|
||||
[ $MAGISK_VER_CODE -lt 20400 ] && require_new_magisk
|
||||
|
||||
install_module
|
||||
exit 0
|
||||
173
scripts/release.sh
Executable file
173
scripts/release.sh
Executable file
|
|
@ -0,0 +1,173 @@
|
|||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
# On macOS, gsed is required (brew install gnu-sed)
|
||||
# Required tools: gh
|
||||
# The GitHub cli (gh) has to be properly authenticated
|
||||
|
||||
# These variables can be modified as needed
|
||||
CONFIG=config.prop
|
||||
NOTES=notes.md
|
||||
|
||||
# These are constants, do not modify
|
||||
GCONFIG=app/gradle.properties
|
||||
BUILDCMD="./build.py -c $CONFIG"
|
||||
CWD=$(pwd)
|
||||
|
||||
grep_prop() {
|
||||
local REGEX="s/^$1=//p"
|
||||
shift
|
||||
local FILES=$@
|
||||
sed -n "$REGEX" $FILES | head -n 1
|
||||
}
|
||||
|
||||
ensure_config() {
|
||||
# Make sure version is not commented out and exists
|
||||
sed -i "s:^# version=:version=:g" $CONFIG
|
||||
if ! grep -qE '^version=' $CONFIG; then
|
||||
echo 'version=' >> $CONFIG
|
||||
fi
|
||||
# Make sure abiList is not set when building for release
|
||||
sed -i "s:^abiList=:# abiList=:g" $CONFIG
|
||||
}
|
||||
|
||||
disable_version_config() {
|
||||
# Comment out version config
|
||||
sed -i "s:^version=:# version=:g" $CONFIG
|
||||
}
|
||||
|
||||
bump_canary_version() {
|
||||
# Update version code
|
||||
local code=$(grep_prop magisk.versionCode $GCONFIG)
|
||||
code=$((code + 1))
|
||||
local tag="canary-$code"
|
||||
sed -i "s:versionCode=.*:versionCode=${code}:g" $GCONFIG
|
||||
|
||||
# Commit version code changes
|
||||
git add -u .
|
||||
git status
|
||||
git commit -m "Release new canary build" -m "[skip ci]"
|
||||
git tag $tag
|
||||
|
||||
# Update version name
|
||||
local ver=$(git rev-parse --short=8 HEAD)
|
||||
sed -i "s:version=.*:version=${ver}:g" $CONFIG
|
||||
sed -i "1s:.*:## Magisk (${ver}) (${code}):" $NOTES
|
||||
}
|
||||
|
||||
# $1 = ver
|
||||
set_version() {
|
||||
local ver=$1
|
||||
local code=$(echo - | awk "{ print $ver * 1000 }")
|
||||
local tag="v$ver"
|
||||
|
||||
sed -i "s:versionCode=.*:versionCode=${code}:g" $GCONFIG
|
||||
sed -i "s:version=.*:version=${ver}:g" $CONFIG
|
||||
sed -i "1s:.*:## $(date +'%Y.%-m.%-d') Magisk v$ver:" $NOTES
|
||||
|
||||
# Commit version code changes
|
||||
git add -u .
|
||||
git status
|
||||
git commit -m "Release Magisk v$ver" -m "[skip ci]"
|
||||
git tag $tag
|
||||
}
|
||||
|
||||
build_apk() {
|
||||
$BUILDCMD clean
|
||||
$BUILDCMD all
|
||||
$BUILDCMD -r all
|
||||
}
|
||||
|
||||
build_canary() {
|
||||
bump_canary_version
|
||||
build_apk
|
||||
}
|
||||
|
||||
# $1 = ver
|
||||
build_public() {
|
||||
[ -z $1 ] && exit 1
|
||||
local ver=$1
|
||||
set_version $ver
|
||||
build_apk
|
||||
}
|
||||
|
||||
upload() {
|
||||
# Verify pattern
|
||||
[[ "$1" =~ canary|beta|stable ]]
|
||||
local type=$1
|
||||
|
||||
gh auth status
|
||||
|
||||
local latest_tag=$(git describe --abbrev=0 --tags)
|
||||
local ver=$(grep_prop version $CONFIG)
|
||||
local code=$(grep_prop magisk.versionCode $GCONFIG)
|
||||
local out=$(grep_prop outdir $CONFIG)
|
||||
local tag title
|
||||
|
||||
if [ -z $out ]; then
|
||||
out=out
|
||||
fi
|
||||
|
||||
git push origin master
|
||||
git push --tags
|
||||
|
||||
# Prepare release notes
|
||||
tail -n +3 $NOTES > release.md
|
||||
|
||||
case $type in
|
||||
canary )
|
||||
tag="canary-$code"
|
||||
title="Magisk ($ver) ($code)"
|
||||
|
||||
# Assert tag format
|
||||
[ $latest_tag = $tag ]
|
||||
|
||||
# Publish release
|
||||
gh release create --verify-tag $tag -p -t "$title" -F release.md $out/app-release.apk $out/app-debug.apk $NOTES
|
||||
;;
|
||||
beta|stable )
|
||||
tag="v$ver"
|
||||
title="Magisk v$ver"
|
||||
|
||||
# Assert tag format
|
||||
[ $latest_tag = $tag ]
|
||||
|
||||
# Publish release
|
||||
local release_apk="Magisk-v${ver}.apk"
|
||||
cp $out/app-release.apk $release_apk
|
||||
gh release create --verify-tag $tag -p -t "$title" -F release.md $release_apk $out/app-debug.apk $NOTES
|
||||
rm -f $release_apk
|
||||
;;
|
||||
esac
|
||||
|
||||
# If publishing stable, make it not prerelease and explicitly latest
|
||||
if [ $type = "stable" ]; then
|
||||
gh release edit $tag --prerelease=false --latest
|
||||
fi
|
||||
|
||||
rm -f release.md
|
||||
}
|
||||
|
||||
revert() {
|
||||
local latest_tag=$(git describe --abbrev=0 --tags)
|
||||
git tag -d $latest_tag
|
||||
git reset --hard HEAD~
|
||||
}
|
||||
|
||||
# Use GNU sed on macOS
|
||||
if command -v gsed >/dev/null; then
|
||||
function sed() { gsed "$@"; }
|
||||
export -f sed
|
||||
fi
|
||||
|
||||
git pull
|
||||
|
||||
trap disable_version_config EXIT
|
||||
ensure_config
|
||||
case $1 in
|
||||
canary ) build_canary ;;
|
||||
public ) build_public $2 ;;
|
||||
upload ) upload $2 ;;
|
||||
revert ) revert ;;
|
||||
* ) exit 1 ;;
|
||||
esac
|
||||
87
scripts/test_common.sh
Normal file
87
scripts/test_common.sh
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
if [ -z $ANDROID_HOME ]; then
|
||||
export ANDROID_HOME=$ANDROID_SDK_ROOT
|
||||
fi
|
||||
|
||||
# Make sure paths are consistent
|
||||
export ANDROID_USER_HOME="$HOME/.android"
|
||||
export ANDROID_EMULATOR_HOME="$ANDROID_USER_HOME"
|
||||
export ANDROID_AVD_HOME="$ANDROID_EMULATOR_HOME/avd"
|
||||
export PATH="$PATH:$ANDROID_HOME/platform-tools"
|
||||
|
||||
emu="$ANDROID_HOME/emulator/emulator"
|
||||
sdk="$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager"
|
||||
avd="$ANDROID_HOME/cmdline-tools/latest/bin/avdmanager"
|
||||
|
||||
boot_timeout=100
|
||||
|
||||
core_count=$(nproc)
|
||||
if [ $core_count -gt 8 ]; then
|
||||
core_count=8
|
||||
fi
|
||||
|
||||
print_title() {
|
||||
echo -e "\n\033[44;39m${1}\033[0m\n"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "\n\033[41;39m${1}\033[0m\n" >&2
|
||||
}
|
||||
|
||||
# $1 = TestClass#method
|
||||
# $2 = component
|
||||
am_instrument() {
|
||||
set +x
|
||||
local out=$(adb shell am instrument -w --user 0 -e class "$1" "$2")
|
||||
echo "$out"
|
||||
if grep -q 'OK (' <<< "$out"; then
|
||||
set -x
|
||||
return 0
|
||||
else
|
||||
set -x
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# $1 = pkg
|
||||
wait_for_pm() {
|
||||
sleep 5
|
||||
adb shell pm uninstall $1 || true
|
||||
}
|
||||
|
||||
run_setup() {
|
||||
local variant=$1
|
||||
adb shell 'PATH=$PATH:/debug_ramdisk magisk -v'
|
||||
|
||||
# Install the Magisk app
|
||||
adb install -r -g out/app-${variant}.apk
|
||||
|
||||
# Install the test app
|
||||
adb install -r -g out/test.apk
|
||||
|
||||
local app='com.topjohnwu.magisk.test/com.topjohnwu.magisk.test.AppTestRunner'
|
||||
|
||||
# Run setup through the test app
|
||||
am_instrument '.Environment#setupEnvironment' $app
|
||||
}
|
||||
|
||||
run_tests() {
|
||||
local pkg='com.topjohnwu.magisk.test'
|
||||
local self="$pkg/$pkg.TestRunner"
|
||||
local app="$pkg/$pkg.AppTestRunner"
|
||||
local stub="repackaged.$pkg/$pkg.AppTestRunner"
|
||||
|
||||
# Run app tests
|
||||
am_instrument '.MagiskAppTest,.AdditionalTest' $app
|
||||
|
||||
# Test app hiding
|
||||
am_instrument '.AppMigrationTest#testAppHide' $self
|
||||
|
||||
# Make sure it still works
|
||||
am_instrument '.MagiskAppTest' $stub
|
||||
|
||||
# Test app restore
|
||||
am_instrument '.AppMigrationTest#testAppRestore' $self
|
||||
|
||||
# Make sure it still works
|
||||
am_instrument '.MagiskAppTest' $app
|
||||
}
|
||||
181
scripts/uninstaller.sh
Normal file
181
scripts/uninstaller.sh
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
#MAGISK
|
||||
############################################
|
||||
# Magisk Uninstaller (updater-script)
|
||||
############################################
|
||||
|
||||
##############
|
||||
# Preparation
|
||||
##############
|
||||
|
||||
# Default permissions
|
||||
umask 022
|
||||
|
||||
OUTFD=$2
|
||||
COMMONDIR=$INSTALLER/assets
|
||||
CHROMEDIR=$INSTALLER/assets/chromeos
|
||||
|
||||
if [ ! -f $COMMONDIR/util_functions.sh ]; then
|
||||
echo "! Unable to extract zip file!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Load utility functions
|
||||
. $COMMONDIR/util_functions.sh
|
||||
|
||||
setup_flashable
|
||||
|
||||
############
|
||||
# Detection
|
||||
############
|
||||
|
||||
if echo $MAGISK_VER | grep -q '\.'; then
|
||||
PRETTY_VER=$MAGISK_VER
|
||||
else
|
||||
PRETTY_VER="$MAGISK_VER($MAGISK_VER_CODE)"
|
||||
fi
|
||||
print_title "Magisk $PRETTY_VER Uninstaller"
|
||||
|
||||
is_mounted /data || mount /data || abort "! Unable to mount /data, please uninstall with the Magisk app"
|
||||
mount_partitions
|
||||
check_data
|
||||
$DATA_DE || abort "! Cannot access /data, please uninstall with the Magisk app"
|
||||
get_flags
|
||||
find_boot_image
|
||||
|
||||
[ -z $BOOTIMAGE ] && abort "! Unable to detect target image"
|
||||
ui_print "- Target image: $BOOTIMAGE"
|
||||
|
||||
# Detect version and architecture
|
||||
api_level_arch_detect
|
||||
|
||||
ui_print "- Device platform: $ABI"
|
||||
|
||||
BINDIR=$INSTALLER/lib/$ABI
|
||||
cd $BINDIR
|
||||
for file in lib*.so; do mv "$file" "${file:3:${#file}-6}"; done
|
||||
cd /
|
||||
cp -af $CHROMEDIR/. $BINDIR/chromeos
|
||||
chmod -R 755 $BINDIR
|
||||
|
||||
############
|
||||
# Uninstall
|
||||
############
|
||||
|
||||
cd $BINDIR
|
||||
|
||||
CHROMEOS=false
|
||||
|
||||
ui_print "- Unpacking boot image"
|
||||
# Dump image for MTD/NAND character device boot partitions
|
||||
if [ -c $BOOTIMAGE ]; then
|
||||
nanddump -f boot.img $BOOTIMAGE
|
||||
BOOTNAND=$BOOTIMAGE
|
||||
BOOTIMAGE=boot.img
|
||||
fi
|
||||
./magiskboot unpack "$BOOTIMAGE"
|
||||
|
||||
case $? in
|
||||
1 )
|
||||
abort "! Unsupported/Unknown image format"
|
||||
;;
|
||||
2 )
|
||||
ui_print "- ChromeOS boot image detected"
|
||||
CHROMEOS=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# Restore the original boot partition path
|
||||
[ "$BOOTNAND" ] && BOOTIMAGE=$BOOTNAND
|
||||
|
||||
# Detect boot image state
|
||||
ui_print "- Checking ramdisk status"
|
||||
if [ -e ramdisk.cpio ]; then
|
||||
./magiskboot cpio ramdisk.cpio test
|
||||
STATUS=$?
|
||||
else
|
||||
# Stock A only system-as-root
|
||||
STATUS=0
|
||||
fi
|
||||
case $((STATUS & 3)) in
|
||||
0 ) # Stock boot
|
||||
ui_print "- Stock boot image detected"
|
||||
;;
|
||||
1 ) # Magisk patched
|
||||
ui_print "- Magisk patched image detected"
|
||||
# Find SHA1 of stock boot image
|
||||
./magiskboot cpio ramdisk.cpio "extract .backup/.magisk config.orig"
|
||||
if [ -f config.orig ]; then
|
||||
chmod 0644 config.orig
|
||||
SHA1=$(grep_prop SHA1 config.orig)
|
||||
rm config.orig
|
||||
fi
|
||||
BACKUPDIR=/data/magisk_backup_$SHA1
|
||||
if [ -d $BACKUPDIR ]; then
|
||||
ui_print "- Restoring stock boot image"
|
||||
flash_image $BACKUPDIR/boot.img.gz $BOOTIMAGE
|
||||
for name in dtb dtbo dtbs; do
|
||||
[ -f $BACKUPDIR/${name}.img.gz ] || continue
|
||||
IMAGE=$(find_block $name$SLOT)
|
||||
[ -z $IMAGE ] && continue
|
||||
ui_print "- Restoring stock $name image"
|
||||
flash_image $BACKUPDIR/${name}.img.gz $IMAGE
|
||||
done
|
||||
else
|
||||
ui_print "! Boot image backup unavailable"
|
||||
ui_print "- Restoring ramdisk with internal backup"
|
||||
./magiskboot cpio ramdisk.cpio restore
|
||||
if ! ./magiskboot cpio ramdisk.cpio "exists init"; then
|
||||
# A only system-as-root
|
||||
rm -f ramdisk.cpio
|
||||
fi
|
||||
./magiskboot repack $BOOTIMAGE
|
||||
# Sign chromeos boot
|
||||
$CHROMEOS && sign_chromeos
|
||||
ui_print "- Flashing restored boot image"
|
||||
flash_image new-boot.img $BOOTIMAGE || abort "! Insufficient partition size"
|
||||
fi
|
||||
;;
|
||||
2 ) # Unsupported
|
||||
ui_print "! Boot image patched by unsupported programs"
|
||||
abort "! Cannot uninstall"
|
||||
;;
|
||||
esac
|
||||
|
||||
if $BOOTMODE; then
|
||||
ui_print "- Removing modules"
|
||||
magisk --remove-modules -n
|
||||
fi
|
||||
|
||||
ui_print "- Removing Magisk files"
|
||||
rm -rf \
|
||||
/cache/*magisk* /cache/unblock /data/*magisk* /data/cache/*magisk* /data/property/*magisk* \
|
||||
/data/Magisk.apk /data/busybox /data/custom_ramdisk_patch.sh /data/adb/*magisk* \
|
||||
/data/adb/post-fs-data.d /data/adb/service.d /data/adb/modules* \
|
||||
/data/unencrypted/magisk /metadata/magisk /metadata/watchdog/magisk /persist/magisk /mnt/vendor/persist/magisk
|
||||
|
||||
ADDOND=/system/addon.d/99-magisk.sh
|
||||
if [ -f $ADDOND ]; then
|
||||
blockdev --setrw /dev/block/mapper/system$SLOT 2>/dev/null
|
||||
mount -o rw,remount /system || mount -o rw,remount /
|
||||
rm -f $ADDOND
|
||||
fi
|
||||
|
||||
cd /
|
||||
|
||||
if $BOOTMODE; then
|
||||
ui_print "********************************************"
|
||||
ui_print " The Magisk app will uninstall itself, and"
|
||||
ui_print " the device will reboot after a few seconds"
|
||||
ui_print "********************************************"
|
||||
(sleep 8; /system/bin/reboot)&
|
||||
else
|
||||
ui_print "********************************************"
|
||||
ui_print " The Magisk app will not be uninstalled"
|
||||
ui_print " Please uninstall it manually after reboot"
|
||||
ui_print "********************************************"
|
||||
recovery_cleanup
|
||||
ui_print "- Done"
|
||||
fi
|
||||
|
||||
rm -rf $TMPDIR
|
||||
exit 0
|
||||
27
scripts/update_binary.sh
Normal file
27
scripts/update_binary.sh
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#!/sbin/sh
|
||||
|
||||
TMPDIR=/dev/tmp
|
||||
rm -rf $TMPDIR
|
||||
mkdir -p $TMPDIR 2>/dev/null
|
||||
|
||||
export BBBIN=$TMPDIR/busybox
|
||||
for arch in "x86_64" "x86" "arm64-v8a" "armeabi-v7a"; do
|
||||
unzip -o "$3" "lib/$arch/libbusybox.so" -d $TMPDIR >&2
|
||||
libpath="$TMPDIR/lib/$arch/libbusybox.so"
|
||||
chmod 755 $libpath
|
||||
if [ -x $libpath ] && $libpath >/dev/null 2>&1; then
|
||||
mv -f $libpath $BBBIN
|
||||
break
|
||||
fi
|
||||
done
|
||||
$BBBIN rm -rf $TMPDIR/lib
|
||||
|
||||
export INSTALLER=$TMPDIR/install
|
||||
$BBBIN mkdir -p $INSTALLER
|
||||
$BBBIN unzip -o "$3" "assets/*" "lib/*" "META-INF/com/google/*" -x "lib/*/libbusybox.so" -d $INSTALLER >&2
|
||||
export ASH_STANDALONE=1
|
||||
if echo "$3" | $BBBIN grep -q "uninstall"; then
|
||||
exec $BBBIN sh "$INSTALLER/assets/uninstaller.sh" "$@"
|
||||
else
|
||||
exec $BBBIN sh "$INSTALLER/META-INF/com/google/android/updater-script" "$@"
|
||||
fi
|
||||
763
scripts/util_functions.sh
Normal file
763
scripts/util_functions.sh
Normal file
|
|
@ -0,0 +1,763 @@
|
|||
############################################
|
||||
# Magisk General Utility Functions
|
||||
############################################
|
||||
|
||||
#MAGISK_VERSION_STUB
|
||||
|
||||
###################
|
||||
# Global Variables
|
||||
###################
|
||||
|
||||
# True if the script is running on booted Android, not something like recovery
|
||||
# BOOTMODE=
|
||||
|
||||
# The path to store temporary files that don't need to persist
|
||||
# TMPDIR=
|
||||
|
||||
# The non-volatile path where magisk executables are stored
|
||||
# MAGISKBIN=
|
||||
|
||||
###################
|
||||
# Helper Functions
|
||||
###################
|
||||
|
||||
ui_print() {
|
||||
if $BOOTMODE; then
|
||||
echo "$1"
|
||||
else
|
||||
echo -e "ui_print $1\nui_print" >> /proc/self/fd/$OUTFD
|
||||
fi
|
||||
}
|
||||
|
||||
toupper() {
|
||||
echo "$@" | tr '[:lower:]' '[:upper:]'
|
||||
}
|
||||
|
||||
grep_cmdline() {
|
||||
local REGEX="s/^$1=//p"
|
||||
{ echo $(cat /proc/cmdline)$(sed -e 's/[^"]//g' -e 's/""//g' /proc/cmdline) | xargs -n 1; \
|
||||
sed -e 's/ = /=/g' -e 's/, /,/g' -e 's/"//g' /proc/bootconfig; \
|
||||
} 2>/dev/null | sed -n "$REGEX"
|
||||
}
|
||||
|
||||
grep_prop() {
|
||||
local REGEX="s/^$1=//p"
|
||||
shift
|
||||
local FILES=$@
|
||||
[ -z "$FILES" ] && FILES='/system/build.prop'
|
||||
cat $FILES 2>/dev/null | dos2unix | sed -n "$REGEX" | head -n 1
|
||||
}
|
||||
|
||||
grep_get_prop() {
|
||||
local result=$(grep_prop $@)
|
||||
if [ -z "$result" ]; then
|
||||
# Fallback to getprop
|
||||
getprop "$1"
|
||||
else
|
||||
echo $result
|
||||
fi
|
||||
}
|
||||
|
||||
getvar() {
|
||||
local VARNAME=$1
|
||||
local VALUE
|
||||
local PROPPATH='/data/.magisk /cache/.magisk'
|
||||
[ ! -z $MAGISKTMP ] && PROPPATH="$MAGISKTMP/.magisk/config $PROPPATH"
|
||||
VALUE=$(grep_prop $VARNAME $PROPPATH)
|
||||
[ ! -z $VALUE ] && eval $VARNAME=\$VALUE
|
||||
}
|
||||
|
||||
is_mounted() {
|
||||
grep -q " $(readlink -f $1) " /proc/mounts 2>/dev/null
|
||||
return $?
|
||||
}
|
||||
|
||||
abort() {
|
||||
ui_print "$1"
|
||||
$BOOTMODE || recovery_cleanup
|
||||
[ ! -z $MODPATH ] && rm -rf $MODPATH
|
||||
rm -rf $TMPDIR
|
||||
exit 1
|
||||
}
|
||||
|
||||
print_title() {
|
||||
local len line1len line2len bar
|
||||
line1len=$(echo -n $1 | wc -c)
|
||||
line2len=$(echo -n $2 | wc -c)
|
||||
len=$line2len
|
||||
[ $line1len -gt $line2len ] && len=$line1len
|
||||
len=$((len + 2))
|
||||
bar=$(printf "%${len}s" | tr ' ' '*')
|
||||
ui_print "$bar"
|
||||
ui_print " $1 "
|
||||
[ "$2" ] && ui_print " $2 "
|
||||
ui_print "$bar"
|
||||
}
|
||||
|
||||
######################
|
||||
# Environment Related
|
||||
######################
|
||||
|
||||
setup_flashable() {
|
||||
ensure_bb
|
||||
$BOOTMODE && return
|
||||
if [ -z $OUTFD ] || readlink /proc/$$/fd/$OUTFD | grep -q /tmp; then
|
||||
# We will have to manually find out OUTFD
|
||||
for FD in $(ls /proc/$$/fd); do
|
||||
if readlink /proc/$$/fd/$FD | grep -q pipe; then
|
||||
if ps | grep -v grep | grep -qE " 3 $FD |status_fd=$FD"; then
|
||||
OUTFD=$FD
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
recovery_actions
|
||||
}
|
||||
|
||||
ensure_bb() {
|
||||
if set -o | grep -q standalone; then
|
||||
# We are definitely in busybox ash
|
||||
set -o standalone
|
||||
return
|
||||
fi
|
||||
|
||||
# Find our busybox binary
|
||||
local bb
|
||||
if [ -f $TMPDIR/busybox ]; then
|
||||
bb=$TMPDIR/busybox
|
||||
elif [ -f $MAGISKBIN/busybox ]; then
|
||||
bb=$MAGISKBIN/busybox
|
||||
else
|
||||
abort "! Cannot find BusyBox"
|
||||
fi
|
||||
chmod 755 $bb
|
||||
|
||||
# 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
|
||||
|
||||
# Find our current arguments
|
||||
# Run in busybox environment to ensure consistent results
|
||||
# /proc/<pid>/cmdline shall be <interpreter> <script> <arguments...>
|
||||
local cmds="$($bb sh -c "
|
||||
for arg in \$(tr '\0' '\n' < /proc/$$/cmdline); do
|
||||
if [ -z \"\$cmds\" ]; then
|
||||
# Skip the first argument as we want to change the interpreter
|
||||
cmds=\"sh\"
|
||||
else
|
||||
cmds=\"\$cmds '\$arg'\"
|
||||
fi
|
||||
done
|
||||
echo \$cmds")"
|
||||
|
||||
# Re-exec our script
|
||||
echo $cmds | $bb xargs $bb
|
||||
exit
|
||||
}
|
||||
|
||||
recovery_actions() {
|
||||
# Make sure random won't get blocked
|
||||
mount -o bind /dev/urandom /dev/random
|
||||
# Unset library paths
|
||||
OLD_LD_LIB=$LD_LIBRARY_PATH
|
||||
OLD_LD_PRE=$LD_PRELOAD
|
||||
OLD_LD_CFG=$LD_CONFIG_FILE
|
||||
unset LD_LIBRARY_PATH
|
||||
unset LD_PRELOAD
|
||||
unset LD_CONFIG_FILE
|
||||
}
|
||||
|
||||
recovery_cleanup() {
|
||||
local DIR
|
||||
ui_print "- Unmounting partitions"
|
||||
(
|
||||
if [ ! -d /postinstall/tmp ]; then
|
||||
umount -l /system
|
||||
umount -l /system_root
|
||||
fi
|
||||
umount -l /vendor
|
||||
umount -l /persist
|
||||
umount -l /metadata
|
||||
for DIR in /apex /system /system_root; do
|
||||
if [ -L "${DIR}_link" ]; then
|
||||
rmdir $DIR
|
||||
mv -f ${DIR}_link $DIR
|
||||
fi
|
||||
done
|
||||
umount -l /dev/random
|
||||
) 2>/dev/null
|
||||
[ -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
|
||||
}
|
||||
|
||||
#######################
|
||||
# Installation Related
|
||||
#######################
|
||||
|
||||
# find_block [partname...]
|
||||
find_block() {
|
||||
local BLOCK DEV DEVICE DEVNAME PARTNAME UEVENT
|
||||
for BLOCK in "$@"; do
|
||||
DEVICE=$(find /dev/block \( -type b -o -type c -o -type l \) -iname $BLOCK | head -n 1) 2>/dev/null
|
||||
if [ ! -z $DEVICE ]; then
|
||||
echo $DEVICE
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
# Fallback by parsing sysfs uevents
|
||||
for UEVENT in /sys/dev/block/*/uevent; do
|
||||
DEVNAME=$(grep_prop DEVNAME $UEVENT)
|
||||
PARTNAME=$(grep_prop PARTNAME $UEVENT)
|
||||
for BLOCK in "$@"; do
|
||||
if [ "$(toupper $BLOCK)" = "$(toupper $PARTNAME)" ]; then
|
||||
echo /dev/block/$DEVNAME
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
done
|
||||
# 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
|
||||
echo $DEVICE
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
# setup_mntpoint <mountpoint>
|
||||
setup_mntpoint() {
|
||||
local POINT=$1
|
||||
[ -L $POINT ] && mv -f $POINT ${POINT}_link
|
||||
if [ ! -d $POINT ]; then
|
||||
rm -f $POINT
|
||||
mkdir -p $POINT
|
||||
fi
|
||||
}
|
||||
|
||||
# mount_name <partname(s)> <mountpoint> <flag>
|
||||
mount_name() {
|
||||
local PART=$1
|
||||
local POINT=$2
|
||||
local FLAG=$3
|
||||
setup_mntpoint $POINT
|
||||
is_mounted $POINT && return
|
||||
# First try mounting with fstab
|
||||
mount $FLAG $POINT 2>/dev/null
|
||||
if ! is_mounted $POINT; then
|
||||
local BLOCK=$(find_block $PART)
|
||||
mount $FLAG $BLOCK $POINT || return
|
||||
fi
|
||||
ui_print "- Mounting $POINT"
|
||||
}
|
||||
|
||||
# mount_ro_ensure <partname(s)> <mountpoint>
|
||||
mount_ro_ensure() {
|
||||
# We handle ro partitions only in recovery
|
||||
$BOOTMODE && return
|
||||
local PART=$1
|
||||
local POINT=$2
|
||||
mount_name "$PART" $POINT '-o ro'
|
||||
is_mounted $POINT || abort "! Cannot mount $POINT"
|
||||
}
|
||||
|
||||
# After calling this method, the following variables will be set:
|
||||
# SLOT, SYSTEM_AS_ROOT, LEGACYSAR
|
||||
mount_partitions() {
|
||||
# Check A/B slot
|
||||
SLOT=$(grep_cmdline androidboot.slot_suffix)
|
||||
if [ -z $SLOT ]; then
|
||||
SLOT=$(grep_cmdline androidboot.slot)
|
||||
[ -z $SLOT ] || SLOT=_${SLOT}
|
||||
fi
|
||||
[ "$SLOT" = "normal" ] && unset SLOT
|
||||
[ -z $SLOT ] || ui_print "- Current boot slot: $SLOT"
|
||||
|
||||
# Mount ro partitions
|
||||
if is_mounted /system_root; then
|
||||
umount /system 2>/dev/null
|
||||
umount /system_root 2>/dev/null
|
||||
fi
|
||||
mount_ro_ensure "system$SLOT app$SLOT" /system
|
||||
if [ -f /system/init -o -L /system/init ]; then
|
||||
SYSTEM_AS_ROOT=true
|
||||
setup_mntpoint /system_root
|
||||
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
|
||||
mount -o bind /system_root/system /system
|
||||
else
|
||||
if grep ' / ' /proc/mounts | grep -qv 'rootfs' || grep -q ' /system_root ' /proc/mounts; then
|
||||
SYSTEM_AS_ROOT=true
|
||||
else
|
||||
SYSTEM_AS_ROOT=false
|
||||
fi
|
||||
fi
|
||||
$SYSTEM_AS_ROOT && ui_print "- Device is system-as-root"
|
||||
|
||||
LEGACYSAR=false
|
||||
if $BOOTMODE; then
|
||||
grep ' / ' /proc/mounts | grep -q '/dev/root' && LEGACYSAR=true
|
||||
else
|
||||
# Recovery mode, assume devices that don't use dynamic partitions are legacy SAR
|
||||
local IS_DYNAMIC=false
|
||||
if grep -q 'androidboot.super_partition' /proc/cmdline; then
|
||||
IS_DYNAMIC=true
|
||||
elif [ -n "$(find_block super)" ]; then
|
||||
IS_DYNAMIC=true
|
||||
fi
|
||||
if $SYSTEM_AS_ROOT && ! $IS_DYNAMIC; then
|
||||
LEGACYSAR=true
|
||||
ui_print "- Legacy SAR, force kernel to load rootfs"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# After calling this method, the following variables will be set:
|
||||
# ISENCRYPTED, PATCHVBMETAFLAG,
|
||||
# KEEPVERITY, KEEPFORCEENCRYPT, RECOVERYMODE, VENDORBOOT
|
||||
get_flags() {
|
||||
if grep ' /data ' /proc/mounts | grep -q 'dm-'; then
|
||||
ISENCRYPTED=true
|
||||
elif [ "$(getprop ro.crypto.state)" = "encrypted" ]; then
|
||||
ISENCRYPTED=true
|
||||
elif [ "$DATA" = "false" ]; then
|
||||
# No data access means unable to decrypt in recovery
|
||||
ISENCRYPTED=true
|
||||
else
|
||||
ISENCRYPTED=false
|
||||
fi
|
||||
if [ -n "$(find_block vbmeta vbmeta_a)" ]; then
|
||||
PATCHVBMETAFLAG=false
|
||||
else
|
||||
PATCHVBMETAFLAG=true
|
||||
ui_print "- No vbmeta partition, patch vbmeta in boot image"
|
||||
fi
|
||||
|
||||
# Overridable config flags with safe defaults
|
||||
getvar KEEPVERITY
|
||||
getvar KEEPFORCEENCRYPT
|
||||
getvar RECOVERYMODE
|
||||
getvar VENDORBOOT
|
||||
if [ -z $KEEPVERITY ]; then
|
||||
if $SYSTEM_AS_ROOT; then
|
||||
KEEPVERITY=true
|
||||
ui_print "- System-as-root, keep dm-verity"
|
||||
else
|
||||
KEEPVERITY=false
|
||||
fi
|
||||
fi
|
||||
if [ -z $KEEPFORCEENCRYPT ]; then
|
||||
if $ISENCRYPTED; then
|
||||
KEEPFORCEENCRYPT=true
|
||||
ui_print "- Encrypted data, keep forceencrypt"
|
||||
else
|
||||
KEEPFORCEENCRYPT=false
|
||||
fi
|
||||
fi
|
||||
[ -z $RECOVERYMODE ] && RECOVERYMODE=false
|
||||
[ -z $VENDORBOOT ] && VENDORBOOT=false
|
||||
}
|
||||
|
||||
# Returns whether the device is GKI 13+
|
||||
is_gt_gki_13() {
|
||||
[ "$(uname -r | cut -d. -f1)" -ge 5 ] && uname -r | grep -Evq "android12-|^5\.4"
|
||||
}
|
||||
|
||||
# Require RECOVERYMODE, VENDORBOOT, SLOT to be set.
|
||||
# After calling this method, BOOTIMAGE will be set.
|
||||
find_boot_image() {
|
||||
BOOTIMAGE=
|
||||
if $VENDORBOOT; then
|
||||
BOOTIMAGE="/dev/block/by-name/vendor_boot$SLOT"
|
||||
elif $RECOVERYMODE; then
|
||||
BOOTIMAGE=$(find_block "recovery$SLOT" "sos")
|
||||
elif [ -e "/dev/block/by-name/init_boot$SLOT" ] && is_gt_gki_13; then
|
||||
# init_boot is only used with GKI 13+. It is possible that some devices with init_boot
|
||||
# partition still uses Android 12 GKI or previous kernels, so we need to explicitly detect that scenario.
|
||||
BOOTIMAGE="/dev/block/by-name/init_boot$SLOT"
|
||||
elif [ -e "/dev/block/by-name/boot$SLOT" ]; then
|
||||
# Standard location since AOSP Android 10+
|
||||
BOOTIMAGE="/dev/block/by-name/boot$SLOT"
|
||||
elif [ -n "$SLOT" ]; then
|
||||
# Fallback for A/B devices running < Android 10
|
||||
BOOTIMAGE=$(find_block "ramdisk$SLOT" "boot$SLOT")
|
||||
else
|
||||
# Fallback for all legacy and non-standard devices
|
||||
BOOTIMAGE=$(find_block ramdisk kern-a android_boot kernel bootimg boot lnx boot_a)
|
||||
fi
|
||||
if [ -z $BOOTIMAGE ]; then
|
||||
# Lets see what fstabs tells me
|
||||
BOOTIMAGE=$(grep -v '#' /etc/*fstab* | grep -E '/boot(img)?[^a-zA-Z]' | grep -oE '/dev/[a-zA-Z0-9_./-]*' | head -n 1)
|
||||
fi
|
||||
}
|
||||
|
||||
flash_image() {
|
||||
local CMD1
|
||||
case "$1" in
|
||||
*.gz) CMD1="gzip -d < '$1' 2>/dev/null";;
|
||||
*) CMD1="cat '$1'";;
|
||||
esac
|
||||
if [ -b "$2" ]; then
|
||||
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" | cat - /dev/zero > "$2" 2>/dev/null
|
||||
elif [ -c "$2" ]; then
|
||||
flash_eraseall "$2" >&2
|
||||
eval "$CMD1" | nandwrite -p "$2" - >&2
|
||||
else
|
||||
ui_print "- Not block or char device, storing image"
|
||||
eval "$CMD1" > "$2" 2>/dev/null
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Common installation script for flash_script.sh and addon.d.sh
|
||||
install_magisk() {
|
||||
cd $MAGISKBIN
|
||||
|
||||
# Source the boot patcher
|
||||
SOURCEDMODE=true
|
||||
. ./boot_patch.sh "$BOOTIMAGE"
|
||||
|
||||
ui_print "- Flashing new boot image"
|
||||
flash_image new-boot.img "$BOOTIMAGE"
|
||||
case $? in
|
||||
1)
|
||||
abort "! Insufficient partition size"
|
||||
;;
|
||||
2)
|
||||
abort "! $BOOTIMAGE is read only"
|
||||
;;
|
||||
esac
|
||||
|
||||
./magiskboot cleanup
|
||||
rm -f new-boot.img
|
||||
|
||||
run_migrations
|
||||
}
|
||||
|
||||
sign_chromeos() {
|
||||
ui_print "- Signing ChromeOS boot image"
|
||||
|
||||
echo > empty
|
||||
./chromeos/futility vbutil_kernel --pack new-boot.img.signed \
|
||||
--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
|
||||
}
|
||||
|
||||
remove_system_su() {
|
||||
[ -d /postinstall/tmp ] && POSTINST=/postinstall
|
||||
cd $POSTINST/system
|
||||
if [ -f bin/su -o -f xbin/su ] && [ ! -f /su/bin/su ]; then
|
||||
ui_print "- Removing system installed root"
|
||||
blockdev --setrw /dev/block/mapper/system$SLOT 2>/dev/null
|
||||
mount -o rw,remount $POSTINST/system
|
||||
# SuperSU
|
||||
cd bin
|
||||
if [ -e .ext/.su ]; then
|
||||
mv -f app_process32_original app_process32 2>/dev/null
|
||||
mv -f app_process64_original app_process64 2>/dev/null
|
||||
mv -f install-recovery_original.sh install-recovery.sh 2>/dev/null
|
||||
if [ -e app_process64 ]; then
|
||||
ln -sf app_process64 app_process
|
||||
elif [ -e app_process32 ]; then
|
||||
ln -sf app_process32 app_process
|
||||
fi
|
||||
fi
|
||||
# More SuperSU, SuperUser & ROM su
|
||||
cd ..
|
||||
rm -rf .pin bin/.ext etc/.installed_su_daemon etc/.has_su_daemon \
|
||||
xbin/daemonsu xbin/su xbin/sugote xbin/sugote-mksh xbin/supolicy \
|
||||
bin/app_process_init bin/su /cache/su lib/libsupol.so lib64/libsupol.so \
|
||||
su.d etc/init.d/99SuperSUDaemon etc/install-recovery.sh /cache/install-recovery.sh \
|
||||
.supersu /cache/.supersu /data/.supersu \
|
||||
app/Superuser.apk app/SuperSU /cache/Superuser.apk
|
||||
elif [ -f /cache/su.img -o -f /data/su.img -o -d /data/su -o -d /data/adb/su ]; then
|
||||
ui_print "- Removing systemless installed root"
|
||||
umount -l /su 2>/dev/null
|
||||
rm -rf /cache/su.img /data/su.img /data/su /data/adb/su /data/adb/suhide \
|
||||
/cache/.supersu /data/.supersu /cache/supersu_install /data/supersu_install
|
||||
fi
|
||||
cd $TMPDIR
|
||||
}
|
||||
|
||||
api_level_arch_detect() {
|
||||
API=$(grep_get_prop ro.build.version.sdk)
|
||||
ABI=$(grep_get_prop ro.product.cpu.abi)
|
||||
if [ "$ABI" = "arm64-v8a" ]; then
|
||||
ARCH=arm64
|
||||
ABI32=armeabi-v7a
|
||||
IS64BIT=true
|
||||
elif [ "$ABI" = "x86_64" ]; then
|
||||
ARCH=x64
|
||||
ABI32=x86
|
||||
IS64BIT=true
|
||||
elif [ "$ABI" = "armeabi-v7a" ]; then
|
||||
ARCH=arm
|
||||
ABI32=armeabi-v7a
|
||||
IS64BIT=false
|
||||
elif [ "$ABI" = "x86" ]; then
|
||||
ARCH=x86
|
||||
ABI32=x86
|
||||
IS64BIT=false
|
||||
elif [ "$ABI" = "riscv64" ]; then
|
||||
ARCH=riscv64
|
||||
ABI32=riscv32
|
||||
IS64BIT=true
|
||||
fi
|
||||
}
|
||||
|
||||
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
|
||||
# Test if data is decrypted
|
||||
$DATA && [ -d /data/adb ] && touch /data/adb/.rw && rm /data/adb/.rw && DATA_DE=true
|
||||
$DATA_DE && [ -d /data/adb/magisk ] || mkdir /data/adb/magisk || DATA_DE=false
|
||||
fi
|
||||
MAGISKBIN="/data/magisk"
|
||||
$DATA || MAGISKBIN="/cache/data_adb/magisk"
|
||||
$DATA_DE && MAGISKBIN="/data/adb/magisk"
|
||||
}
|
||||
|
||||
run_migrations() {
|
||||
local SHA1
|
||||
local TARGET
|
||||
# Legacy app installation
|
||||
local BACKUP=$MAGISKBIN/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
|
||||
SHA1=$(basename $gz | sed -e 's/stock_boot_//' -e 's/.img.gz//')
|
||||
[ -z $SHA1 ] && break
|
||||
mkdir /data/magisk_backup_${SHA1} 2>/dev/null
|
||||
mv $gz /data/magisk_backup_${SHA1}/boot.img.gz
|
||||
done
|
||||
|
||||
# Stock backups
|
||||
SHA1=
|
||||
for name in boot dtb dtbo dtbs; do
|
||||
BACKUP=$MAGISKBIN/stock_${name}.img
|
||||
[ -f $BACKUP ] || continue
|
||||
if [ $name = 'boot' ]; then
|
||||
SHA1=$($MAGISKBIN/magiskboot sha1 $BACKUP)
|
||||
mkdir /data/magisk_backup_${SHA1} 2>/dev/null
|
||||
fi
|
||||
[ -z $SHA1 ] && break
|
||||
TARGET=/data/magisk_backup_${SHA1}/${name}.img
|
||||
cp $BACKUP $TARGET
|
||||
rm -f $BACKUP
|
||||
gzip -9f $TARGET
|
||||
done
|
||||
|
||||
copy_preinit_files
|
||||
}
|
||||
|
||||
copy_preinit_files() {
|
||||
local PREINITDIR=$MAGISKTMP/.magisk/preinit
|
||||
if [ ! -d $PREINITDIR ]; then
|
||||
ui_print "- Unable to find preinit dir"
|
||||
return 1
|
||||
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
|
||||
[ -f $MODDIR/update ] && continue
|
||||
cat $r
|
||||
echo
|
||||
done > $PREINITDIR/sepolicy.rule
|
||||
}
|
||||
|
||||
#################
|
||||
# Module Related
|
||||
#################
|
||||
|
||||
set_perm() {
|
||||
chown $2:$3 $1 || return 1
|
||||
chmod $4 $1 || return 1
|
||||
local CON=$5
|
||||
[ -z $CON ] && CON=u:object_r:system_file:s0
|
||||
chcon $CON $1 || return 1
|
||||
}
|
||||
|
||||
set_perm_recursive() {
|
||||
find $1 -type d 2>/dev/null | while read dir; do
|
||||
set_perm $dir $2 $3 $4 $6
|
||||
done
|
||||
find $1 -type f -o -type l 2>/dev/null | while read file; do
|
||||
set_perm $file $2 $3 $5 $6
|
||||
done
|
||||
}
|
||||
|
||||
mktouch() {
|
||||
mkdir -p ${1%/*} 2>/dev/null
|
||||
[ -z $2 ] && touch $1 || echo $2 > $1
|
||||
chmod 644 $1
|
||||
}
|
||||
|
||||
boot_actions() { return; }
|
||||
|
||||
# Require ZIPFILE to be set
|
||||
is_legacy_script() {
|
||||
unzip -l "$ZIPFILE" install.sh | grep -q install.sh
|
||||
return $?
|
||||
}
|
||||
|
||||
# $1 = MODPATH
|
||||
set_default_perm() {
|
||||
set_perm_recursive $1 0 0 0755 0644
|
||||
set_perm_recursive $1/system/bin 0 2000 0755 0755
|
||||
set_perm_recursive $1/system/xbin 0 2000 0755 0755
|
||||
set_perm_recursive $1/system/system_ext/bin 0 2000 0755 0755
|
||||
set_perm_recursive $1/system/vendor/bin 0 2000 0755 0755 u:object_r:vendor_file:s0
|
||||
}
|
||||
|
||||
# Require OUTFD, ZIPFILE to be set
|
||||
install_module() {
|
||||
rm -rf $TMPDIR
|
||||
mkdir -p $TMPDIR
|
||||
chcon u:object_r:system_file:s0 $TMPDIR
|
||||
cd $TMPDIR
|
||||
|
||||
setup_flashable
|
||||
mount_partitions
|
||||
api_level_arch_detect
|
||||
|
||||
# Setup busybox and binaries
|
||||
if $BOOTMODE; then
|
||||
boot_actions
|
||||
else
|
||||
recovery_actions
|
||||
fi
|
||||
|
||||
# Extract prop file
|
||||
unzip -o "$ZIPFILE" module.prop -d $TMPDIR >&2
|
||||
[ ! -f $TMPDIR/module.prop ] && abort "! This zip is not a Magisk module!"
|
||||
|
||||
local MODDIRNAME=modules
|
||||
$BOOTMODE && MODDIRNAME=modules_update
|
||||
local MODULEROOT=/data/adb/$MODDIRNAME
|
||||
MODID=$(grep_prop id $TMPDIR/module.prop)
|
||||
MODNAME=$(grep_prop name $TMPDIR/module.prop)
|
||||
MODAUTH=$(grep_prop author $TMPDIR/module.prop)
|
||||
MODPATH=$MODULEROOT/$MODID
|
||||
|
||||
# Create mod paths
|
||||
rm -rf $MODPATH
|
||||
mkdir -p $MODPATH
|
||||
chcon u:object_r:system_file:s0 $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
|
||||
print_title "$MODNAME" "by $MODAUTH"
|
||||
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
|
||||
set_default_perm $MODPATH
|
||||
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
|
||||
|
||||
for TARGET in $REMOVE; do
|
||||
ui_print "- Remove target: $TARGET"
|
||||
mkdir -p $(dirname $MODPATH$TARGET) 2>/dev/null
|
||||
mknod $MODPATH$TARGET c 0 0
|
||||
done
|
||||
|
||||
if $BOOTMODE; then
|
||||
# Update info for Magisk app
|
||||
mktouch /data/adb/modules/$MODID/update
|
||||
rm -rf /data/adb/modules/$MODID/remove 2>/dev/null
|
||||
rm -rf /data/adb/modules/$MODID/disable 2>/dev/null
|
||||
cp -af $MODPATH/module.prop /data/adb/modules/$MODID/module.prop
|
||||
fi
|
||||
|
||||
# Copy over custom sepolicy rules
|
||||
if [ -f $MODPATH/sepolicy.rule ]; then
|
||||
ui_print "- Installing custom sepolicy rules"
|
||||
copy_preinit_files
|
||||
fi
|
||||
|
||||
# Remove stuff that doesn't belong to modules and clean up any empty directories
|
||||
rm -rf \
|
||||
$MODPATH/system/placeholder $MODPATH/customize.sh \
|
||||
$MODPATH/README.md $MODPATH/.git*
|
||||
rmdir -p $MODPATH 2>/dev/null
|
||||
|
||||
cd /
|
||||
$BOOTMODE || recovery_cleanup
|
||||
rm -rf $TMPDIR
|
||||
|
||||
ui_print "- Done"
|
||||
}
|
||||
|
||||
##########
|
||||
# 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
|
||||
|
||||
TMPDIR=/dev/tmp
|
||||
MAGISKBIN="/data/adb/magisk"
|
||||
Loading…
Add table
Add a link
Reference in a new issue