2960 lines
80 KiB
Bash
Executable File
2960 lines
80 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
##########################################################################################
|
|
#
|
|
# Magisk Boot Image Patcher - original created by topjohnwu and modded by shakalaca's
|
|
# modded by NewBit XDA for Android Studio AVD
|
|
##########################################################################################
|
|
|
|
###################
|
|
# Helper Functions
|
|
###################
|
|
|
|
# Copied 1 to 1 from topjohnwu
|
|
getdir() {
|
|
case "$1" in
|
|
*/*) dir=${1%/*}; [ -z $dir ] && echo "/" || echo $dir ;;
|
|
*) echo "." ;;
|
|
esac
|
|
}
|
|
|
|
get_flags() {
|
|
echo "[-] Get Flags"
|
|
if [ -f /system/init -o -L /system/init ]; then
|
|
SYSTEM_ROOT=true
|
|
else
|
|
SYSTEM_ROOT=false
|
|
grep ' / ' /proc/mounts | grep -qv 'rootfs' || grep -q ' /system_root ' /proc/mounts && SYSTEM_ROOT=true
|
|
fi
|
|
|
|
if [ -z $KEEPVERITY ]; then
|
|
if $SYSTEM_ROOT; then
|
|
KEEPVERITY=true
|
|
echo "[*] System-as-root, keep dm/avb-verity"
|
|
else
|
|
KEEPVERITY=false
|
|
fi
|
|
fi
|
|
|
|
ISENCRYPTED=false
|
|
grep ' /data ' /proc/mounts | grep -q 'dm-' && ISENCRYPTED=true
|
|
[ "$(getprop ro.crypto.state)" = "encrypted" ] && ISENCRYPTED=true
|
|
|
|
if [ -z $KEEPFORCEENCRYPT ]; then
|
|
# No data access means unable to decrypt in recovery
|
|
if $ISENCRYPTED || ! $DATA; then
|
|
KEEPFORCEENCRYPT=true
|
|
echo "[-] Encrypted data, keep forceencrypt"
|
|
else
|
|
KEEPFORCEENCRYPT=false
|
|
fi
|
|
fi
|
|
|
|
RECOVERYMODE=false
|
|
|
|
if [[ $API -eq 28 ]]; then
|
|
RECOVERYMODE=true
|
|
fi
|
|
|
|
export RECOVERYMODE
|
|
export KEEPVERITY
|
|
export KEEPFORCEENCRYPT
|
|
echo "[*] RECOVERYMODE=$RECOVERYMODE"
|
|
echo "[-] KEEPVERITY=$KEEPVERITY"
|
|
echo "[*] KEEPFORCEENCRYPT=$KEEPFORCEENCRYPT"
|
|
}
|
|
|
|
copyARCHfiles() {
|
|
BINDIR=$BASEDIR/lib/$ABI
|
|
ASSETSDIR=$BASEDIR/assets
|
|
STUBAPK=false
|
|
|
|
if [ -e $BINDIR/libstub.so ]; then
|
|
ABI=$ARCH32
|
|
BINDIR=$BASEDIR/lib/$ABI
|
|
echo "[*] No 64-Bit Binarys found, please consider Magisk Alpha"
|
|
elif $IS64BIT && ! $IS64BITONLY; then
|
|
echo "[*] copy $ARCH32 files to $BINDIR"
|
|
cp $BASEDIR/lib/$ARCH32/lib*32.so $BINDIR 2>/dev/null
|
|
fi
|
|
|
|
cd $BINDIR
|
|
for file in lib*.so; do mv "$file" "${file:3:${#file}-6}"; done
|
|
cd $BASEDIR
|
|
echo "[-] copy all $ABI files from $BINDIR to $BASEDIR"
|
|
cp $BINDIR/* $BASEDIR 2>/dev/null
|
|
|
|
if [ -e $ASSETSDIR/stub.apk ]; then
|
|
echo "[-] copy 'stub.apk' from $ASSETSDIR to $BASEDIR"
|
|
cp $ASSETSDIR/stub.apk $BASEDIR 2>/dev/null
|
|
STUBAPK=true
|
|
fi
|
|
|
|
chmod -R 755 $BASEDIR
|
|
export STUBAPK
|
|
}
|
|
|
|
api_level_arch_detect() {
|
|
echo "[-] Api Level Arch Detect"
|
|
# Detect version and architecture
|
|
# To select the right files for the patching
|
|
|
|
ABI=$(getprop ro.product.cpu.abi)
|
|
ABILIST32=$(getprop ro.product.cpu.abilist32)
|
|
ABILIST64=$(getprop ro.product.cpu.abilist64)
|
|
|
|
API=$(getprop ro.build.version.sdk)
|
|
FIRSTAPI=$(getprop ro.product.first_api_level)
|
|
|
|
AVERSION=$(getprop ro.build.version.release)
|
|
|
|
IS64BIT=false
|
|
IS64BITONLY=false
|
|
IS32BITONLY=false
|
|
|
|
if [ "$ABI" = "x86" ]; then
|
|
ARCH=x86
|
|
ARCH32=x86
|
|
elif [ "$ABI" = "arm64-v8a" ]; then
|
|
ARCH=arm64
|
|
ARCH32=armeabi-v7a
|
|
IS64BIT=true
|
|
elif [ "$ABI" = "x86_64" ]; then
|
|
ARCH=x64
|
|
ARCH32=x86
|
|
IS64BIT=true
|
|
else
|
|
ARCH=arm
|
|
ABI=armeabi-v7a
|
|
ABI32=armeabi-v7a
|
|
IS64BIT=false
|
|
fi
|
|
|
|
if [ -z "$ABILIST32" ]; then
|
|
IS64BITONLY=true
|
|
fi
|
|
|
|
if [ -z "$ABILIST64" ]; then
|
|
IS32BITONLY=true
|
|
fi
|
|
|
|
if $IS64BITONLY || $IS32BITONLY ; then
|
|
echo "[-] Device Platform is $ARCH only"
|
|
else
|
|
echo "[-] Device Platform: $ARCH"
|
|
echo "[-] ARCH32 $ARCH32"
|
|
fi
|
|
|
|
echo "[-] Device SDK API: $API"
|
|
echo "[-] First API Level: $FIRSTAPI"
|
|
echo "[-] The AVD runs on Android $AVERSION"
|
|
|
|
[ -d /system/lib64 ] && IS64BIT=true || IS64BIT=false
|
|
|
|
export ARCH
|
|
export ARCH32
|
|
export IS64BIT
|
|
export IS64BITONLY
|
|
export IS32BITONLY
|
|
export ABI
|
|
export API
|
|
export FIRSTAPI
|
|
export AVERSION
|
|
}
|
|
|
|
abort_script() {
|
|
echo "[!] aborting the script"
|
|
exit 1
|
|
}
|
|
|
|
compression_method() {
|
|
local FILE="$1"
|
|
local FIRSTFILEBYTES
|
|
local METHOD_LZ4="02214c18"
|
|
local METHOD_GZ="1f8b0800"
|
|
local ENDG=""
|
|
FIRSTFILEBYTES=$(xxd -p -c8 -l8 "$FILE")
|
|
FIRSTFILEBYTES="${FIRSTFILEBYTES:0:8}"
|
|
|
|
if [ "$FIRSTFILEBYTES" == "$METHOD_LZ4" ]; then
|
|
ENDG=".lz4"
|
|
elif [ "$FIRSTFILEBYTES" == "$METHOD_GZ" ]; then
|
|
ENDG=".gz"
|
|
fi
|
|
echo "$ENDG"
|
|
}
|
|
|
|
detect_ramdisk_compression_method() {
|
|
echo "[*] Detecting ramdisk.img compression"
|
|
RDF=$BASEDIR/ramdisk.img
|
|
CPIO=$BASEDIR/ramdisk.cpio
|
|
CPIOORIG=$BASEDIR/ramdisk.cpio.orig
|
|
|
|
local FIRSTFILEBYTES
|
|
local METHOD_LZ4="02214c18"
|
|
local METHOD_GZ="1f8b0800"
|
|
COMPRESS_SIGN=""
|
|
FIRSTFILEBYTES=$(xxd -p -c8 -l8 "$RDF")
|
|
FIRSTFILEBYTES="${FIRSTFILEBYTES:0:8}"
|
|
RAMDISK_LZ4=false
|
|
RAMDISK_GZ=false
|
|
ENDG=""
|
|
METHOD=""
|
|
|
|
if [ "$FIRSTFILEBYTES" == "$METHOD_LZ4" ]; then
|
|
ENDG=".lz4"
|
|
METHOD="lz4_legacy"
|
|
RAMDISK_LZ4=true
|
|
mv $RDF $RDF$ENDG
|
|
RDF=$RDF$ENDG
|
|
COMPRESS_SIGN="$METHOD_LZ4"
|
|
elif [ "$FIRSTFILEBYTES" == "$METHOD_GZ" ]; then
|
|
ENDG=".gz"
|
|
METHOD="gzip"
|
|
RAMDISK_GZ=true
|
|
mv $RDF $RDF$ENDG
|
|
#cp $RDF $RDF$ENDG
|
|
COMPRESS_SIGN="$METHOD_GZ"
|
|
fi
|
|
|
|
if [ "$ENDG" == "" ]; then
|
|
echo "[!] Ramdisk.img uses UNKNOWN compression $FIRSTFILEBYTES"
|
|
abort_script
|
|
fi
|
|
|
|
echo "[!] Ramdisk.img uses $METHOD compression"
|
|
}
|
|
|
|
runMagisk_to_Patch_fake_boot_img() {
|
|
am force-stop $PKG_NAME
|
|
echo "[-] Starting Magisk"
|
|
monkey -p $PKG_NAME -c android.intent.category.LAUNCHER 1 > /dev/null 2>&1
|
|
echo "[*] Install/Patch $FBI and hit Enter when done(max. 60s)"
|
|
read -t 60 proceed
|
|
case $proceed in
|
|
*)
|
|
;;
|
|
esac
|
|
}
|
|
|
|
detecting_users() {
|
|
local userID=""
|
|
local userZero=0
|
|
echo "[*] Detecting current user"
|
|
userID=$(am get-current-user)
|
|
echo "[-] Current user $userID"
|
|
if [ "$userID" != "$userZero" ]; then
|
|
echo "[-] Switching to user $userZero"
|
|
am switch-user $userZero
|
|
userID=$(am get-current-user)
|
|
echo "[-] Current user $userID"
|
|
fi
|
|
}
|
|
|
|
generate_build_prop() {
|
|
echo "[*] generating Build.prop"
|
|
local BPR=$BASEDIR/build.prop
|
|
local recfstab=$BASEDIR/recovery.fstab
|
|
getprop > $BPR
|
|
sed -i -e 's/: /=/g' -e 's/\[//g' -e 's/\]//g' $BPR
|
|
|
|
echo "[*] generating recovery.fstab from fstab.ranchu"
|
|
cp /system/vendor/etc/fstab.ranchu $recfstab
|
|
|
|
echo "[-] adding Build.prop and recovery.fstab to Stock Ramdisk"
|
|
$BASEDIR/magiskboot cpio $CPIO \
|
|
"add 0644 system/build.prop build.prop" \
|
|
"add 0644 system/etc/recovery.fstab recovery.fstab"
|
|
#exit
|
|
#BASEDIR=$(pwd)
|
|
}
|
|
|
|
writeLittleEndian() {
|
|
printf "\x${1:6:2}\x${1:4:2}\x${1:2:2}\x${1:0:2}"
|
|
}
|
|
|
|
create_fake_boot_img() {
|
|
|
|
if $DEBUG; then
|
|
generate_build_prop
|
|
fi
|
|
|
|
echo "[*] Creating a fake Boot.img"
|
|
FBHI=$BASEDIR/fakebootheader.img
|
|
FBI=$SDCARD/fakeboot.img
|
|
RAMDISK_SZ="$(printf '%08x' $(stat -c%s $CPIO))"
|
|
PAGESIZE=2048
|
|
PAGESIZE_HEX="$(printf '%08x' $PAGESIZE)"
|
|
|
|
echo "[-] removing old $FBI"
|
|
rm -f $FBI $RDF
|
|
|
|
printf "\x41\x4E\x44\x52\x4F\x49\x44\x21" > $FBHI # ANDROID!
|
|
printf "\x00\x00\x00\x00\x00\x00\x00\x00" >> $FBHI # HEADER_VER KERNEL_SZ
|
|
writeLittleEndian $RAMDISK_SZ >> $FBHI # RAMDISK_SZ
|
|
|
|
printf "\x00\x00\x00\x00" >> $FBHI # SECOND_SZ
|
|
printf "\x00\x00\x00\x00\x00\x00\x00\x00" >> $FBHI # EXTRA_SZ
|
|
printf "\x00\x00\x00\x00" >> $FBHI
|
|
writeLittleEndian $PAGESIZE_HEX >> $FBHI # PAGESIZE_HEX
|
|
|
|
echo "[!] Only a minimal header is required for Magisk to repack the ramdisk"
|
|
#mv $RDF $CPIO
|
|
|
|
echo "[*] repacking ramdisk.img into $FBI"
|
|
$BASEDIR/magiskboot repack $FBHI $FBI > /dev/null 2>&1
|
|
|
|
test -f "$FBI"
|
|
RESULT="$?"
|
|
if [[ "$RESULT" != "0" ]]; then
|
|
echo "[*] $FBI could not be created"
|
|
echo "[-] Magisk expects a more complete boot.img header as source"
|
|
|
|
# fill 00 (to Pagesize 2048)
|
|
truncate -s $PAGESIZE $FBHI
|
|
|
|
echo "[*] Adding $CPIO to fakeboot.img header"
|
|
cat $CPIO >> $FBHI
|
|
|
|
echo "[*] Checking filesize Padding for Pagesize 2048"
|
|
|
|
FBHI_SZ=$(stat -c%s $FBHI)
|
|
FBHI_PAD_SZ=$(( FBHI_SZ / $PAGESIZE ))
|
|
FBHI_PAD_SZ=$(( FBHI_PAD_SZ * $PAGESIZE ))
|
|
|
|
if [[ ! $FBHI_PAD_SZ -eq $FBHI_SZ ]]; then
|
|
echo "[*] Padding filesize to match Pagesize of 2048 Bytes"
|
|
FBHI_PAD_SZ=$(( FBHI_SZ / $PAGESIZE +1))
|
|
FBHI_PAD_SZ=$(( FBHI_PAD_SZ * $PAGESIZE ))
|
|
truncate -s $FBHI_PAD_SZ $FBHI
|
|
fi
|
|
|
|
echo "[-] repacking ramdisk.img into $FBI with the more complete header"
|
|
$BASEDIR/magiskboot repack $FBHI $FBI > /dev/null 2>&1
|
|
|
|
test -f "$FBI"
|
|
RESULT="$?"
|
|
if [[ "$RESULT" != "0" ]]; then
|
|
echo "[!] $FBI could not be created"
|
|
abort_script
|
|
fi
|
|
fi
|
|
echo "[!] $FBI created"
|
|
|
|
InstallMagiskTemporarily
|
|
detecting_users
|
|
runMagisk_to_Patch_fake_boot_img
|
|
RemoveTemporarilyMagisk
|
|
}
|
|
|
|
unpack_patched_ramdisk_from_fake_boot_img() {
|
|
|
|
if [ "$MagiskPatchedFiles" != "" ]; then
|
|
echo "[!] magisk_patched file(s) could be found!"
|
|
for file in `ls -tu $SDCARD/*magisk_patched*`; do
|
|
MagiskPatched=$file
|
|
break
|
|
done
|
|
echo "[*] unpacking latest $MagiskPatched"
|
|
$BASEDIR/magiskboot unpack $MagiskPatched > /dev/null 2>&1
|
|
echo "[-] deleting all magisk_patched files"
|
|
for file in `ls -tu $SDCARD/*magisk_patched*`; do
|
|
rm -f $file
|
|
done
|
|
else
|
|
echo "[!] No magisk_patched file could be found!"
|
|
abort_script
|
|
fi
|
|
}
|
|
|
|
process_fake_boot_img() {
|
|
|
|
SDCARD=/sdcard/Download
|
|
|
|
echo "[*] Processing fake Boot.img"
|
|
MagiskPatchedFiles=$(ls "$SDCARD"/*magisk_patched*) > /dev/null 2>&1
|
|
if [ "$MagiskPatchedFiles" != "" ]; then
|
|
echo "[!] external magisk_patched file(s) could be found!"
|
|
unpack_patched_ramdisk_from_fake_boot_img
|
|
else
|
|
create_fake_boot_img
|
|
MagiskPatchedFiles=$(ls "$SDCARD"/*magisk_patched*) > /dev/null 2>&1
|
|
unpack_patched_ramdisk_from_fake_boot_img
|
|
fi
|
|
}
|
|
|
|
# requires additional setup
|
|
construct_environment() {
|
|
ROOT=`su -c "id -u"` 2>/dev/null
|
|
|
|
if [[ "$ROOT" == "" ]]; then
|
|
ROOT=$(id -u)
|
|
fi
|
|
|
|
echo "[-] Constructing environment - PAY ATTENTION to the AVDs Screen"
|
|
if [[ $ROOT -eq 0 ]]; then
|
|
echo "[!] we are root"
|
|
local BBBIN=$BB
|
|
local COMMONDIR=$BASEDIR/assets
|
|
local NVBASE=/data/adb
|
|
local MAGISKBIN=$NVBASE/magisk
|
|
|
|
`su -c "rm -rf $MAGISKBIN/* 2>/dev/null && \
|
|
mkdir -p $MAGISKBIN 2>/dev/null && \
|
|
cp -af $BINDIR/. $COMMONDIR/. $BBBIN $MAGISKBIN && \
|
|
chown root.root -R $MAGISKBIN && \
|
|
chmod -R 755 $MAGISKBIN && \
|
|
rm -rf $BASEDIR 2>/dev/null && \
|
|
reboot \
|
|
"`
|
|
fi
|
|
|
|
echo "[!] not root yet"
|
|
echo "[!] Couldn't construct environment"
|
|
echo "[!] Double Check Root Access"
|
|
echo "[!] Re-Run Script with clean ramdisk.img and try again"
|
|
abort_script
|
|
}
|
|
|
|
checkfile() {
|
|
#echo "checkfile $1"
|
|
if [ -r "$1" ]; then
|
|
#echo "File exists and is readable"
|
|
if [ -s "$1" ]; then
|
|
#echo "and has a size greater than zero"
|
|
if [ -w "$1" ]; then
|
|
#echo "and is writable"
|
|
if [ -f "$1" ]; then
|
|
#echo "and is a regular file."
|
|
return 1
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
# If all is done well so far, you can install some APK's to the AVD
|
|
# every APK file in the Apps DIR will be (re)installed
|
|
# Like magisk.apk etc.
|
|
install_apps() {
|
|
local ADBECHO=""
|
|
APPS="Apps/*"
|
|
echo "[-] Install all APKs placed in the Apps folder"
|
|
FILES=$APPS
|
|
|
|
for f in $FILES; do
|
|
echo "[*] Trying to install $f"
|
|
ADBECHO=""
|
|
while [[ "$ADBECHO" != *"Success"* ]]; do
|
|
ADBECHO=$(adb install -r -d "$f" 2>&1)
|
|
if [[ "$ADBECHO" == *"INSTALL_FAILED_UPDATE_INCOMPATIBLE"* ]]; then
|
|
echo "$ADBECHO" | while read I; do echo "[*] $I"; done
|
|
Package=
|
|
for I in $ADBECHO; do
|
|
if [[ "$Package" == *"Package"* ]]; then
|
|
echo "[*] Need to uninstall $I first"
|
|
ADBECHO=$(adb uninstall $I 2>&1)
|
|
echo "$ADBECHO" | while read I; do echo "[*] $I"; done
|
|
ADBECHO=$(adb install -r -d "$f" 2>&1)
|
|
break
|
|
fi
|
|
Package=$I
|
|
done
|
|
fi
|
|
done
|
|
echo "$ADBECHO" | while read I; do echo "[*] $I"; done
|
|
done
|
|
}
|
|
|
|
pushtoAVD() {
|
|
local SRC=""
|
|
local DST="$2"
|
|
local ADBPUSHECHO=""
|
|
SRC=${1##*/}
|
|
|
|
if [[ "$DST" == "" ]]; then
|
|
echo "[*] Push $SRC into $ADBBASEDIR"
|
|
ADBPUSHECHO=$(adb push "$1" $ADBBASEDIR 2>/dev/null)
|
|
else
|
|
echo "[*] Push $SRC into $ADBBASEDIR/$DST"
|
|
ADBPUSHECHO=$(adb push "$1" $ADBBASEDIR/$DST 2>/dev/null)
|
|
fi
|
|
|
|
echo "[-] $ADBPUSHECHO"
|
|
}
|
|
|
|
pullfromAVD() {
|
|
local SRC=""
|
|
local DST=""
|
|
local ADBPULLECHO=""
|
|
SRC=${1##*/}
|
|
DST=${2##*/}
|
|
ADBPULLECHO=$(adb pull $ADBBASEDIR/$SRC "$2" 2>/dev/null)
|
|
if [[ ! "$ADBPULLECHO" == *"error"* ]]; then
|
|
echo "[*] Pull $SRC into $DST"
|
|
echo "[-] $ADBPULLECHO"
|
|
fi
|
|
}
|
|
|
|
create_backup() {
|
|
local FILE=""
|
|
local FILEPATH=""
|
|
local FILENAME=""
|
|
local BACKUPFILE=""
|
|
FILE="$1"
|
|
FILEPATH=${FILE%/*}
|
|
FILENAME=${FILE##*/}
|
|
BACKUPFILE="$FILENAME.backup"
|
|
|
|
cd "$FILEPATH" > /dev/null
|
|
# If no backup file exist, create one
|
|
if ( checkfile $BACKUPFILE -eq 0 ); then
|
|
echo "[*] create Backup File of $FILENAME"
|
|
cp $FILENAME $BACKUPFILE
|
|
else
|
|
echo "[-] $FILENAME Backup exists already"
|
|
fi
|
|
cd - > /dev/null
|
|
}
|
|
|
|
restore_backups() {
|
|
local BACKUPFILE=""
|
|
local RESTOREFILE=""
|
|
|
|
cd "$1" > /dev/null
|
|
for f in $(find . -type f -name '*.backup'); do
|
|
BACKUPFILE="$f"
|
|
RESTOREFILE="${BACKUPFILE%.backup}"
|
|
echo "[!] Restoring ${BACKUPFILE##*/} to ${RESTOREFILE##*/}"
|
|
cp $BACKUPFILE $RESTOREFILE
|
|
done
|
|
cd - > /dev/null
|
|
|
|
if [ "$f" == "" ]; then
|
|
echo "[*] No Backup(s) to restore"
|
|
else
|
|
echo "[*] Backups still remain in place"
|
|
fi
|
|
exit 0
|
|
}
|
|
|
|
toggle_Ramdisk() {
|
|
|
|
#AVDPATHWITHRDFFILE="$1"
|
|
#AVDPATH=${AVDPATHWITHRDFFILE%/*}
|
|
#RDFFILE=${AVDPATHWITHRDFFILE##*/}
|
|
#RESTOREPATH=$AVDPATH
|
|
|
|
local RamdiskFile="$AVDPATHWITHRDFFILE"
|
|
local PatchedFile="$AVDPATHWITHRDFFILE.patched"
|
|
local BackupFile="$AVDPATHWITHRDFFILE.backup"
|
|
|
|
local hasBackup=false
|
|
local hasPatched=false
|
|
|
|
if ( checkfile "$BackupFile" -eq 0 ); then
|
|
echo "[!] we need a valid backup file to proceed"
|
|
exit 0
|
|
fi
|
|
|
|
echo "[-] Toggle Ramdisk"
|
|
if ( checkfile "$PatchedFile" -eq 0 ); then
|
|
echo "[*] Pushing patched Ramdisk into Stack"
|
|
mv "$RamdiskFile" "$PatchedFile"
|
|
echo "[*] Popping original Ramdisk from Backup"
|
|
cp "$BackupFile" "$RamdiskFile"
|
|
else
|
|
echo "[*] Popping patched Ramdisk back from Stack"
|
|
mv -f "$PatchedFile" "$RamdiskFile"
|
|
fi
|
|
exit 0
|
|
}
|
|
|
|
TestADB() {
|
|
|
|
local ADB_EX=""
|
|
local exportedADB=false
|
|
|
|
while true; do
|
|
echo "[-] Test if ADB SHELL is working"
|
|
ADBWORKS=$(which adb)
|
|
if [ "$ADBWORKS" == *"not found"* ] || [ "$ADBWORKS" == "" ]; then
|
|
if [ ! -d "$ANDROIDHOME/$ADB_DIR" ]; then
|
|
echo "[!] ADB not found, please install and add it to your \$PATH"
|
|
exit
|
|
fi
|
|
|
|
cd "$ANDROIDHOME" > /dev/null
|
|
for adb in $(find "$ADB_DIR" -type f -name adb); do
|
|
ADB_EX="$ANDROIDHOME/$adb"
|
|
done
|
|
cd - > /dev/null
|
|
|
|
if [[ "$ADB_EX" == "" ]]; then
|
|
echo "[!] ADB binary not found in $ENVVAR/$ADB_DIR"
|
|
exit
|
|
fi
|
|
|
|
echo "[!] ADB is not in your Path, try to:"
|
|
echo ""
|
|
echo "export PATH=$ENVVAR/$ADB_DIR:\$PATH"
|
|
echo ""
|
|
|
|
if $exportedADB; then
|
|
echo "[!] export didn't work'"
|
|
break
|
|
fi
|
|
|
|
if ( ! checkfile "$ADB_EX" -eq 0 ); then
|
|
echo "[*] setting it, just during this session, for you"
|
|
export "PATH=$ANDROIDHOME/$ADB_DIR:$PATH"
|
|
exportedADB=true
|
|
fi
|
|
else
|
|
break
|
|
fi
|
|
done
|
|
|
|
ADBWORKS=$(adb shell 'echo true' 2>/dev/null)
|
|
if [ -z "$ADBWORKS" ]; then
|
|
echo "[!] no ADB connection possible"
|
|
exit
|
|
elif [[ "$ADBWORKS" == "true" ]]; then
|
|
echo "[*] ADB connection possible"
|
|
fi
|
|
}
|
|
|
|
MakeBlueStacksRW() {
|
|
|
|
if ( checkfile "$BLUESTACKSPATH/$AVBOXFILE" -eq 0 ); then
|
|
echo "[!] $AVBOXFILE not found"
|
|
echo "[!] check your BlueStacks installation"
|
|
exit 0
|
|
fi
|
|
echo "[!] $AVBOXFILE found"
|
|
create_backup "$AVBOX"
|
|
echo "[*] Changing $ROOTVDIFILE type to \"Normal\""
|
|
sed 's,location="Root.vdi" format="VDI" type="Readonly",location="Root.vdi" format="VDI" type="Normal",' $AVBOX > $AVBOX".edit"
|
|
mv $AVBOX".edit" $AVBOX
|
|
}
|
|
|
|
ShutDownAVD() {
|
|
|
|
if ( "$BLUESTACKS" ); then
|
|
echo "[-] Shut-Down & Reboot BlueStacks and see if it worked"
|
|
echo "[-] Root and Su with Magisk for BlueStacks"
|
|
|
|
APPNAME=BlueStacks.app
|
|
if [ $(ps aux | grep -v grep | grep -c $APPNAME) -gt 0 ]; then
|
|
echo "[-] Trying to shut down BlueStacks"
|
|
pkill -x BlueStacks
|
|
if [ "$?" == "0" ]; then
|
|
echo "[*] Shut down Signal were send"
|
|
fi
|
|
echo "[!] If BlueStacks doesn't shut down, try it manually!"
|
|
fi
|
|
echo "[*] If BlueStacks Home Screen is closing, run Magisk from the Terminal and hide it"
|
|
echo "adb shell monkey -p com.topjohnwu.magisk -c android.intent.category.LAUNCHER 1"
|
|
else
|
|
echo "[-] Shut-Down & Reboot (Cold Boot Now) the AVD and see if it worked"
|
|
echo "[-] Root and Su with Magisk for Android Studio AVDs"
|
|
|
|
ADBPULLECHO=$(adb shell setprop sys.powerctl shutdown 2>/dev/null)
|
|
if [[ ! "$ADBPULLECHO" == *"error"* ]]; then
|
|
echo "[-] Trying to shut down the AVD"
|
|
fi
|
|
echo "[!] If the AVD doesn't shut down, try it manually!"
|
|
fi
|
|
echo "[-] Modded by NewBit XDA - Jan. 2021"
|
|
echo "[!] Huge Credits and big Thanks to topjohnwu, shakalaca, vvb2060 and HuskyDG"
|
|
}
|
|
|
|
GetAVDPKGRevision() {
|
|
local sourcepropfile="source.properties"
|
|
if [[ -d "$AVDPATH" ]]; then
|
|
cd "$AVDPATH" > /dev/null
|
|
# If a source.properties file exist, try to find the Pkg.Revision number
|
|
if ( ! checkfile $sourcepropfile -eq 0 ); then
|
|
echo "[-] source.properties file exist"
|
|
echo "[*] AVD system-image $(grep 'Pkg.Revision=' $sourcepropfile)"
|
|
fi
|
|
cd - > /dev/null
|
|
fi
|
|
}
|
|
|
|
CopyMagiskToAVD() {
|
|
# Set Folders and FileNames
|
|
echo "[*] Set Directorys"
|
|
if ( "$BLUESTACKS" ); then
|
|
# BlueStacks has its ramdisk.img within, no AVD Path needed
|
|
# but the VBOX container Root.vdi should be backuped
|
|
BLUESTACKSROOTVDIFILE=~/Library/BlueStacks/Android/Root.vdi
|
|
AVBOX=~/Library/BlueStacks/Android/Android.vbox
|
|
AVBOXFILE=${AVBOX##*/}
|
|
BLUESTACKSPATH=${BLUESTACKSROOTVDIFILE%/*}
|
|
ROOTVDIFILE=${BLUESTACKSROOTVDIFILE##*/}
|
|
RESTOREPATH=$BLUESTACKSPATH
|
|
else
|
|
AVDPATHWITHRDFFILE="$ANDROIDHOME/$1"
|
|
AVDPATH=${AVDPATHWITHRDFFILE%/*}
|
|
RDFFILE=${AVDPATHWITHRDFFILE##*/}
|
|
RESTOREPATH=$AVDPATH
|
|
fi
|
|
|
|
if ( "$restore" ); then
|
|
restore_backups "$RESTOREPATH"
|
|
fi
|
|
|
|
if ( "$toggleRamdisk" ); then
|
|
toggle_Ramdisk "$RESTOREPATH"
|
|
fi
|
|
|
|
if ( "$BLUESTACKS" ); then
|
|
if ( checkfile "$BLUESTACKSPATH/$ROOTVDIFILE" -eq 0 ); then
|
|
echo "[!] $ROOTVDIFILE not found"
|
|
echo "[!] check your BlueStacks installation"
|
|
exit
|
|
fi
|
|
echo "[!] $ROOTVDIFILE found"
|
|
create_backup "$BLUESTACKSROOTVDIFILE"
|
|
MakeBlueStacksRW
|
|
fi
|
|
|
|
GetAVDPKGRevision
|
|
TestADB
|
|
|
|
# The Folder where the script was called from
|
|
ROOTAVD="`getdir "${BASH_SOURCE:-$0}"`"
|
|
MAGISKZIP=$ROOTAVD/Magisk.zip
|
|
|
|
# change to ROOTAVD directory
|
|
cd "$ROOTAVD"
|
|
|
|
# Kernel Names
|
|
BZFILE=$ROOTAVD/bzImage
|
|
KRFILE=kernel-ranchu
|
|
|
|
if ( "$InstallApps" ); then
|
|
install_apps
|
|
exit
|
|
fi
|
|
|
|
ADBWORKDIR=/data/data/com.android.shell
|
|
adb shell "cd $ADBWORKDIR" 2>/dev/null
|
|
|
|
if [ "$?" != "0" ]; then
|
|
echo "[!] $ADBWORKDIR doesn't exist, switching to tmp'"
|
|
ADBWORKDIR=/data/local/tmp
|
|
fi
|
|
|
|
ADBBASEDIR=$ADBWORKDIR/Magisk
|
|
echo "[-] In any AVD via ADB, you can execute code without root in $ADBWORKDIR"
|
|
|
|
echo "[*] Cleaning up the ADB working space"
|
|
adb shell rm -rf $ADBBASEDIR
|
|
|
|
echo "[*] Creating the ADB working space"
|
|
adb shell mkdir $ADBBASEDIR
|
|
|
|
# If Magisk.zip file doesn't exist, just ignore it
|
|
if ( ! checkfile "$MAGISKZIP" -eq 0 ); then
|
|
echo "[-] Magisk installer Zip exists already"
|
|
pushtoAVD "$MAGISKZIP"
|
|
fi
|
|
|
|
# Proceed with ramdisk
|
|
if "$RAMDISKIMG"; then
|
|
# Is it a ramdisk named img file?
|
|
if [[ "$RDFFILE" != ramdisk*.img ]]; then
|
|
echo "[!] please give a path to a ramdisk file"
|
|
exit
|
|
fi
|
|
|
|
create_backup "$AVDPATHWITHRDFFILE"
|
|
pushtoAVD "$AVDPATHWITHRDFFILE" "ramdisk.img"
|
|
|
|
if ( "$InstallKernelModules" ); then
|
|
INITRAMFS=$ROOTAVD/initramfs.img
|
|
if ( ! checkfile "$INITRAMFS" -eq 0 ); then
|
|
pushtoAVD "$INITRAMFS"
|
|
fi
|
|
fi
|
|
|
|
if ( "$AddRCscripts" ); then
|
|
for f in $ROOTAVD/*.rc; do
|
|
pushtoAVD "$f"
|
|
done
|
|
pushtoAVD "$ROOTAVD/sbin"
|
|
fi
|
|
fi
|
|
|
|
pushtoAVD "rootAVD.sh"
|
|
|
|
if ( "$UpdateBusyBoxScript" ); then
|
|
pushtoAVD "libbusybox*.so"
|
|
fi
|
|
|
|
echo "[-] run the actually Boot/Ramdisk/Kernel Image Patch Script"
|
|
echo "[*] from Magisk by topjohnwu and modded by NewBit XDA"
|
|
|
|
adb shell sh $ADBBASEDIR/rootAVD.sh $@
|
|
if [ "$?" == "0" ]; then
|
|
|
|
if ( "$UpdateBusyBoxScript" ); then
|
|
pullfromAVD "bbscript.sh" "rootAVD.sh"
|
|
chmod +x rootAVD.sh
|
|
exit
|
|
fi
|
|
|
|
if ( ! "$DEBUG" && "$BLUESTACKS" ); then
|
|
pullfromAVD "Magisk.apk" "Apps/"
|
|
pullfromAVD "Magisk.zip" "$ROOTAVD"
|
|
echo "[-] Clean up the ADB working space"
|
|
adb shell rm -rf $ADBBASEDIR
|
|
install_apps
|
|
ShutDownAVD
|
|
adb kill-server
|
|
fi
|
|
|
|
# In Debug-Mode we can skip parts of the script
|
|
if ( ! "$DEBUG" && "$RAMDISKIMG" ); then
|
|
|
|
pullfromAVD "ramdiskpatched4AVD.img" "$AVDPATHWITHRDFFILE"
|
|
pullfromAVD "Magisk.apk" "Apps/"
|
|
pullfromAVD "Magisk.zip" "$ROOTAVD"
|
|
|
|
if ( "$InstallPrebuiltKernelModules" ); then
|
|
pullfromAVD "$BZFILE" "$ROOTAVD"
|
|
InstallKernelModules=true
|
|
fi
|
|
|
|
if ( "$InstallKernelModules" ); then
|
|
if ( ! checkfile "$BZFILE" -eq 0 ); then
|
|
create_backup "$AVDPATH/$KRFILE"
|
|
echo "[*] Copy $BZFILE (Kernel) into kernel-ranchu"
|
|
cp $BZFILE $AVDPATH/$KRFILE
|
|
if [ "$?" == "0" ]; then
|
|
rm -f $BZFILE $INITRAMFS
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
echo "[-] Clean up the ADB working space"
|
|
adb shell rm -rf $ADBBASEDIR
|
|
|
|
install_apps
|
|
ShutDownAVD
|
|
fi
|
|
fi
|
|
}
|
|
|
|
###################################################
|
|
# Method to extract specified field data from json
|
|
# Globals: None
|
|
# Arguments: 2
|
|
# ${1} - value of field to fetch from json
|
|
# ${2} - Optional, nth number of value from extracted values, by default shows all.
|
|
# Input: file | here string | pipe
|
|
# _json_value "Arguments" < file
|
|
# _json_value "Arguments <<< "${varibale}"
|
|
# echo something | _json_value "Arguments"
|
|
# Result: print extracted value
|
|
###################################################
|
|
json_value() {
|
|
$BB grep -o "\"""${1}""\"\:.*" | $BB sed -e "s/.*\"""${1}""\": //" -e 's/[",]*$//' -e 's/["]*$//' -e 's/[,]*$//' -e "s/\"//" -n -e "${2}"p
|
|
}
|
|
|
|
CheckAVDIsOnline() {
|
|
if [ -z $AVDIsOnline ]; then
|
|
echo "[-] Checking AVDs Internet connection..."
|
|
AVDIsOnline=false
|
|
$BB timeout 3 $BB wget -q --spider --no-check-certificate http://github.com > /dev/null 2>&1
|
|
if [ $? -eq 0 ]; then
|
|
AVDIsOnline=true
|
|
else
|
|
echo "[-] Checking AVDs Internet connection another way..."
|
|
echo -e "GET http://google.com HTTP/1.0\n\n" | $BB timeout 3 $BB nc -v google.com 80 > /dev/null 2>&1
|
|
if [ $? -eq 0 ]; then
|
|
AVDIsOnline=true
|
|
fi
|
|
fi
|
|
$AVDIsOnline && echo "[!] AVD is online" || echo "[!] AVD is offline"
|
|
fi
|
|
export AVDIsOnline
|
|
}
|
|
|
|
GetPrettyVer() {
|
|
if echo $1 | $BB grep -q '\.'; then
|
|
PRETTY_VER=$1
|
|
else
|
|
PRETTY_VER="$1($2)"
|
|
fi
|
|
echo "$PRETTY_VER"
|
|
}
|
|
|
|
DownLoadFile() {
|
|
CheckAVDIsOnline
|
|
if ("$AVDIsOnline"); then
|
|
local URL="$1"
|
|
local SRC="$2"
|
|
local DST="$3"
|
|
|
|
OF=$BASEDIR/download.tmp
|
|
rm -f $OF
|
|
BS=1024
|
|
CUTOFF=100
|
|
|
|
if [ "$DST" == "" ]; then
|
|
DST=$BASEDIR/$SRC
|
|
else
|
|
DST=$BASEDIR/$DST
|
|
fi
|
|
#echo "[*] Downloading File $SRC"
|
|
$BB wget -q -O $DST --no-check-certificate $URL$SRC
|
|
RESULT="$?"
|
|
while [ $RESULT != "0" ]
|
|
do
|
|
echo "[!] Error while downloading File $SRC"
|
|
echo "[-] patching it together"
|
|
FSIZE=$(./busybox stat $DST -c %s)
|
|
if [ $FSIZE -gt $BS ]; then
|
|
COUNT=$(( FSIZE/BS ))
|
|
if [ $COUNT -gt $CUTOFF ]; then
|
|
COUNT=$(( COUNT - $CUTOFF ))
|
|
fi
|
|
fi
|
|
$BB dd if=$DST count=$COUNT bs=$BS of=$OF > /dev/null 2>&1
|
|
mv -f $OF $DST
|
|
$BB wget -q -O $DST --no-check-certificate $URL$SRC -c
|
|
RESULT="$?"
|
|
done
|
|
echo "[!] Downloading File $SRC complete!"
|
|
fi
|
|
}
|
|
|
|
GetUSBHPmod() {
|
|
USBHPZSDDL="/sdcard/Download/usbhostpermissons.zip"
|
|
USBHPZ="https://github.com/newbit1/usbhostpermissons/releases/download/v1.0/usbhostpermissons.zip"
|
|
if [ ! -e $USBHPZSDDL ]; then
|
|
echo "[*] Downloading USB HOST Permissions Module Zip"
|
|
$BB wget -q -O $USBHPZSDDL --no-check-certificate $USBHPZ
|
|
else
|
|
echo "[*] USB HOST Permissions Module Zip is already present"
|
|
fi
|
|
}
|
|
|
|
FetchMagiskDLData() {
|
|
local SRCURL="$1"
|
|
local CHANNEL="$2"
|
|
local JSON="$CHANNEL.json"
|
|
local VER=""
|
|
local VER_CODE=""
|
|
local DLL=""
|
|
local i=1
|
|
|
|
rm -rf *.json > /dev/null 2>&1
|
|
$BB wget -q --no-check-certificate $SRCURL$JSON
|
|
VER=$(json_value "version" < $JSON)
|
|
VER_CODE=$(json_value "versionCode" 1 < $JSON)
|
|
DLL=$(json_value "link" 1 < $JSON)
|
|
VER=$(GetPrettyVer $VER $VER_CODE)
|
|
|
|
if ! echo $DLL | $BB grep -q 'https'; then
|
|
DLL=$SRCURL$DLL
|
|
fi
|
|
|
|
if [ -e $MAGISK_DL_LINKS ]; then
|
|
echo $DLL >> $MAGISK_DL_LINKS
|
|
echo $VER >> $MAGISK_VERSIONS
|
|
echo $CHANNEL >> $MAGISK_CHANNEL
|
|
i=$($BB sed -n '$=' $MAGISK_DL_LINKS)
|
|
echo "[$i] $CHANNEL $VER" >> $MAGISK_MENU
|
|
else
|
|
if [[ "$MAGISK_LOCL_VER" != "" ]]; then
|
|
echo "local" > $MAGISK_DL_LINKS
|
|
echo $MAGISK_LOCL_VER > $MAGISK_VERSIONS
|
|
echo "local "$CHANNEL > $MAGISK_CHANNEL
|
|
echo "[$i] local $CHANNEL $MAGISK_LOCL_VER (ENTER)" > $MAGISK_MENU
|
|
i=$((i+1))
|
|
fi
|
|
echo $DLL >> $MAGISK_DL_LINKS
|
|
echo $VER >> $MAGISK_VERSIONS
|
|
echo $CHANNEL >> $MAGISK_CHANNEL
|
|
if [[ "$i" == "1" ]]; then
|
|
|
|
echo "[$i] $CHANNEL $VER (ENTER)" >> $MAGISK_MENU
|
|
else
|
|
#echo $CHANNEL > $MAGISK_CHANNEL
|
|
echo "[$i] $CHANNEL $VER" >> $MAGISK_MENU
|
|
fi
|
|
fi
|
|
rm -rf *.json > /dev/null 2>&1
|
|
}
|
|
|
|
FetchMagiskRLCommits() {
|
|
#$GITHUB $TJWCOMMITSURL $TJWBLOBURL $CHANNEL $TJWREPOURL
|
|
local DOMAIN="$1"
|
|
local COMMITSURL="$2"
|
|
local BLOBURL="$3"
|
|
local CHANNEL="$4"
|
|
local JSON="$CHANNEL.json"
|
|
local REPOURL="$5"
|
|
local COMMITS=""
|
|
|
|
rm -rf $JSON
|
|
$BB wget -q --no-check-certificate $DOMAIN$COMMITSURL$JSON
|
|
|
|
COMMITS=$($BB grep $BLOBURL $JSON | $BB sed -e 's,.*'"$BLOBURL"',,' -e 's,'"$JSON"'.*,,')
|
|
|
|
for commit in $COMMITS;do
|
|
FetchMagiskDLData $RAWGITHUB$REPOURL$commit $CHANNEL
|
|
done
|
|
}
|
|
|
|
CheckAvailableMagisks() {
|
|
|
|
MAGISK_VERSIONS=$BASEDIR/magisk_versions.txt
|
|
MAGISK_DL_LINKS=$BASEDIR/magisk_dl_links.txt
|
|
MAGISK_MENU=$BASEDIR/magisk_menu.txt
|
|
MAGISK_CHANNEL=$BASEDIR/magisk_channel.txt
|
|
|
|
local GITHUB="https://github.com/"
|
|
RAWGITHUB="https://raw.githubusercontent.com/"
|
|
local TJWREPOURL="topjohnwu/magisk-files/"
|
|
local TJWCOMMITSURL="topjohnwu/magisk-files/commits/master/"
|
|
local TJWBLOBURL="topjohnwu/magisk-files/blob/"
|
|
|
|
local VVB2060REPOURL="vvb2060/magisk_files/"
|
|
local VVB2060COMMITSURL="vvb2060/magisk_files/commits/alpha/"
|
|
local VVB2060BLOBURL="vvb2060/magisk_files/blob/"
|
|
local DLL_cnt=0
|
|
|
|
if [ -z $MAGISKVERCHOOSEN ]; then
|
|
|
|
UFSH=$BASEDIR/assets/util_functions.sh
|
|
OF=$BASEDIR/download.tmp
|
|
BS=1024
|
|
CUTOFF=100
|
|
|
|
if [ -e $UFSH ]; then
|
|
MAGISK_LOCL_VER=$($BB grep $UFSH -e "MAGISK_VER" -w | sed 's/^.*=//')
|
|
MAGISK_LOCL_VER_CODE=$($BB grep $UFSH -e "MAGISK_VER_CODE" -w | sed 's/^.*=//')
|
|
MAGISK_LOCL_VER=$(GetPrettyVer $MAGISK_LOCL_VER $MAGISK_LOCL_VER_CODE)
|
|
else
|
|
MAGISK_LOCL_VER=""
|
|
MAGISK_LOCL_VER_CODE=""
|
|
fi
|
|
|
|
CheckAVDIsOnline
|
|
if ("$AVDIsOnline"); then
|
|
echo "[!] Checking available Magisk Versions"
|
|
|
|
rm *.txt > /dev/null 2>&1
|
|
|
|
FetchMagiskDLData $RAWGITHUB$TJWREPOURL"master/" "stable"
|
|
FetchMagiskDLData $RAWGITHUB$TJWREPOURL"master/" "canary"
|
|
FetchMagiskDLData $RAWGITHUB$VVB2060REPOURL"alpha/" "alpha"
|
|
|
|
while :
|
|
do
|
|
DLL_cnt=$($BB sed -n '$=' $MAGISK_DL_LINKS)
|
|
echo "[?] Choose a Magisk Version to install and make it local"
|
|
echo "[s] (s)how all available Magisk Versions"
|
|
cat $MAGISK_MENU
|
|
read -t 10 choice
|
|
case $choice in
|
|
*)
|
|
if [[ "$choice" == "" ]]; then
|
|
choice=1
|
|
fi
|
|
|
|
if [[ $choice -gt 0 && $choice -le $DLL_cnt ]]; then
|
|
MAGISK_VER=$($BB sed "$choice"'!d' $MAGISK_VERSIONS)
|
|
MAGISK_CNL=$($BB sed "$choice"'!d' $MAGISK_CHANNEL)
|
|
echo "[-] You choose Magisk $MAGISK_CNL Version $MAGISK_VER"
|
|
|
|
MAGISK_DL=$($BB sed "$choice"'!d' $MAGISK_DL_LINKS)
|
|
if [[ "$MAGISK_DL" == "local" ]]; then
|
|
MAGISKVERCHOOSEN=false
|
|
fi
|
|
break
|
|
fi
|
|
|
|
if [[ "$choice" == "s" ]]; then
|
|
echo "[!] Fetching all available Magisk Versions..."
|
|
rm *.txt > /dev/null 2>&1
|
|
FetchMagiskRLCommits $GITHUB $TJWCOMMITSURL $TJWBLOBURL "stable" $TJWREPOURL
|
|
FetchMagiskRLCommits $GITHUB $TJWCOMMITSURL $TJWBLOBURL "canary" $TJWREPOURL
|
|
FetchMagiskRLCommits $GITHUB $VVB2060COMMITSURL $VVB2060BLOBURL "alpha" $VVB2060REPOURL
|
|
else
|
|
echo "invalid option $choice"
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
#exit
|
|
else
|
|
MAGISK_VER=$MAGISK_LOCL_VER
|
|
MAGISKVERCHOOSEN=false
|
|
fi
|
|
|
|
if [ -z $MAGISKVERCHOOSEN ]; then
|
|
echo "[*] Deleting local Magisk $MAGISK_LOCL_VER"
|
|
rm -rf $MZ
|
|
rm -rf *.apk
|
|
echo "[*] Downloading Magisk $MAGISK_CNL $MAGISK_VER"
|
|
$BB wget -q -O $MZ --no-check-certificate $MAGISK_DL
|
|
RESULT="$?"
|
|
while [ $RESULT != "0" ]; do
|
|
echo "[!] Error while downloading Magisk $MAGISK_CNL $MAGISK_VER"
|
|
echo "[-] patching it together"
|
|
FSIZE=$(./busybox stat $MZ -c %s)
|
|
if [ $FSIZE -gt $BS ]; then
|
|
COUNT=$(( FSIZE/BS ))
|
|
if [ $COUNT -gt $CUTOFF ]; then
|
|
COUNT=$(( COUNT - $CUTOFF ))
|
|
fi
|
|
fi
|
|
$BB dd if=$MZ count=$COUNT bs=$BS of=$OF > /dev/null 2>&1
|
|
mv -f $OF $MZ
|
|
$BB wget -q -O $MZ --no-check-certificate $MAGISK_DL -c
|
|
RESULT="$?"
|
|
done
|
|
echo "[!] Downloading Magisk $MAGISK_CNL $MAGISK_VER complete!"
|
|
MAGISKVERCHOOSEN=true
|
|
PrepBusyBoxAndMagisk
|
|
fi
|
|
|
|
# Call rootAVD with GetUSBHPmodZ to download the usbhostpermissons module
|
|
$GetUSBHPmodZ && $AVDIsOnline && GetUSBHPmod
|
|
fi
|
|
export MAGISK_VER
|
|
export MAGISKVERCHOOSEN
|
|
export UFSH
|
|
}
|
|
|
|
InstallMagiskTemporarily() {
|
|
magiskispreinstalled=false
|
|
|
|
echo "[*] Searching for pre installed Magisk Apps"
|
|
PKG_NAMES=$(pm list packages magisk | cut -f 2 -d ":") > /dev/null 2>&1
|
|
PKG_NAME=""
|
|
local MAGISK_PKG_VER_CODE=""
|
|
local MAGISK_ZIP_VER_CODE=""
|
|
|
|
if [[ "$PKG_NAMES" == "" ]]; then
|
|
echo "[!] Temporarily installing Magisk"
|
|
pm install -r $MZ >/dev/null 2>&1
|
|
PKG_NAME=$(pm list packages magisk | cut -f 2 -d ":") > /dev/null 2>&1
|
|
else
|
|
PKG_NAME=$PKG_NAMES
|
|
|
|
$(pm dump --help > /dev/null 2>&1)
|
|
RESULT="$?"
|
|
|
|
if [[ "$RESULT" == "0" ]]; then
|
|
MAGISK_PKG_VER_CODE=$(pm dump $PKG_NAME | grep versionCode= | sed 's/.*versionCode=\([0-9]\{1,\}\).*/\1/')
|
|
#echo "MAGISK_PKG_VER_CODE=$MAGISK_PKG_VER_CODE"
|
|
MAGISK_ZIP_VER_CODE=$(grep $UFSH -e "MAGISK_VER_CODE" -w | sed 's/^.*=//')
|
|
#echo "MAGISK_ZIP_VER_CODE=$MAGISK_ZIP_VER_CODE"
|
|
#echo "PKG_NAME=$PKG_NAME"
|
|
fi
|
|
|
|
if [[ "$MAGISK_PKG_VER_CODE" != "$MAGISK_ZIP_VER_CODE" ]]; then
|
|
echo "[-] Magisk Versions differ"
|
|
echo "[*] Exchanging pre installed Magisk App Version $MAGISK_PKG_VER_CODE"
|
|
pm clear $PKG_NAME >/dev/null 2>&1
|
|
pm uninstall $PKG_NAME >/dev/null 2>&1
|
|
echo "[-] with the Magisk App Version $MAGISK_ZIP_VER_CODE"
|
|
pm install -r $MZ >/dev/null 2>&1
|
|
PKG_NAME=$(pm list packages magisk | cut -f 2 -d ":") > /dev/null 2>&1
|
|
fi
|
|
if [[ "$MAGISK_PKG_VER_CODE" == "" ]]; then
|
|
echo "[!] Found a pre installed Magisk App, use it"
|
|
else
|
|
echo "[!] Found a pre installed Magisk App Version $MAGISK_PKG_VER_CODE, use it"
|
|
fi
|
|
magiskispreinstalled=true
|
|
fi
|
|
}
|
|
|
|
RemoveTemporarilyMagisk() {
|
|
|
|
if ! $magiskispreinstalled; then
|
|
echo "[!] Removing Temporarily installed Magisk"
|
|
pm clear $PKG_NAME >/dev/null 2>&1
|
|
pm uninstall $PKG_NAME >/dev/null 2>&1
|
|
fi
|
|
}
|
|
|
|
TestingBusyBoxVersion() {
|
|
|
|
local busyboxworks=false
|
|
local RESULT=""
|
|
echo "[*] Testing Busybox $1"
|
|
|
|
rm -fR $TMP
|
|
mkdir -p $TMP
|
|
|
|
cd $TMP > /dev/null
|
|
$(ASH_STANDALONE=1 $1 sh -c 'grep' > /dev/null 2>&1)
|
|
RESULT="$?"
|
|
if [[ "$RESULT" != "255" ]]; then
|
|
$($1 unzip $MZ -oq > /dev/null 2>&1)
|
|
RESULT="$?"
|
|
if [[ "$RESULT" != "0" ]]; then
|
|
echo "[!] Busybox binary does not support extracting Magisk.zip"
|
|
else
|
|
busyboxworks=true
|
|
fi
|
|
fi
|
|
cd - > /dev/null
|
|
|
|
rm -fR $TMP
|
|
$busyboxworks && return 0 || return 1
|
|
}
|
|
|
|
FindWorkingBusyBox() {
|
|
echo "[*] Finding a working Busybox Version"
|
|
local bbversion=""
|
|
local RESULT=""
|
|
|
|
for file in $(ls $BASEDIR/lib/*/*busybox*); do
|
|
chmod +x "$file"
|
|
bbversion=$($file | $file head -n 1)>/dev/null 2>&1
|
|
if [[ $bbversion == *"BusyBox"*"Magisk"*"multi-call"* ]]; then
|
|
TestingBusyBoxVersion "$file"
|
|
RESULT="$?"
|
|
if [[ "$RESULT" == "0" ]]; then
|
|
echo "[!] Found a working Busybox Version"
|
|
echo "[!] $bbversion"
|
|
export WorkingBusyBox="$file"
|
|
return
|
|
fi
|
|
fi
|
|
done
|
|
echo "[!] Can not find any working Busybox Version"
|
|
abort_script
|
|
}
|
|
|
|
ExtractMagiskViaPM() {
|
|
InstallMagiskTemporarily
|
|
PKG_PATH=$(pm path $PKG_NAME)
|
|
PKG_PATH=${PKG_PATH%/*}
|
|
PKG_PATH=${PKG_PATH#*:}
|
|
echo "[*] Copy Magisk Lib Files to workdir"
|
|
cp -Rf $PKG_PATH/lib $BASEDIR/
|
|
RemoveTemporarilyMagisk
|
|
}
|
|
|
|
DownloadUptoDateSript() {
|
|
echo "[*] Trying to Download the Up-To-Date Script Version"
|
|
|
|
local DLL_URL="https://github.com/newbit1/rootAVD/raw/master/"
|
|
local DLL_SCRIPT="rootAVD.sh"
|
|
local DLL_ROOTAVD_ZIP="https://github.com/newbit1/rootAVD/archive/refs/heads/master.zip"
|
|
local PKG_PATH=""
|
|
|
|
ExtractMagiskViaPM
|
|
FindWorkingBusyBox
|
|
CopyBusyBox
|
|
DownLoadFile $DLL_URL $DLL_SCRIPT
|
|
}
|
|
|
|
ExtractBusyboxFromScript() {
|
|
local BBSCR=$BASEDIR/bbscript.sh
|
|
local bblineoffset=""
|
|
local last_line=""
|
|
local bbline_cnt=""
|
|
cp $0 $BBSCR
|
|
|
|
bblineoffset=$(sed -n '/BUSYBOXBINARY/=' $BBSCR | sort -nr)
|
|
bbline_cnt=$(sed -n '/BUSYBOXBINARY/=' $BBSCR | sort -nr | sed -n '$=')
|
|
|
|
if [[ "$bbline_cnt" -gt "3" ]]; then
|
|
echo "[*] Extracting busybox from script ..."
|
|
for i in $bblineoffset;do
|
|
cp $BBSCR busybox
|
|
sed -i 1,"$i"'d',"$i"'q' $BB
|
|
$($BB >/dev/null 2>&1)
|
|
if [[ "$?" == "0" ]]; then
|
|
echo "[!] Found a working busybox Binary: $file"
|
|
echo "[!] $($BB | $BB head -n 1)"
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
|
|
$($BB >/dev/null 2>&1)
|
|
if [[ ! "$?" == "0" ]]; then
|
|
echo "[!] There is no busybox behind the script"
|
|
#echo "[!] Run rootAVD with UpdateBusyBoxScript first"
|
|
DownloadUptoDateSript
|
|
fi
|
|
}
|
|
|
|
UpdateBusyBoxToScript() {
|
|
local BBSCR=$BASEDIR/bbscript.sh
|
|
local FSIZE=""
|
|
local last_line=""
|
|
cp $0 $BBSCR
|
|
chmod +x libbusybox*.so
|
|
|
|
# Find the first working busybox binary
|
|
for file in libbusybox*.so; do
|
|
cp -fF $file $BB
|
|
$($BB >/dev/null 2>&1)
|
|
if [[ "$?" == "0" ]]; then
|
|
echo "[!] Found a working busybox Binary: $file"
|
|
echo "[!] $($BB | $BB head -n 1)"
|
|
break
|
|
fi
|
|
done
|
|
|
|
$($BB >/dev/null 2>&1)
|
|
if [[ ! "$?" == "0" ]]; then
|
|
echo "[!] Can't find a working busybox Binary"
|
|
exit 0
|
|
fi
|
|
|
|
# Add every provided busybox binary behind the script
|
|
for file in libbusybox*.so; do
|
|
echo "" >> $BBSCR
|
|
echo "###BUSYBOXBINARY###" >> $BBSCR
|
|
FSIZE=$(./busybox stat $BBSCR -c %s)
|
|
$BB dd if=$file oflag=seek_bytes seek=$FSIZE of=$BBSCR > /dev/null 2>&1
|
|
done
|
|
|
|
#sed -i "$((bblineoffset+1))","$last_line"'d' $BBSCR
|
|
}
|
|
|
|
CopyBusyBox() {
|
|
echo "[*] Copy busybox from lib to workdir"
|
|
# if [ -e $BASEDIR/lib ]; then
|
|
# chmod -R 755 $BASEDIR/lib
|
|
# cp -f $BASEDIR/lib/$ABI/libbusybox.so $BB >/dev/null 2>&1
|
|
# $BB >/dev/null 2>&1 && return || cp -f $BASEDIR/lib/$ARCH32/libbusybox.so $BB >/dev/null 2>&1
|
|
# $BB >/dev/null 2>&1 && return || cp -f $BASEDIR/lib/$ARCH/libbusybox.so $BB >/dev/null 2>&1
|
|
# fi
|
|
cp -fF $WorkingBusyBox $BB >/dev/null 2>&1
|
|
chmod +x $BB
|
|
}
|
|
|
|
MoveBusyBox() {
|
|
echo "[*] Move busybox from lib to workdir"
|
|
# if [ -e $BASEDIR/lib ]; then
|
|
# chmod -R 755 $BASEDIR/lib
|
|
# mv -f $BASEDIR/lib/$ABI/libbusybox.so $BB >/dev/null 2>&1
|
|
# $BB >/dev/null 2>&1 && return || mv -f $BASEDIR/lib/$ARCH32/libbusybox.so $BB >/dev/null 2>&1
|
|
# $BB >/dev/null 2>&1 && return || mv -f $BASEDIR/lib/$ARCH/libbusybox.so $BB >/dev/null 2>&1
|
|
# fi
|
|
mv -f $WorkingBusyBox $BB >/dev/null 2>&1
|
|
chmod +x $BB
|
|
}
|
|
|
|
FindUnzip() {
|
|
local RESULT=""
|
|
if [ -e $MZ ]; then
|
|
echo "[*] Looking for an unzip binary"
|
|
$(which unzip > /dev/null 2>&1)
|
|
RESULT="$?"
|
|
|
|
if [[ "$RESULT" == "0" ]]; then
|
|
echo "[-] unzip binary found"
|
|
echo "[*] Extracting busybox and Magisk.zip via unzip ..."
|
|
$(unzip $MZ -oq > /dev/null 2>&1)
|
|
RESULT="$?"
|
|
if [[ "$RESULT" != "0" ]]; then
|
|
echo "[!] unzip binary does not support extracting Magisk.zip"
|
|
exit 1
|
|
else
|
|
FindWorkingBusyBox
|
|
fi
|
|
else
|
|
echo "[-] No unzip binary found"
|
|
fi
|
|
|
|
if [[ "$RESULT" != "0" ]]; then
|
|
ExtractMagiskViaPM
|
|
FindWorkingBusyBox
|
|
CopyBusyBox
|
|
echo "[*] Extracting Magisk.zip via Busybox ..."
|
|
$($BB unzip $MZ -oq > /dev/null 2>&1)
|
|
RESULT="$?"
|
|
if [[ "$RESULT" != "0" ]]; then
|
|
echo "[!] Busybox binary does not support extracting Magisk.zip"
|
|
exit 1
|
|
fi
|
|
fi
|
|
else
|
|
echo "[!] No Magisk.zip present"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
PrepBusyBoxAndMagisk() {
|
|
echo "[-] Switch to the location of the script file"
|
|
BASEDIR="`getdir "${BASH_SOURCE:-$0}"`"
|
|
if [[ "$BASEDIR" == "." ]]; then
|
|
BASEDIR=$(pwd)
|
|
fi
|
|
TMP=$BASEDIR/tmp
|
|
BB=$BASEDIR/busybox
|
|
MZ=$BASEDIR/Magisk.zip
|
|
cd $BASEDIR
|
|
|
|
if ("$UpdateBusyBoxScript"); then
|
|
UpdateBusyBoxToScript $@
|
|
exit 1
|
|
fi
|
|
|
|
rm -rf lib assets
|
|
FindUnzip
|
|
MoveBusyBox
|
|
|
|
chmod -R 755 $BASEDIR
|
|
CheckAvailableMagisks
|
|
}
|
|
|
|
ExecBusyBoxAsh() {
|
|
export PREPBBMAGISK=1
|
|
export ASH_STANDALONE=1
|
|
export BASEDIR
|
|
export TMP
|
|
export BB
|
|
export MZ
|
|
|
|
if [ "$DERIVATE" == "BlueStacks" ]; then
|
|
CheckBlueStacksSUBinary
|
|
echo "[*] Re-Run rootAVD in Magisk Busybox STANDALONE (D)ASH as Root"
|
|
exec $SU 0 $BB sh $0 $@
|
|
fi
|
|
echo "[*] Re-Run rootAVD in Magisk Busybox STANDALONE (D)ASH"
|
|
exec $BB sh $0 $@
|
|
}
|
|
|
|
repack_ramdisk() {
|
|
echo "[*] Repacking ramdisk .."
|
|
cd $TMP/ramdisk > /dev/null
|
|
`find . | cpio -H newc -o > $CPIO`
|
|
cd - > /dev/null
|
|
}
|
|
|
|
extract_patched_ramdisk() {
|
|
echo "[-] Clearing $TMP/ramdisk"
|
|
rm -fR $TMP/ramdisk
|
|
mkdir -p $TMP/ramdisk
|
|
|
|
cd $TMP/ramdisk > /dev/null
|
|
$BASEDIR/busybox cpio -F $CPIO -i *lib* > /dev/null 2>&1
|
|
../../magiskboot cpio ../../ramdisk.cpio "rm -r /lib/modules/*"
|
|
ls -la
|
|
cd - > /dev/null
|
|
exit
|
|
}
|
|
|
|
extract_stock_ramdisk() {
|
|
echo "[-] Clearing $TMP/ramdisk"
|
|
rm -fR $TMP/ramdisk
|
|
mkdir -p $TMP/ramdisk
|
|
|
|
cd $TMP/ramdisk > /dev/null
|
|
echo "[*] Extracting Stock ramdisk"
|
|
$BASEDIR/busybox cpio -F $CPIO -i > /dev/null 2>&1
|
|
cd - > /dev/null
|
|
}
|
|
|
|
decompress_ramdisk(){
|
|
echo "[-] taken from shakalaca's MagiskOnEmulator/process.sh"
|
|
echo "[*] executing ramdisk splitting / extraction / repacking"
|
|
# extract and check ramdisk
|
|
if [[ $API -ge 30 ]]; then
|
|
$RAMDISK_GZ && gzip -fdk $RDF$ENDG
|
|
echo "[-] API level greater then 30"
|
|
echo "[*] Check if we need to repack ramdisk before patching .."
|
|
COUNT=`strings -t d $RDF | grep TRAILER\!\! | wc -l`
|
|
if [[ $COUNT -gt 1 ]]; then
|
|
echo "[-] Multiple cpio archives detected"
|
|
REPACKRAMDISK=1
|
|
fi
|
|
fi
|
|
|
|
if [ "$DERIVATE" == "BlueStacks" ]; then
|
|
$RAMDISK_GZ && gzip -fdk $RDF$ENDG
|
|
COUNT=`strings -t d $RDF | grep TRAILER | wc -l`
|
|
REPACKRAMDISK=1
|
|
fi
|
|
|
|
if [[ -n "$REPACKRAMDISK" ]]; then
|
|
$RAMDISK_GZ && rm $RDF$ENDG
|
|
echo "[*] Unpacking ramdisk .."
|
|
mkdir -p $TMP/ramdisk
|
|
LASTINDEX=0
|
|
NextArchiveINDEX=0
|
|
IBS=1
|
|
OBS=4096
|
|
OF=$TMP/temp$ENDG
|
|
|
|
RAMDISKS=`strings -t d $RDF | grep TRAILER | sed 's|TRAILER.*|TRAILER|'`
|
|
|
|
for OFFSET in $RAMDISKS; do
|
|
|
|
# calculate offset to next archive
|
|
if [ `echo "$OFFSET" | grep TRAILER` ]; then
|
|
# find position of end of TRAILER!!! string in image
|
|
|
|
if $RAMDISK_GZ; then
|
|
LEN=${#OFFSET}
|
|
START=$((LASTINDEX+LEN))
|
|
# find first occurance of string in image, that will be start of cpio archive
|
|
dd if=$RDF skip=$START count=$OBS ibs=$IBS obs=$OBS of=$OF > /dev/null 2>&1
|
|
HEAD=`strings -t d $OF | head -1`
|
|
# vola
|
|
for i in $HEAD;do
|
|
HEAD=$i
|
|
break
|
|
done
|
|
LASTINDEX=$((START+HEAD))
|
|
fi
|
|
continue
|
|
fi
|
|
|
|
# number of blocks we'll extract
|
|
$RAMDISK_GZ && BLOCKS=$(((OFFSET+128)/IBS))
|
|
if $RAMDISK_LZ4; then
|
|
if [ $LASTINDEX == "0" ]; then
|
|
echo "[*] Searching for the real End of the 1st Archive"
|
|
while [ $LASTINDEX == "0" ]; do
|
|
FIRSTFILEBYTES=$(xxd -p -c8 -l8 -s "$OFFSET" "$RDF")
|
|
FIRSTFILEBYTES="${FIRSTFILEBYTES:0:8}"
|
|
if [ "$FIRSTFILEBYTES" == "$COMPRESS_SIGN" ]; then
|
|
break
|
|
fi
|
|
OFFSET=$((OFFSET+1))
|
|
done
|
|
fi
|
|
BLOCKS=$((OFFSET/IBS))
|
|
fi
|
|
|
|
# extract and dump
|
|
echo "[-] Dumping from $LASTINDEX to $BLOCKS .."
|
|
dd if=$RDF skip=$LASTINDEX count=$BLOCKS ibs=$IBS obs=$OBS of=$OF > /dev/null 2>&1
|
|
|
|
cd $TMP/ramdisk > /dev/null
|
|
$RAMDISK_GZ && cat $OF | $BASEDIR/busybox cpio -i > /dev/null 2>&1
|
|
if $RAMDISK_LZ4; then
|
|
$BASEDIR/magiskboot decompress $OF $OF.cpio
|
|
$BASEDIR/busybox cpio -F $OF.cpio -i > /dev/null 2>&1
|
|
fi
|
|
cd - > /dev/null
|
|
|
|
LASTINDEX=$OFFSET
|
|
done
|
|
repack_ramdisk
|
|
else
|
|
echo "[*] After decompressing ramdisk.img, magiskboot will work"
|
|
$RAMDISK_GZ && RDF=$RDF$ENDG
|
|
$BASEDIR/magiskboot decompress $RDF $CPIO
|
|
fi
|
|
#update_lib_modules
|
|
}
|
|
|
|
apply_ramdisk_hacks() {
|
|
|
|
# Call rootAVD with PATCHFSTAB if you want the RAMDISK merge your modded fstab.ranchu before Magisk Mirror gets mounted
|
|
|
|
# cp the read-only fstab.ranchu from vendor partition and add usb:auto for SD devices
|
|
# kernel musst have Mass-Storage + SCSI Support enabled to create /dev/block/sd* nodes
|
|
|
|
#echo "[!] PATCHFSTAB=$PATCHFSTAB"
|
|
if ("$PATCHFSTAB"); then
|
|
echo "[-] pulling fstab.ranchu from AVD"
|
|
cp /system/vendor/etc/fstab.ranchu $(pwd)
|
|
echo "[-] adding usb:auto to fstab.ranchu"
|
|
echo "/devices/*/block/sd* auto auto defaults voldmanaged=usb:auto" >> fstab.ranchu
|
|
#echo "/devices/*/block/loop7 auto auto defaults voldmanaged=sdcard:auto" >> fstab.ranchu
|
|
#echo "/devices/1-* auto auto defaults voldmanaged=usb:auto" >> fstab.ranchu
|
|
$BASEDIR/magiskboot cpio ramdisk.cpio \
|
|
"mkdir 0755 overlay.d/vendor" \
|
|
"mkdir 0755 overlay.d/vendor/etc" \
|
|
"add 0644 overlay.d/vendor/etc/fstab.ranchu fstab.ranchu"
|
|
echo "[-] overlay adding complete"
|
|
#echo "[-] jumping back to patching ramdisk for magisk init"
|
|
#else
|
|
#echo "[!] Skipping fstab.ranchu patch with /dev/block/sda"
|
|
#echo "[?] If you want fstab.ranchu patched, Call rootAVD with PATCHFSTAB"
|
|
fi
|
|
|
|
#echo "[!] AddRCscripts=$AddRCscripts"
|
|
if ("$AddRCscripts"); then
|
|
echo "[*] adding *.rc files to ramdisk"
|
|
#for f in *.rc; do
|
|
# ./magiskboot cpio ramdisk.cpio "add 0644 overlay.d/sbin/$f $f"
|
|
#done
|
|
#CSTRC=init.custom.rc
|
|
#touch $CSTRC
|
|
for f in *.rc; do
|
|
#echo "$f" > $CSTRC
|
|
$BASEDIR/magiskboot cpio ramdisk.cpio "add 0755 overlay.d/$f $f"
|
|
done
|
|
|
|
if [ -d $BASEDIR/sbin ]; then
|
|
echo "[*] adding sbin files to ramdisk"
|
|
for f in sbin/*; do
|
|
$BASEDIR/magiskboot cpio ramdisk.cpio "add 0755 overlay.d/$f $f"
|
|
done
|
|
fi
|
|
#$BASEDIR/magiskboot cpio ramdisk.cpio "add 0755 overlay.d/$CSTRC $CSTRC"
|
|
echo "[-] overlay adding complete"
|
|
#echo "[-] jumping back to patching ramdisk for magisk init"
|
|
#else
|
|
#echo "[!] Skip adding *.rc scripts into ramdisk.img/sbin/*.rc"
|
|
#echo "[?] If you want *.rc scripts added into ramdisk.img/sbin/*.rc, Call rootAVD with AddRCscripts"
|
|
fi
|
|
|
|
#$PATCHFSTAB && SKIPOVERLAYD="#" || SKIPOVERLAYD=""
|
|
update_lib_modules
|
|
}
|
|
|
|
verify_ramdisk_origin() {
|
|
echo "[*] Verifying Boot Image by its Kernel Release number:"
|
|
local KRNAVD=$(uname -r)
|
|
local KRNRDF=""
|
|
echo "[-] This AVD = $KRNAVD"
|
|
KRNRDF=$(cat $CPIO | strings | grep -m 1 vermagic= | sed 's/vermagic=//;s/ .*$//')
|
|
|
|
if [ "$KRNRDF" != "" ]; then
|
|
echo "[-] Ramdisk = $KRNRDF"
|
|
if [ "$KRNAVD" == "$KRNRDF" ]; then
|
|
echo "[!] Ramdisk is probably from this AVD"
|
|
else
|
|
echo "[!] Ramdisk is probably NOT from this AVD"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
test_ramdisk_patch_status(){
|
|
|
|
if [ -e ramdisk.cpio ]; then
|
|
$BASEDIR/magiskboot cpio ramdisk.cpio test 2>/dev/null
|
|
STATUS=$?
|
|
echo "[-] Checking ramdisk STATUS=$STATUS"
|
|
else
|
|
echo "[-] Stock A only system-as-root"
|
|
STATUS=0
|
|
fi
|
|
PATCHEDBOOTIMAGE=false
|
|
|
|
case $((STATUS & 3)) in
|
|
0 ) # Stock boot
|
|
echo "[-] Stock boot image detected"
|
|
SHA1=`$BASEDIR/magiskboot sha1 ramdisk.cpio 2>/dev/null`
|
|
cp -af $CPIO $CPIOORIG 2>/dev/null
|
|
;;
|
|
|
|
1 ) # Magisk patched
|
|
echo "[-] Magisk patched boot image detected"
|
|
#construct_environment
|
|
PATCHEDBOOTIMAGE=true
|
|
;;
|
|
2 ) # Unsupported
|
|
echo "[!] Boot image patched by unsupported programs"
|
|
echo "[!] Please restore back to stock boot image"
|
|
abort_script
|
|
;;
|
|
esac
|
|
|
|
if [ $((STATUS & 8)) -ne 0 ]; then
|
|
echo "[!] TWOSTAGE INIT image detected - Possibly using 2SI, export env var"
|
|
export TWOSTAGEINIT=true
|
|
fi
|
|
export PATCHEDBOOTIMAGE
|
|
}
|
|
|
|
patching_ramdisk(){
|
|
##########################################################################################
|
|
# Ramdisk patches
|
|
##########################################################################################
|
|
|
|
echo "[-] Patching ramdisk"
|
|
|
|
echo "KEEPVERITY=$KEEPVERITY" > config
|
|
echo "KEEPFORCEENCRYPT=$KEEPFORCEENCRYPT" >> config
|
|
echo "RECOVERYMODE=$RECOVERYMODE" >> config
|
|
|
|
# actually here is the SHA of the bootimage generated
|
|
# we only have one file, so it could make sense
|
|
[ ! -z $SHA1 ] && echo "SHA1=$SHA1" >> config
|
|
|
|
# Compress to save precious ramdisk space
|
|
|
|
if $IS32BITONLY || ! $IS64BITONLY ; then
|
|
$BASEDIR/magiskboot compress=xz magisk32 magisk32.xz
|
|
fi
|
|
|
|
if $IS64BITONLY || ! $IS32BITONLY ; then
|
|
$BASEDIR/magiskboot compress=xz magisk64 magisk64.xz
|
|
fi
|
|
|
|
$IS64BITONLY && SKIP32="#" || SKIP32=""
|
|
$IS64BIT && SKIP64="" || SKIP64="#"
|
|
|
|
if $STUBAPK; then
|
|
echo "[!] stub.apk is present, compress and add it to ramdisk"
|
|
$BASEDIR/magiskboot compress=xz stub.apk stub.xz
|
|
fi
|
|
|
|
$STUBAPK && SKIPSTUB="" || SKIPSTUB="#"
|
|
|
|
# Here gets the ramdisk.img patched with the magisk su files and stuff
|
|
|
|
echo "[*] adding overlay.d/sbin folders to ramdisk"
|
|
$BASEDIR/magiskboot cpio ramdisk.cpio \
|
|
"mkdir 0750 overlay.d" \
|
|
"mkdir 0750 overlay.d/sbin"
|
|
|
|
apply_ramdisk_hacks
|
|
|
|
echo "[!] patching the ramdisk with Magisk Init"
|
|
$BASEDIR/magiskboot cpio ramdisk.cpio \
|
|
"add 0750 init magiskinit" \
|
|
"$SKIP32 add 0644 overlay.d/sbin/magisk32.xz magisk32.xz" \
|
|
"$SKIP64 add 0644 overlay.d/sbin/magisk64.xz magisk64.xz" \
|
|
"$SKIPSTUB add 0644 overlay.d/sbin/stub.xz stub.xz" \
|
|
"patch" \
|
|
"backup ramdisk.cpio.orig" \
|
|
"mkdir 000 .backup" \
|
|
"add 000 .backup/.magisk config"
|
|
}
|
|
|
|
|
|
rename_copy_magisk() {
|
|
if ( "$MAGISKVERCHOOSEN" ); then
|
|
echo "[!] Copy Magisk.zip to Magisk.apk"
|
|
cp Magisk.zip Magisk.apk
|
|
else
|
|
echo "[!] Rename Magisk.zip to Magisk.apk"
|
|
mv Magisk.zip Magisk.apk
|
|
fi
|
|
}
|
|
|
|
repacking_ramdisk(){
|
|
if [ $((STATUS & 4)) -ne 0 ]; then
|
|
echo "[!] Compressing ramdisk before repacking it"
|
|
$BASEDIR/magiskboot cpio ramdisk.cpio compress
|
|
fi
|
|
|
|
echo "[*] repacking back to ramdisk.img format"
|
|
# Rename and compress ramdisk.cpio back to ramdiskpatched4AVD.img
|
|
$BASEDIR/magiskboot compress=$METHOD "ramdisk.cpio" "ramdiskpatched4AVD.img"
|
|
}
|
|
|
|
strip_html_links() {
|
|
sed -i -e 's/<a href=/\n<a href=/g;s/<\/a>/<\/a>\n/g' "$1"
|
|
}
|
|
strip_kernel_builds() {
|
|
sed -i -n '/>Update kernel to builds/p' "$1"
|
|
}
|
|
strip_next_pages() {
|
|
sed -n '/>Next/p' "$1"
|
|
}
|
|
find_next_pages() {
|
|
local URL="$2"
|
|
local NEXTPAGESRC=""
|
|
local TMPHTML="tmp.html"
|
|
rm -rf $TMPHTML
|
|
NEXTPAGESRC=$(strip_next_pages $1)
|
|
|
|
echo "[-] Find Next Page(s)"
|
|
while [[ "$NEXTPAGESRC" != "" ]]; do
|
|
NEXTPAGESRC=$(echo $NEXTPAGESRC | sed -e 's/.*href=\"/\1/' -e 's/\">Next.*//')
|
|
#echo $NEXTPAGESRC
|
|
DownLoadFile $URL $NEXTPAGESRC $TMPHTML
|
|
strip_html_links $TMPHTML
|
|
cat $TMPHTML >> $1
|
|
NEXTPAGESRC=$(strip_next_pages $TMPHTML)
|
|
done
|
|
}
|
|
|
|
update_lib_modules() {
|
|
local INITRAMFS=initramfs.img
|
|
if ("$AVDIsOnline"); then
|
|
if ( "$InstallPrebuiltKernelModules" ); then
|
|
local KERNEL_ARCH="x86-64"
|
|
if [[ $ABI == *"arm"* ]]; then
|
|
KERNEL_ARCH="arm64"
|
|
fi
|
|
local unameR=$(uname -r)
|
|
local majmin=${unameR%.*}
|
|
#majmin=5.15
|
|
local installedbuild=${unameR##*ab}
|
|
|
|
echo "[*] Fetching Kernel Data:"
|
|
echo "[-] Android: $AVERSION"
|
|
echo "[-] Arch: $KERNEL_ARCH"
|
|
echo "[-] Uname: $unameR"
|
|
echo "[-] Version: $majmin"
|
|
echo "[-] Build Version: $installedbuild"
|
|
|
|
local URL="https://android.googlesource.com"
|
|
#local TAG="android$AVERSION-mainline-sdkext-release"
|
|
local TAG="android$AVERSION-gsi"
|
|
#local TAG="master"
|
|
local KERSRC="/kernel/prebuilts/$majmin/$KERNEL_ARCH/+log/refs/heads/$TAG"
|
|
#local KERSRC="/platform/prebuilts/qemu-kernel/+log/refs/heads/$TAG"
|
|
#https://android.googlesource.com/platform/prebuilts/qemu-kernel/+log/refs/heads/android11-gsi
|
|
#https://android.googlesource.com/platform/prebuilts/qemu-kernel/+/refs/heads/android11-gsi
|
|
#local KERSRC="/kernel/prebuilts/$majmin/$KERNEL_ARCH/+log/refs/heads/android$AVERSION-mainline-sdkext-release"
|
|
|
|
local MODSRC="/kernel/prebuilts/common-modules/virtual-device/$majmin/$KERNEL_ARCH/+log/refs/heads/$TAG"
|
|
#local MODSRC="/kernel/prebuilts/common-modules/virtual-device/$majmin/$KERNEL_ARCH/+log/refs/heads/android$AVERSION-mainline-sdkext-release"
|
|
local KERPREMASHTML="kernelprebuiltsmaster.html"
|
|
local KERDST="prebuiltkernel.tar.gz"
|
|
local MODDST="prebuiltmodules.tar.gz"
|
|
local MODPREMASHTML="moduleprebuiltsmaster.html"
|
|
local TMPSTRIPFILE="tmpstripfile"
|
|
local TMPREADFILE="tmpreadfile"
|
|
local FILETOREAD=""
|
|
local FILETOSTRIP=""
|
|
|
|
local BUILDVERCHOOSEN=""
|
|
local CHOOSENLINE=""
|
|
local KERCOMMITID=""
|
|
local MODCOMMITID=""
|
|
|
|
local ker_line_cnt=""
|
|
local mod_line_cnt=""
|
|
local i=""
|
|
|
|
|
|
DownLoadFile $URL $KERSRC $KERPREMASHTML
|
|
strip_html_links $KERPREMASHTML
|
|
find_next_pages $KERPREMASHTML $URL
|
|
strip_kernel_builds $KERPREMASHTML
|
|
|
|
DownLoadFile $URL $MODSRC $MODPREMASHTML
|
|
strip_html_links $MODPREMASHTML
|
|
find_next_pages $MODPREMASHTML $URL
|
|
strip_kernel_builds $MODPREMASHTML
|
|
|
|
ker_line_cnt=$(sed -n '$=' $KERPREMASHTML)
|
|
mod_line_cnt=$(sed -n '$=' $MODPREMASHTML)
|
|
|
|
if [ "$ker_line_cnt" -gt "$mod_line_cnt" ];then
|
|
FILETOREAD="$KERPREMASHTML"
|
|
FILETOSTRIP="$MODPREMASHTML"
|
|
else
|
|
FILETOREAD="$MODPREMASHTML"
|
|
FILETOSTRIP="$KERPREMASHTML"
|
|
fi
|
|
|
|
touch $TMPSTRIPFILE
|
|
touch $TMPREADFILE
|
|
|
|
echo "[*] Find common Build Versions"
|
|
while read line; do
|
|
BUILDVER=$(echo $line | sed -e 's/<[^>]*>//g')
|
|
grep -e ">$BUILDVER<" -F $FILETOSTRIP >> $TMPSTRIPFILE
|
|
if [[ "$?" == "0" ]]; then
|
|
echo $line >> $TMPREADFILE
|
|
fi
|
|
done < $FILETOREAD
|
|
|
|
mv -f $TMPREADFILE $FILETOREAD
|
|
mv -f $TMPSTRIPFILE $FILETOSTRIP
|
|
|
|
while :
|
|
do
|
|
i=0
|
|
echo "[!] Installed Kernel builds $installedbuild"
|
|
echo "[?] Choose a Prebuild Kernel/Module Version"
|
|
while read line; do
|
|
i=$(( i + 1 ))
|
|
BUILDVER=$(echo $line | sed -e 's/<[^>]*>//g')
|
|
echo "[$i] $BUILDVER"
|
|
done < $KERPREMASHTML
|
|
|
|
read choice
|
|
case $choice in
|
|
*)
|
|
if [[ "$choice" == "" ]]; then
|
|
choice=1
|
|
fi
|
|
if [ "$choice" -le "$i" ];then
|
|
BUILDVERCHOOSEN=$choice
|
|
CHOOSENLINE=$(sed -n "$BUILDVERCHOOSEN"'p' $KERPREMASHTML)
|
|
BUILDVER=$(echo $CHOOSENLINE| sed -e 's/<[^>]*>//g')
|
|
KERCOMMITID=$(echo $CHOOSENLINE | sed -e 's/^[^"]*"\([^"]*\)".*/\1/')
|
|
KERCOMMITID=${KERCOMMITID##*/}".tar.gz"
|
|
|
|
CHOOSENLINE=$(sed -n "$BUILDVERCHOOSEN"'p' $MODPREMASHTML)
|
|
MODCOMMITID=$(echo $CHOOSENLINE | sed -e 's/^[^"]*"\([^"]*\)".*/\1/')
|
|
MODCOMMITID=${MODCOMMITID##*/}".tar.gz"
|
|
|
|
echo "[$BUILDVERCHOOSEN] You choose: $BUILDVER"
|
|
break
|
|
fi
|
|
echo "Choice is out of range";;
|
|
esac
|
|
done
|
|
|
|
echo "[-] Downloading Kernel and its Modules..."
|
|
# Download Kernel
|
|
DownLoadFile "$URL/kernel/prebuilts/$majmin/$KERNEL_ARCH/+archive/" $KERCOMMITID $KERDST
|
|
# Download Modules
|
|
DownLoadFile "$URL/kernel/prebuilts/common-modules/virtual-device/$majmin/$KERNEL_ARCH/+archive/" $MODCOMMITID $MODDST
|
|
|
|
echo "[*] Extracting kernel-$majmin to bzImage"
|
|
tar -xf $KERDST kernel-$majmin -O > bzImage
|
|
echo "[-] Extracting $INITRAMFS"
|
|
tar -xf $MODDST $INITRAMFS
|
|
|
|
InstallKernelModules=true
|
|
fi
|
|
fi
|
|
|
|
if ( "$InstallKernelModules" ); then
|
|
|
|
if [ -e "$INITRAMFS" ]; then
|
|
echo "[!] Installing new Kernel Modules"
|
|
echo "[*] Copy initramfs.img $TMP/initramfs"
|
|
mkdir -p $TMP/initramfs
|
|
CMPRMTH=$(compression_method $INITRAMFS)
|
|
cp $INITRAMFS $TMP/initramfs/initramfs.cpio$CMPRMTH
|
|
else
|
|
return 0
|
|
fi
|
|
|
|
echo "[-] Extracting Modules from $INITRAMFS"
|
|
|
|
cd $TMP/initramfs > /dev/null
|
|
$BASEDIR/magiskboot decompress initramfs.cpio$CMPRMTH
|
|
$BASEDIR/busybox cpio -F initramfs.cpio -i *lib* > /dev/null 2>&1
|
|
cd - > /dev/null
|
|
|
|
if [ ! -d "$TMP/initramfs/lib/modules" ]; then
|
|
echo "[!] $INITRAMFS has no lib/modules, aborting"
|
|
rm -rf bzImage 2>/dev/null
|
|
return 0
|
|
fi
|
|
|
|
# If Stock or patched Status
|
|
if $PATCHEDBOOTIMAGE; then
|
|
# If it is a already patched ramdisk
|
|
if [ ! -e "$TMP/ramdisk" ]; then
|
|
mkdir -p $TMP/ramdisk
|
|
fi
|
|
|
|
echo "[*] Extracting Modules from patched ramdisk.img"
|
|
cd $TMP/ramdisk > /dev/null
|
|
$BASEDIR/busybox cpio -F $CPIO -i *lib* > /dev/null 2>&1
|
|
cd - > /dev/null
|
|
else
|
|
# If it is a Stock Ramdisk
|
|
echo "[*] Extracting Modules from Stock ramdisk.img"
|
|
extract_stock_ramdisk
|
|
fi
|
|
|
|
OLDVERMAGIC=$(cat $(find $TMP/ramdisk/. -name '*.ko' | head -n 1 2> /dev/null) | strings | grep vermagic= | sed 's/vermagic=//;s/ .*$//' 2> /dev/null)
|
|
OLDANDROID=$(cat $(find $TMP/ramdisk/. -name '*.ko' | head -n 1 2> /dev/null) | strings | grep 'Android (' | sed 's/ c.*$//' 2> /dev/null)
|
|
|
|
# If Stock or patched Status
|
|
if $PATCHEDBOOTIMAGE; then
|
|
# If it is a already patched ramdisk
|
|
echo "[*] Removing Modules from patched ramdisk.img"
|
|
$BASEDIR/magiskboot cpio $CPIO "rm -r lib" > /dev/null 2>&1
|
|
else
|
|
# If it is a Stock Ramdisk
|
|
echo "[*] Removing Modules from Stock ramdisk.img"
|
|
rm -f $TMP/ramdisk/lib/modules/*
|
|
fi
|
|
|
|
echo "[!] $OLDVERMAGIC"
|
|
echo "[!] $OLDANDROID"
|
|
|
|
echo "[-] Installing new Modules into ramdisk.img"
|
|
cd $TMP/initramfs > /dev/null
|
|
find ./lib/modules -type f -name '*' -exec cp {} . \;
|
|
find . -name '*.ko' -exec cp {} $TMP/ramdisk/lib/modules/ \;
|
|
NEWVERMAGIC=$(cat $(find . -name '*.ko' | head -n 1 2> /dev/null) | strings | grep vermagic= | sed 's/vermagic=//;s/ .*$//' 2> /dev/null)
|
|
NEWANDROID=$(cat $(find . -name '*.ko' | head -n 1 2> /dev/null) | strings | grep 'Android (' | sed 's/ c.*$//' 2> /dev/null)
|
|
cp modules.alias modules.dep modules.load modules.softdep $TMP/ramdisk/lib/modules/
|
|
cd - > /dev/null
|
|
|
|
echo "[!] $NEWVERMAGIC"
|
|
echo "[!] $NEWANDROID"
|
|
|
|
echo "[*] Adjusting modules.load and modules.dep"
|
|
cd $TMP/ramdisk/lib/modules > /dev/null
|
|
sed -i -E 's~[^[:blank:]]+/~/lib/modules/~g' modules.load
|
|
sort -s -o modules.load modules.load
|
|
sed -i -E 's~[^[:blank:]]+/~/lib/modules/~g' modules.dep
|
|
sort -s -o modules.dep modules.dep
|
|
cd - > /dev/null
|
|
|
|
# If Stock or patched Status
|
|
if $PATCHEDBOOTIMAGE; then
|
|
# If it is a already patched ramdisk
|
|
echo "[*] Adding new Modules into patched ramdisk.img"
|
|
cd $TMP/ramdisk/lib/modules > /dev/null
|
|
$BASEDIR/magiskboot cpio $CPIO \
|
|
"mkdir 0755 lib" \
|
|
"mkdir 0755 lib/modules" > /dev/null 2>&1
|
|
for f in *.*; do
|
|
$BASEDIR/magiskboot cpio $CPIO \
|
|
"add 0644 lib/modules/$f $f" > /dev/null 2>&1
|
|
#echo "$f"
|
|
done
|
|
cd - > /dev/null
|
|
else
|
|
# If it is a Stock Ramdisk
|
|
repack_ramdisk
|
|
fi
|
|
fi
|
|
}
|
|
|
|
#### BlueStacks functions
|
|
### taken from HuskyDG script MagiskOnEmu libbash.so ->
|
|
|
|
random() {
|
|
VALUE=$1; TYPE=$2; PICK="$3"; PICKC="$4"
|
|
TMPR=""
|
|
HEX="0123456789abcdef"; HEXC=16
|
|
CHAR="qwertyuiopasdfghjklzxcvbnm"; CHARC=26
|
|
NUM="0123456789"; NUMC=10
|
|
COUNT=$(seq 1 1 $VALUE)
|
|
list_pick=$HEX; C=$HEXC
|
|
[ "$TYPE" == "char" ] && list_pick=$CHAR && C=$CHARC
|
|
[ "$TYPE" == "number" ] && list_pick=$NUM && C=$NUMC
|
|
[ "$TYPE" == "custom" ] && list_pick="$PICK" && C=$PICKC
|
|
for i in $COUNT; do
|
|
random_pick=$(( $RANDOM % $C))
|
|
echo -n ${list_pick:$random_pick:1}
|
|
done
|
|
}
|
|
|
|
random_str() {
|
|
random_length=$(random 1 custom 56789 5);
|
|
random $random_length custom "qwertyuiopasdfghjklzxcvbnm0123456789QWERTYUIOPASDFGHJKLZXCVBNM" 63 | base64 | sed "s/=//g"
|
|
}
|
|
magisk_loader() {
|
|
magisk_overlay=`random_str`
|
|
magisk_postfsdata=`random_str`
|
|
magisk_service=`random_str`
|
|
magisk_daemon=`random_str`
|
|
magisk_boot_complete=`random_str`
|
|
magisk_loadpolicy=`random_str`
|
|
dev_random=`random_str`
|
|
#system-as-root, /sbin is removal
|
|
MAGISKTMP="/dev/$dev_random"
|
|
mount_sbin="mkdir -p \"$MAGISKTMP\"
|
|
mnt_tmpfs \"$MAGISKTMP\"
|
|
chmod 755 \"$MAGISKTMP\""
|
|
umount_sbin="umount /sbin"
|
|
|
|
|
|
# apply multiple sepolicy at same time
|
|
|
|
LOAD_MODULES_POLICY="rm -rf \"\$MAGISKTMP/.magisk/sepolicy.rules\"
|
|
for module in \$(ls /data/adb/modules); do
|
|
if ! [ -f \"/data/adb/modules/\$module/disable\" ] && [ -f \"/data/adb/modules/\$module/sepolicy.rule\" ]; then
|
|
echo \"## * module sepolicy: \$module\" >>\"\$MAGISKTMP/.magisk/sepolicy.rules\"
|
|
cat \"/data/adb/modules/\$module/sepolicy.rule\" >>\"\$MAGISKTMP/.magisk/sepolicy.rules\"
|
|
echo \"\" >>\"\$MAGISKTMP/.magisk/sepolicy.rules\"
|
|
|
|
fi
|
|
done
|
|
\$MAGISKTMP/magiskpolicy --live --apply \"\$MAGISKTMP/.magisk/sepolicy.rules\""
|
|
|
|
ADDITIONAL_SCRIPT="( # addition script
|
|
rm -rf /data/adb/post-fs-data.d/fix_mirror_mount.sh
|
|
rm -rf /data/adb/service.d/fix_modules_not_show.sh
|
|
|
|
|
|
# additional script to deal with bullshit faulty design of emulator
|
|
# that close built-in root will remove magisk's /system/bin/su
|
|
|
|
echo \"
|
|
export PATH=\\\"\$MAGISKTMP:\\\$PATH\\\"
|
|
if [ -f \\\"/system/bin/magisk\\\" ]; then
|
|
umount -l /system/bin/su
|
|
rm -rf /system/bin/su
|
|
ln -fs ./magisk /system/bin/su
|
|
mount -o ro,remount /system/bin
|
|
umount -l /system/bin/magisk
|
|
mount --bind \\\"\$MAGISKTMP/magisk\\\" /system/bin/magisk
|
|
fi\" >\$MAGISKTMP/emu/magisksu_survival.sh
|
|
|
|
# additional script to deal with bullshit faulty design of Bluestacks
|
|
# that /system is a bind mountpoint
|
|
|
|
echo \"
|
|
SCRIPT=\\\"\\\$0\\\"
|
|
MAGISKTMP=\\\$(magisk --path) || MAGISKTMP=/sbin
|
|
( #fix bluestacks
|
|
MIRROR_SYSTEM=\\\"\\\$MAGISKTMP/.magisk/mirror/system\\\"
|
|
test ! -d \\\"\\\$MIRROR_SYSTEM/android/system\\\" && exit
|
|
test \\\"\\\$(cd /system; ls)\\\" == \\\"\\\$(cd \\\"\\\$MIRROR_SYSTEM\\\"; ls)\\\" && exit
|
|
mount --bind \\\"\\\$MIRROR_SYSTEM/android/system\\\" \\\"\\\$MIRROR_SYSTEM\\\" )
|
|
( #fix mount data mirror
|
|
function cmdline() {
|
|
awk -F\\\"\\\${1}=\\\" '{print \\\$2}' < /proc/cmdline | cut -d' ' -f1 2> /dev/null
|
|
}
|
|
|
|
# additional script to deal with bullshit faulty design of Android-x86
|
|
# that data is a bind mount from $SRC/data on ext4 partition
|
|
|
|
|
|
SRC=\\\"\\\$(cmdline SRC)\\\"
|
|
test -z \\\"\\\$SRC\\\" && exit
|
|
LIST_TEST=\\\"
|
|
/data
|
|
/data/adb
|
|
/data/adb/magisk
|
|
/data/adb/modules
|
|
\\\"
|
|
count=0
|
|
for folder in \\\$LIST_TEST; do
|
|
test \\\"\\\$(ls -A \\\$MAGISKTMP/.magisk/mirror/\\\$folder 2>/dev/null)\\\" == \\\"\\\$(ls -A \\\$folder 2>/dev/null)\\\" && count=\\\$((\\\$count + 1))
|
|
done
|
|
test \\\"\\\$count\\\" == 4 && exit
|
|
count=0
|
|
for folder in \\\$LIST_TEST; do
|
|
test \\\"\\\$(ls -A \\\$MAGISKTMP/.magisk/mirror/data/\\\$SRC/\\\$folder 2>/dev/null)\\\" == \\\"\\\$(ls -A \\\$folder 2>/dev/null)\\\" && count=\\\$((\\\$count + 1))
|
|
done
|
|
if [ \\\"\\\$count\\\" == 4 ]; then
|
|
mount --bind \\\"\\\$MAGISKTMP/.magisk/mirror/data/\\\$SRC/data\\\" \\\"\\\$MAGISKTMP/.magisk/mirror/data\\\"
|
|
fi )
|
|
rm -rf \\\"\\\$SCRIPT\\\"
|
|
\" >/data/adb/post-fs-data.d/fix_mirror_mount.sh
|
|
echo \"
|
|
SCRIPT=\\\"\\\$0\\\"
|
|
MAGISKTMP=\\\$(magisk --path) || MAGISKTMP=/sbin
|
|
CHECK=\\\"/data/adb/modules/.mk_\\\$RANDOM\\\$RANDOM\\\"
|
|
touch \\\"\\\$CHECK\\\"
|
|
test \\\"\\\$(ls -A \\\$MAGISKTMP/.magisk/modules 2>/dev/null)\\\" != \\\"\\\$(ls -A /data/adb/modules 2>/dev/null)\\\" && mount --bind \\\$MAGISKTMP/.magisk/mirror/data/adb/modules \\\$MAGISKTMP/.magisk/modules
|
|
rm -rf \\\"\\\$CHECK\\\"
|
|
rm -rf \\\"\\\$SCRIPT\\\"\" >/data/adb/service.d/fix_modules_not_show.sh
|
|
chmod 755 /data/adb/service.d/fix_modules_not_show.sh
|
|
chmod 755 /data/adb/post-fs-data.d/fix_mirror_mount.sh; )"
|
|
|
|
|
|
EXPORT_PATH="export PATH /sbin:/system/bin:/system/xbin:/vendor/bin:/apex/com.android.runtime/bin:/apex/com.android.art/bin"
|
|
|
|
|
|
magiskloader="
|
|
|
|
on early-init
|
|
$EXPORT_PATH
|
|
|
|
|
|
on post-fs-data
|
|
$RM_RUSTY_MAGISK
|
|
start logd
|
|
start adbd
|
|
rm /dev/.magisk_unblock
|
|
exec u:r:su:s0 root root -- $MAGISKBASE/busybox sh -o standalone $MAGISKBASE/overlay.sh
|
|
exec u:r:magisk:s0 root root -- $MAGISKTMP/magisk --daemon
|
|
start $magisk_postfsdata
|
|
# wait all magisk post-fs-data jobs are completed or 40s has passed
|
|
wait /dev/.magisk_unblock 40
|
|
rm /dev/.magisk_unblock
|
|
|
|
service $magisk_postfsdata $MAGISKTMP/magisk --post-fs-data
|
|
user root
|
|
seclabel u:r:magisk:s0
|
|
oneshot
|
|
|
|
service $magisk_service $MAGISKTMP/magisk --service
|
|
class late_start
|
|
user root
|
|
seclabel u:r:magisk:s0
|
|
oneshot
|
|
|
|
on property:sys.boot_completed=1
|
|
$umount_sbin
|
|
start $magisk_boot_complete
|
|
# remove magisk service traces from some detection
|
|
# although detect modified init.rc is not always correct
|
|
exec u:r:magisk:s0 root root -- $MAGISKTMP/magisk resetprop --delete init.svc.$magisk_postfsdata
|
|
exec u:r:magisk:s0 root root -- $MAGISKTMP/magisk resetprop --delete init.svc.$magisk_service
|
|
exec u:r:magisk:s0 root root -- $MAGISKTMP/magisk resetprop --delete init.svc.$magisk_boot_complete
|
|
exec u:r:magisk:s0 root root -- $MAGISKTMP/magisk resetprop --delete init.svc_debug_pid.$magisk_postfsdata
|
|
exec u:r:magisk:s0 root root -- $MAGISKTMP/magisk resetprop --delete init.svc_debug_pid.$magisk_service
|
|
exec u:r:magisk:s0 root root -- $MAGISKTMP/magisk resetprop --delete init.svc_debug_pid.$magisk_boot_complete
|
|
exec u:r:magisk:s0 root root -- $MAGISKTMP/busybox sh -o standalone $MAGISKTMP/emu/magisksu_survival.sh
|
|
service $magisk_boot_complete $MAGISKTMP/magisk --boot-complete
|
|
user root
|
|
seclabel u:r:magisk:s0
|
|
oneshot"
|
|
|
|
|
|
overlay_loader="#!$MAGISKBASE/busybox sh
|
|
|
|
export PATH=/sbin:/system/bin:/system/xbin
|
|
|
|
|
|
mnt_tmpfs(){ (
|
|
# MOUNT TMPFS ON A DIRECTORY
|
|
MOUNTPOINT=\"\$1\"
|
|
mkdir -p \"\$MOUNTPOINT\"
|
|
mount -t tmpfs -o \"mode=0755\" tmpfs \"\$MOUNTPOINT\" 2>/dev/null
|
|
) }
|
|
|
|
|
|
|
|
mnt_bind(){ (
|
|
# SHORTCUT BY BIND MOUNT
|
|
FROM=\"\$1\"; TO=\"\$2\"
|
|
if [ -L \"\$FROM\" ]; then
|
|
SOFTLN=\"\$(readlink \"\$FROM\")\"
|
|
ln -s \"\$SOFTLN\" \"\$TO\"
|
|
elif [ -d \"\$FROM\" ]; then
|
|
mkdir -p \"\$TO\" 2>/dev/null
|
|
mount --bind \"\$FROM\" \"\$TO\"
|
|
else
|
|
echo -n 2>/dev/null >\"\$TO\"
|
|
mount --bind \"\$FROM\" \"\$TO\"
|
|
fi
|
|
) }
|
|
|
|
clone(){ (
|
|
FROM=\"\$1\"; TO=\"\$2\"; IFS=\$\"
|
|
\"
|
|
[ -d \"\$TO\" ] || exit 1;
|
|
( cd \"\$FROM\" && find * -prune ) | while read obj; do
|
|
( if [ -d \"\$FROM/\$obj\" ]; then
|
|
mnt_tmpfs \"\$TO/\$obj\"
|
|
else
|
|
mnt_bind \"\$FROM/\$obj\" \"\$TO/\$obj\" 2>/dev/null
|
|
fi ) &
|
|
sleep 0.05
|
|
done
|
|
) }
|
|
|
|
overlay(){ (
|
|
# RE-OVERLAY A DIRECTORY
|
|
FOLDER=\"\$1\";
|
|
TMPFOLDER=\"/dev/vm-overlay\"
|
|
#_____
|
|
PAYDIR=\"\${TMPFOLDER}_\${RANDOM}_\$(date | base64)\"
|
|
mkdir -p \"\$PAYDIR\"
|
|
mnt_tmpfs \"\$PAYDIR\"
|
|
#_________
|
|
clone \"\$FOLDER\" \"\$PAYDIR\"
|
|
mount --move \"\$PAYDIR\" \"\$FOLDER\"
|
|
rm -rf \"\$PAYDIR\"
|
|
#______________
|
|
) }
|
|
|
|
exit_magisk(){
|
|
umount -l $MAGISKTMP
|
|
echo -n >/dev/.magisk_unblock
|
|
}
|
|
|
|
|
|
API=\$(getprop ro.build.version.sdk)
|
|
ABI=\$(getprop 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
|
|
|
|
magisk_name=\"magisk32\"
|
|
[ \"\$IS64BIT\" == true ] && magisk_name=\"magisk64\"
|
|
|
|
# umount previous /sbin tmpfs overlay
|
|
|
|
count=0
|
|
( magisk --stop ) &
|
|
|
|
# force umount /sbin tmpfs
|
|
|
|
until ! mount | grep -q \" /sbin \"; do
|
|
[ "$count" -gt "10" ] && break
|
|
umount -l /sbin 2>/dev/null
|
|
sleep 0.1
|
|
count=$(($count+1))
|
|
test ! -d /sbin && break
|
|
done
|
|
|
|
# mount magisk tmpfs path
|
|
|
|
$mount_sbin
|
|
|
|
MAGISKTMP=$MAGISKTMP
|
|
chmod 755 \"\$MAGISKTMP\"
|
|
set -x
|
|
mkdir -p \$MAGISKTMP/.magisk
|
|
mkdir -p \$MAGISKTMP/emu
|
|
exec 2>>\$MAGISKTMP/emu/record_logs.txt
|
|
exec >>\$MAGISKTMP/emu/record_logs.txt
|
|
|
|
cd $MAGISKBASE
|
|
|
|
test ! -f \"./\$magisk_name\" && { echo -n >/dev/.overlay_unblock; exit_magisk; exit 0; }
|
|
|
|
|
|
MAGISKBIN=/data/adb/magisk
|
|
mkdir /data/unencrypted
|
|
for mdir in modules post-fs-data.d service.d magisk; do
|
|
test ! -d /data/adb/\$mdir && rm -rf /data/adb/\$mdir
|
|
mkdir /data/adb/\$mdir 2>/dev/null
|
|
done
|
|
for file in magisk32 magisk64 magiskinit; do
|
|
cp -af ./\$file \$MAGISKTMP/\$file 2>/dev/null
|
|
chmod 755 \$MAGISKTMP/\$file
|
|
cp -af ./\$file \$MAGISKBIN/\$file 2>/dev/null
|
|
chmod 755 \$MAGISKBIN/\$file
|
|
done
|
|
cp -af ./magiskboot \$MAGISKBIN/magiskboot
|
|
cp -af ./busybox \$MAGISKBIN/busybox
|
|
cp -af ./busybox \$MAGISKTMP
|
|
chmod 755 \$MAGISKTMP/busybox
|
|
\$MAGISKTMP/busybox --install -s \$MAGISKTMP
|
|
cp -af ./assets/* \$MAGISKBIN
|
|
|
|
# create symlink / applet
|
|
|
|
ln -s ./\$magisk_name \$MAGISKTMP/magisk 2>/dev/null
|
|
ln -s ./magisk \$MAGISKTMP/su 2>/dev/null
|
|
ln -s ./magisk \$MAGISKTMP/resetprop 2>/dev/null
|
|
ln -s ./magisk \$MAGISKTMP/magiskhide 2>/dev/null
|
|
ln -s ./magiskinit \$MAGISKTMP/magiskpolicy 2>/dev/null
|
|
|
|
mkdir -p \$MAGISKTMP/.magisk/mirror
|
|
mkdir \$MAGISKTMP/.magisk/block
|
|
|
|
touch \$MAGISKTMP/.magisk/config
|
|
|
|
cd \$MAGISKTMP
|
|
# SELinux stuffs
|
|
ln -sf ./magiskinit magiskpolicy
|
|
if [ -f /vendor/etc/selinux/precompiled_sepolicy ]; then
|
|
./magiskpolicy --load /vendor/etc/selinux/precompiled_sepolicy --live --magisk 2>&1
|
|
elif [ -f /sepolicy ]; then
|
|
./magiskpolicy --load /sepolicy --live --magisk 2>&1
|
|
else
|
|
./magiskpolicy --live --magisk 2>&1
|
|
fi
|
|
|
|
#remount system read-only to fix Magisk fail to mount mirror
|
|
|
|
$remove_backup
|
|
mount -o ro,remount /
|
|
mount -o ro,remount /system
|
|
mount -o ro,remount /vendor
|
|
mount -o ro,remount /product
|
|
mount -o ro,remount /system_ext
|
|
|
|
restorecon -R /data/adb/magisk
|
|
|
|
$ADDITIONAL_SCRIPT
|
|
$LOAD_MODULES_POLICY
|
|
|
|
[ ! -f \"\$MAGISKTMP/magisk\" ] && exit_magisk
|
|
# test ! \"\$(pidof magiskd)\" && exit_magisk
|
|
|
|
[ -d "/oem/.overlay" ] && umount -l /oem
|
|
umount -l /system/etc/init
|
|
umount -l /init.rc
|
|
umount -l /system/etc/init/hw/init.rc
|
|
"
|
|
}
|
|
### <- taken from HuskyDG script MagiskOnEmu libbash.so
|
|
|
|
CheckBlueStacksSUBinary(){
|
|
SU="/system/xbin/bstk/su"
|
|
echo "[-] Checking for build-in $SU binary"
|
|
if [ ! -e $SU ]; then
|
|
echo "[!] We need Root to get Root"
|
|
echo "[!] No $SU could be found"
|
|
abort_script
|
|
fi
|
|
echo "[*] $SU binary found"
|
|
|
|
# Disable SELinux
|
|
#$SU -c 'setenforce 0'
|
|
}
|
|
|
|
GetBlueStacksRamdisk() {
|
|
echo "[*] Getting BlueStacks Ramdisk"
|
|
|
|
BA="/boot/android"
|
|
|
|
BSTKRDF="$BA/android/ramdisk.img"
|
|
BSTKRDFBU="$BSTKRDF.backup"
|
|
|
|
echo "[-] remounting $BA as RW"
|
|
mount -o remount,rw $BA
|
|
|
|
if [ ! -e $BSTKRDFBU ]; then
|
|
echo "[*] Copy $BSTKRDF to $BSTKRDFBU"
|
|
cp -fac $BSTKRDF $BSTKRDFBU
|
|
fi
|
|
|
|
echo "[*] Copy $BSTKRDF to $BASEDIR"
|
|
cp -fac $BSTKRDF $BASEDIR/
|
|
}
|
|
|
|
FinalizeBlueStacks() {
|
|
if ! $DEBUG; then
|
|
echo "[-] Overwriting $BSTKRDF with ramdiskpatched4AVD.img"
|
|
cp -f ramdiskpatched4AVD.img $BSTKRDF
|
|
echo "[-] Change ramdisk Mode to 644"
|
|
chmod 644 $BSTKRDF
|
|
echo "[-] Change ramdisk Owner to System"
|
|
chown 1000:1000 $BSTKRDF
|
|
fi
|
|
|
|
echo "[*] Change $BASEDIR Owner back to Shell while root for deleting reasons"
|
|
chown 2000:2000 $BASEDIR -R
|
|
echo "[*] Cleaning /data/adb Folder"
|
|
rm -rf /data/adb
|
|
echo "[-] remounting $BA as RO"
|
|
mount -o remount,ro $BA
|
|
}
|
|
|
|
# Taken from the Magisk Modules Template by topjohnwu
|
|
# set_perm <target> <owner> <group> <permission> [context]
|
|
# if [context] is empty, it will default to "u:object_r:system_file:s0"
|
|
# this function is a shorthand for the following commands
|
|
# chown owner.group target
|
|
# chmod permission target
|
|
# chcon context target
|
|
|
|
set_perm() {
|
|
chown $2:$3 $1 || return 1
|
|
chmod $4 $1 || return 1
|
|
CON=$5
|
|
[ -z $CON ] && CON=u:object_r:system_file:s0
|
|
chcon $CON $1 || return 1
|
|
}
|
|
|
|
# set_perm_recursive <directory> <owner> <group> <dirpermission> <filepermission> [context]
|
|
# if [context] is empty, it will default to "u:object_r:system_file:s0"
|
|
# for all files in <directory>, it will call:
|
|
# set_perm file owner group filepermission context
|
|
# for all directories in <directory> (including itself), it will call:
|
|
# set_perm dir owner group dirpermission context
|
|
|
|
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
|
|
}
|
|
|
|
SettingBlueStackMagiskPermissions() {
|
|
echo "[*] Setting BlueStack Magisk Permissions"
|
|
local ROOT=$(stat -c %u /dev)
|
|
cd $BLSTKMAGISKDIR/ > /dev/null
|
|
set_perm_recursive assets $ROOT $ROOT 0750 0777
|
|
set_perm ./busybox $ROOT $ROOT 0750 u:object_r:magisk_file:s0
|
|
|
|
if [ -e "magisk64" ]; then
|
|
set_perm ./magisk64 $ROOT $ROOT 0750 u:object_r:magisk_exec:s0
|
|
elif [ -e "magisk32" ]; then
|
|
set_perm ./magisk32 $ROOT $ROOT 0750 u:object_r:magisk_exec:s0
|
|
fi
|
|
|
|
set_perm ./magiskboot $ROOT $ROOT 0750
|
|
set_perm ./magiskinit $ROOT $ROOT 0750
|
|
set_perm ./overlay.sh $ROOT $ROOT 0750
|
|
set_perm ../init.rc $ROOT $ROOT 0750
|
|
cd - > /dev/null
|
|
}
|
|
|
|
InstallMagiskIntoBlueStacksRamdisk() {
|
|
echo "[-] Patching BlueStacks ramdisk .."
|
|
echo "[*] Taken from HuskyDG script MagiskOnEmu/libbash.so"
|
|
|
|
MAGISKBASE="/magisk"
|
|
BLSTKMAGISKDIR=$TMP/ramdisk$MAGISKBASE
|
|
local INITRC=$TMP/ramdisk/init.rc
|
|
rm -rf $BLSTKMAGISKDIR 2>/dev/null
|
|
mkdir -p $BLSTKMAGISKDIR
|
|
echo "[-] copying Magisk Assets and Files"
|
|
cp -Rf $BASEDIR/assets $BLSTKMAGISKDIR/
|
|
cp $BB $BLSTKMAGISKDIR/
|
|
cp $BASEDIR/magisk32 $BLSTKMAGISKDIR/
|
|
cp $BASEDIR/magisk64 $BLSTKMAGISKDIR/
|
|
cp $BASEDIR/magiskboot $BLSTKMAGISKDIR/
|
|
cp $BASEDIR/magiskinit $BLSTKMAGISKDIR/
|
|
cp $INITRC $BLSTKMAGISKDIR/
|
|
echo "[*] generating Magisk Boot Scripts"
|
|
magisk_loader
|
|
echo "[*] Magisk files will be mounted to $MAGISKTMP"
|
|
echo "[-] writing overlay.sh Script"
|
|
echo "$overlay_loader" >"$BLSTKMAGISKDIR/overlay.sh"
|
|
echo "[*] appending boot commands to init.rc"
|
|
echo "$magiskloader" >> "$TMP/ramdisk/init.rc"
|
|
|
|
# setting permissions
|
|
SettingBlueStackMagiskPermissions
|
|
|
|
echo "[-] Repacking BlueStacks ramdisk .."
|
|
cd $TMP/ramdisk > /dev/null
|
|
`find . | cpio -H newc -o > $CPIO`
|
|
cd - > /dev/null
|
|
}
|
|
|
|
service(){
|
|
echo "[-] service Module testing"
|
|
#exit
|
|
}
|
|
|
|
InstallMagiskToAVD() {
|
|
|
|
if [ -z $PREPBBMAGISK ]; then
|
|
ProcessArguments $@
|
|
api_level_arch_detect
|
|
PrepBusyBoxAndMagisk
|
|
ExecBusyBoxAsh $@
|
|
fi
|
|
|
|
echo "[*] rootAVD with Magisk $MAGISK_VER Installer"
|
|
|
|
get_flags
|
|
copyARCHfiles
|
|
|
|
if [ "$DERIVATE" == "BlueStacks" ]; then
|
|
GetBlueStacksRamdisk
|
|
fi
|
|
|
|
if $INEMULATOR; then
|
|
detect_ramdisk_compression_method
|
|
decompress_ramdisk
|
|
if $FAKEBOOTIMG; then
|
|
process_fake_boot_img
|
|
fi
|
|
|
|
test_ramdisk_patch_status
|
|
verify_ramdisk_origin
|
|
|
|
if [ "$DERIVATE" == "BlueStacks" ]; then
|
|
InstallMagiskIntoBlueStacksRamdisk
|
|
else
|
|
if $PATCHEDBOOTIMAGE; then
|
|
apply_ramdisk_hacks
|
|
else
|
|
patching_ramdisk
|
|
fi
|
|
fi
|
|
|
|
## Magisk Module testing
|
|
if $DEBUG; then
|
|
service
|
|
fi
|
|
|
|
repacking_ramdisk
|
|
rename_copy_magisk
|
|
fi
|
|
|
|
if [ "$DERIVATE" == "BlueStacks" ]; then
|
|
FinalizeBlueStacks
|
|
fi
|
|
}
|
|
|
|
GetANDROIDHOME() {
|
|
|
|
#unset ANDROID_HOME
|
|
#export ANDROID_HOME=~/Downloads/sdk
|
|
#export ANDROID_HOME=~"/Downloads/sd k"
|
|
#export ANDROID_HOME="~/Downloads/sd k"
|
|
|
|
local HOME=~
|
|
local ANDROIDHOME_M=$HOME/Library/Android/sdk
|
|
local ANDROIDHOME_L=$HOME/Android/Sdk
|
|
defaultHOME_M="~/Library/Android/sdk"
|
|
defaultHOME_L="~/Android/Sdk"
|
|
defaultHOME=""
|
|
local hostarch=""
|
|
SYSIM_DIR=system-images
|
|
ADB_DIR=platform-tools
|
|
|
|
NoSystemImages=true
|
|
|
|
if [ -d "$ANDROIDHOME_M" ]; then
|
|
ANDROIDHOME=$ANDROIDHOME_M
|
|
ENVVAR=$defaultHOME_M
|
|
defaultHOME=$defaultHOME_M
|
|
elif [ -d "$ANDROIDHOME_L" ]; then
|
|
ANDROIDHOME=$ANDROIDHOME_L
|
|
ENVVAR=$defaultHOME_L
|
|
defaultHOME=$defaultHOME_L
|
|
fi
|
|
|
|
if [ ! -z "$ANDROID_HOME" ]; then
|
|
if [[ "$ANDROID_HOME" == *"~"* ]]; then
|
|
ANDROID_HOME="${ANDROID_HOME/#~/~}"
|
|
fi
|
|
ANDROIDHOME="$ANDROID_HOME"
|
|
ENVVAR="\$ANDROID_HOME"
|
|
fi
|
|
|
|
if [[ -d "$ANDROIDHOME/$SYSIM_DIR" ]]; then
|
|
NoSystemImages=false
|
|
fi
|
|
|
|
if [[ "$defaultHOME" == "" ]]; then
|
|
hostarch=$(uname -a)
|
|
defaultHOME=$defaultHOME_M
|
|
if [[ "$hostarch" == *"Linux"* ]]; then
|
|
defaultHOME=$defaultHOME_L
|
|
elif [[ "$hostarch" == *"linux"* ]]; then
|
|
defaultHOME=$defaultHOME_M
|
|
fi
|
|
fi
|
|
|
|
export NoSystemImages
|
|
export ANDROIDHOME
|
|
export ENVVAR
|
|
export SYSIM_DIR
|
|
export ADB_DIR
|
|
export defaultHOME
|
|
export ANDROIDHOME_M
|
|
export ANDROIDHOME_L
|
|
}
|
|
|
|
FindSystemImages() {
|
|
local SYSIM_EX=""
|
|
|
|
echo "- use ${bold}$ENVVAR${normal} to search for AVD system images"
|
|
echo " "
|
|
|
|
if $NoSystemImages ; then
|
|
echo "[!] No system-images could be found"
|
|
return 1
|
|
fi
|
|
|
|
cd "$ANDROIDHOME" > /dev/null
|
|
for SI in $(find $SYSIM_DIR -type f -iname ramdisk*.img); do
|
|
if ( "$ListAllAVDs" ); then
|
|
if [[ "$SYSIM_EX" == "" ]]; then
|
|
SYSIM_EX+="$SI"
|
|
else
|
|
SYSIM_EX+=" $SI"
|
|
fi
|
|
else
|
|
SYSIM_EX="$SI"
|
|
fi
|
|
done
|
|
cd - > /dev/null
|
|
|
|
echo "${bold}Command Examples:${normal}"
|
|
echo "${bold}./rootAVD.sh${normal}"
|
|
echo "${bold}./rootAVD.sh ListAllAVDs${normal}"
|
|
echo "${bold}./rootAVD.sh InstallApps${normal}"
|
|
echo ""
|
|
|
|
for SYSIM in $SYSIM_EX;do
|
|
if [[ ! "$SYSIM" == "" ]]; then
|
|
echo "${bold}./rootAVD.sh $SYSIM${normal}"
|
|
echo "${bold}./rootAVD.sh $SYSIM FAKEBOOTIMG${normal}"
|
|
echo "${bold}./rootAVD.sh $SYSIM DEBUG PATCHFSTAB GetUSBHPmodZ${normal}"
|
|
echo "${bold}./rootAVD.sh $SYSIM restore${normal}"
|
|
echo "${bold}./rootAVD.sh $SYSIM InstallKernelModules${normal}"
|
|
echo "${bold}./rootAVD.sh $SYSIM InstallPrebuiltKernelModules${normal}"
|
|
echo "${bold}./rootAVD.sh $SYSIM InstallPrebuiltKernelModules GetUSBHPmodZ PATCHFSTAB DEBUG${normal}"
|
|
echo "${bold}./rootAVD.sh $SYSIM AddRCscripts${normal}"
|
|
echo ""
|
|
else
|
|
echo ""
|
|
echo "No ramdisk files could be found"
|
|
echo ""
|
|
fi
|
|
done
|
|
}
|
|
|
|
ShowHelpText() {
|
|
bold=$(tput bold)
|
|
normal=$(tput sgr0)
|
|
echo "${bold}rootAVD A Script to root AVD by NewBit XDA${normal}"
|
|
echo ""
|
|
echo "Usage: ${bold}rootAVD [DIR/ramdisk.img] [OPTIONS] | [EXTRA ARGUMENTS]${normal}"
|
|
echo "or: ${bold}rootAVD [ARGUMENTS]${normal}"
|
|
echo ""
|
|
echo "Arguments:"
|
|
echo " ${bold}ListAllAVDs${normal} Lists Command Examples for ALL installed AVDs"
|
|
echo ""
|
|
echo " ${bold}InstallApps${normal} Just install all APKs placed in the Apps folder"
|
|
echo ""
|
|
echo "Main operation mode:"
|
|
echo " ${bold}DIR${normal} a path to an AVD system-image"
|
|
echo " - must always be the ${bold}1st${normal} Argument after rootAVD"
|
|
echo " "
|
|
echo "ADB Path | Ramdisk DIR | ANDROID_HOME:"
|
|
echo " ${bold}[M]ac/Darwin:${normal} export PATH=$defaultHOME_M/platform-tools:\$PATH"
|
|
echo " export PATH=\$ANDROID_HOME/platform-tools:\$PATH"
|
|
echo " system-images/android-\$API/google_apis_playstore/x86_64/"
|
|
echo " "
|
|
echo " ${bold}[L]inux:${normal} export PATH=$defaultHOME_L/platform-tools:\$PATH"
|
|
echo " export PATH=\$ANDROID_HOME/platform-tools:\$PATH"
|
|
echo " system-images/android-\$API/google_apis_playstore/x86_64/"
|
|
echo " "
|
|
echo " ${bold}[W]indows:${normal} set PATH=%LOCALAPPDATA%\Android\Sdk\platform-tools;%PATH%"
|
|
echo " set PATH=%ANDROID_HOME%\platform-tools;%PATH%"
|
|
echo " system-images\android-\$API\google_apis_playstore\x86_64\\"
|
|
echo " "
|
|
echo " ${bold}ANDROID_HOME:${normal} By default, the script uses ${bold}$defaultHOME${normal}, to set its Android Home"
|
|
echo " directory, search for AVD system-images and ADB binarys. This behaviour"
|
|
echo " can be overwritten by setting the ANDROID_HOME variable."
|
|
echo " e.g. ${bold}export ANDROID_HOME=~/Downloads/sdk${normal}"
|
|
echo " "
|
|
echo " ${bold}\$API:${normal} 25,29,30,31,32,33,34,UpsideDownCake,etc."
|
|
echo " "
|
|
echo "Options:"
|
|
echo " ${bold}restore${normal} restore all existing ${bold}.backup${normal} files, but doesn't delete them"
|
|
echo " - the AVD doesn't need to be running"
|
|
echo " - no other Argument after will be processed"
|
|
echo " "
|
|
echo " ${bold}InstallKernelModules${normal} install ${bold}custom build kernel and its modules${normal} into ramdisk.img"
|
|
echo " - kernel (bzImage) and its modules (initramfs.img) are inside rootAVD"
|
|
echo " - both files will be deleted after installation"
|
|
echo " "
|
|
echo " ${bold}InstallPrebuiltKernelModules${normal} download and install an ${bold}AOSP prebuilt kernel and its modules${normal} into ramdisk.img"
|
|
echo " - similar to ${bold}InstallKernelModules${normal}, but the AVD needs to be online"
|
|
echo " "
|
|
echo " ${bold}AddRCscripts${normal} install all custom *.rc scripts, placed in the rootAVD folder, into ramdisk.img/overlay.d/sbin"
|
|
echo " "
|
|
echo "Options are ${bold}exclusive${normal}, only one at the time will be processed."
|
|
echo " "
|
|
echo "Extra Arguments:"
|
|
echo " ${bold}DEBUG${normal} ${bold}Debugging Mode${normal}, prevents rootAVD to pull back any patched file"
|
|
echo " "
|
|
echo " ${bold}PATCHFSTAB${normal} ${bold}fstab.ranchu${normal} will get patched to automount Block Devices like ${bold}/dev/block/sda1${normal}"
|
|
echo " - other entries can be added in the script as well"
|
|
echo " - a custom build Kernel might be necessary"
|
|
echo " "
|
|
echo " ${bold}GetUSBHPmodZ${normal} The ${bold}USB HOST Permissions Module Zip${normal} will be downloaded into ${bold}/sdcard/Download${normal}"
|
|
echo " "
|
|
echo " ${bold}FAKEBOOTIMG${normal} Creates a ${bold}fake Boot.img${normal} file that can directly be patched from the ${bold}Magisk APP${normal}"
|
|
echo " - Magisk will be launched to patch the fake Boot.img ${bold}within 60s${normal}"
|
|
echo " - the fake Boot.img will be placed under ${bold}/sdcard/Download/fakeboot.img${normal}"
|
|
echo " "
|
|
echo "Extra Commands can be ${bold}combined${normal}, there is no particular order."
|
|
echo " "
|
|
echo "${bold}Notes: rootAVD will${normal}"
|
|
echo "- always create ${bold}.backup${normal} files of ${bold}ramdisk.img${normal} and ${bold}kernel-ranchu${normal}"
|
|
echo "- ${bold}replace${normal} both when done patching"
|
|
echo "- show a ${bold}Menu${normal}, to choose the Magisk Version ${bold}(Stable || Canary || Alpha)${normal}, if the AVD is ${bold}online${normal}"
|
|
echo "- make the ${bold}choosen${normal} Magisk Version to its ${bold}local${normal}"
|
|
echo "- install all APKs placed in the Apps folder"
|
|
FindSystemImages
|
|
exit
|
|
}
|
|
|
|
ProcessArguments() {
|
|
DEBUG=false
|
|
PATCHFSTAB=false
|
|
GetUSBHPmodZ=false
|
|
RAMDISKIMG=false
|
|
restore=false
|
|
InstallKernelModules=false
|
|
InstallPrebuiltKernelModules=false
|
|
ListAllAVDs=false
|
|
InstallApps=false
|
|
UpdateBusyBoxScript=false
|
|
AddRCscripts=false
|
|
BLUESTACKS=false
|
|
toggleRamdisk=false
|
|
FAKEBOOTIMG=false
|
|
|
|
# Call rootAVD with SOURCING if you just want to source it
|
|
# or export SOURCING=true if you are in crosh
|
|
if [ -z "$SOURCING" ]; then
|
|
SOURCING=false
|
|
fi
|
|
if [[ "$@" == *"SOURCING"* ]]; then
|
|
SOURCING=true
|
|
fi
|
|
|
|
# While debugging and developing you can turn this flag on
|
|
if [[ "$@" == *"DEBUG"* ]]; then
|
|
DEBUG=true
|
|
# Shows whatever line get executed...
|
|
#set -x
|
|
fi
|
|
|
|
# Call rootAVD with PATCHFSTAB if you want the RAMDISK merge your modded fstab.ranchu before Magisk Mirror gets mounted
|
|
if [[ "$@" == *"PATCHFSTAB"* ]]; then
|
|
PATCHFSTAB=true
|
|
fi
|
|
|
|
# Call rootAVD with GetUSBHPmodZ to download the usbhostpermissons module
|
|
if [[ "$@" == *"GetUSBHPmodZ"* ]]; then
|
|
GetUSBHPmodZ=true
|
|
fi
|
|
|
|
# Call rootAVD with ListAllAVDs to show all AVDs with command examples
|
|
if [[ "$@" == *"ListAllAVDs"* ]]; then
|
|
ListAllAVDs=true
|
|
fi
|
|
|
|
# Call rootAVD with InstallApps to just install all APKs placed in the Apps folder
|
|
if [[ "$@" == *"InstallApps"* ]]; then
|
|
InstallApps=true
|
|
fi
|
|
|
|
# Call rootAVD with UpdateBusyBoxScript to update the Busybox Version within the rootAVD.sh
|
|
if [[ "$@" == *"UpdateBusyBoxScript"* ]]; then
|
|
UpdateBusyBoxScript=true
|
|
fi
|
|
|
|
# Call rootAVD with AddRCscripts to add custom *.rc scripts into ramdisk.img/sbin/*.rc
|
|
if [[ "$@" == *"AddRCscripts"* ]]; then
|
|
AddRCscripts=true
|
|
fi
|
|
|
|
|
|
RAMDISKIMG=true
|
|
|
|
case $2 in
|
|
"restore" )
|
|
restore=true
|
|
;;
|
|
|
|
"InstallKernelModules" )
|
|
InstallKernelModules=true
|
|
;;
|
|
|
|
"InstallPrebuiltKernelModules" )
|
|
InstallPrebuiltKernelModules=true
|
|
;;
|
|
esac
|
|
|
|
# Call rootAVD with BLUESTACKS if you want to patch the ramdisk.img of a BlueStacks System
|
|
if [[ "$@" == *"BLUESTACKS"* ]]; then
|
|
BLUESTACKS=true
|
|
RAMDISKIMG=false
|
|
fi
|
|
|
|
# Call rootAVD with toggleRamdisk if you want to toggle between patched and original ramdisk.img
|
|
if [[ "$@" == *"toggleRamdisk"* ]]; then
|
|
toggleRamdisk=true
|
|
fi
|
|
|
|
# Call rootAVD with FAKEBOOTIMG if you want to create a fake boot.img to patch the ramdisk.img via direct install
|
|
if [[ "$@" == *"FAKEBOOTIMG"* ]]; then
|
|
FAKEBOOTIMG=true
|
|
fi
|
|
|
|
export DEBUG
|
|
export PATCHFSTAB
|
|
export GetUSBHPmodZ
|
|
export RAMDISKIMG
|
|
export restore
|
|
export InstallKernelModules
|
|
export InstallPrebuiltKernelModules
|
|
export ListAllAVDs
|
|
export InstallApps
|
|
export UpdateBusyBoxScript
|
|
export AddRCscripts
|
|
export BLUESTACKS
|
|
export toggleRamdisk
|
|
export SOURCING
|
|
export FAKEBOOTIMG
|
|
}
|
|
|
|
# Script Entry Point
|
|
# Checking in which shell we are
|
|
|
|
INEMULATOR=false
|
|
SHELLRESULT=$(getprop 2>/dev/null)
|
|
SHELLRESULT="$?"
|
|
if [[ "$SHELLRESULT" == "0" ]]; then
|
|
INEMULATOR=true
|
|
DERIVATE=$(getprop ro.boot.hardware 2>/dev/null)
|
|
if [[ "$DERIVATE" == "" ]]; then
|
|
$(which /system/xbin/bstk/su > /dev/null 2>&1)
|
|
DERIVATE="$?"
|
|
if [[ "$DERIVATE" == "0" ]]; then
|
|
DERIVATE="BlueStacks"
|
|
fi
|
|
fi
|
|
if [ ! -z $PREPBBMAGISK ]; then
|
|
echo "[-] We are now in Magisk Busybox STANDALONE (D)ASH"
|
|
# Don't use $BB from now on
|
|
else
|
|
echo "[!] We are in a $DERIVATE emulator shell"
|
|
fi
|
|
fi
|
|
|
|
#if [[ $SHELL == "ranchu" ]]; then
|
|
# echo "[!] We are in an emulator shell"
|
|
# RANCHU=true
|
|
#fi
|
|
#if [[ $SHELL == "cheets" ]]; then
|
|
# echo "[!] We are in a ChromeOS shell"
|
|
# RANCHU=true
|
|
#fi
|
|
|
|
export DERIVATE
|
|
export INEMULATOR
|
|
|
|
if $INEMULATOR; then
|
|
InstallMagiskToAVD $@
|
|
return 0
|
|
fi
|
|
|
|
ProcessArguments $@
|
|
GetANDROIDHOME
|
|
|
|
if ( "$SOURCING" ); then
|
|
return
|
|
fi
|
|
|
|
if ( "$DEBUG" ); then
|
|
echo "[!] We are in Debug Mode"
|
|
echo "DEBUG: $DEBUG"
|
|
echo "PATCHFSTAB: $PATCHFSTAB"
|
|
echo "GetUSBHPmodZ: $GetUSBHPmodZ"
|
|
echo "RAMDISKIMG: $RAMDISKIMG"
|
|
echo "restore: $restore"
|
|
echo "InstallKernelModules: $InstallKernelModules"
|
|
echo "InstallPrebuiltKernelModules: $InstallPrebuiltKernelModules"
|
|
echo "ListAllAVDs: $ListAllAVDs"
|
|
echo "InstallApps: $InstallApps"
|
|
echo "UpdateBusyBoxScript: $UpdateBusyBoxScript"
|
|
echo "AddRCscripts: $AddRCscripts"
|
|
echo "BLUESTACKS: $BLUESTACKS"
|
|
echo "toggleRamdisk: $toggleRamdisk"
|
|
echo "SOURCING: $SOURCING"
|
|
echo "FAKEBOOTIMG: $FAKEBOOTIMG"
|
|
fi
|
|
|
|
if ( ! "$InstallApps" && ! "$BLUESTACKS"); then
|
|
# If there is no file to work with, abort the script, except if it is a BlueStacks System
|
|
if [[ "$1" == "" ]]; then
|
|
ShowHelpText
|
|
fi
|
|
if ( ! "$restore"); then
|
|
if (checkfile "$ANDROIDHOME/$1" -eq 0); then
|
|
ShowHelpText
|
|
fi
|
|
fi
|
|
|
|
fi
|
|
|
|
echo "[!] and we are NOT in an emulator shell"
|
|
|
|
CopyMagiskToAVD $@
|
|
|
|
exit |