#!/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 INITLD=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 if [ -e $BASEDIR/init-ld ]; then echo "[*] init LD_PRELOAD is present" INITLD=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" USBHPZ="https://gitlab.com/newbit/usbhostpermissions/-/releases/permalink/latest/downloads/usbhostpermissions" if ls $USBHPZSDDL/usbhostpermissions*.zip 1> /dev/null 2>&1; then echo "[*] USB HOST Permissions Module Zip is already present" else echo "[*] Downloading USB HOST Permissions Module Zip" $BB wget --no-check-certificate $USBHPZ -S -o response.txt USBHPZ=$(cat response.txt | $BB grep -Eo 'https://[^"]+\.(zip)') $BB wget -q -P $USBHPZSDDL --no-check-certificate $USBHPZ 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 usbhostpermissions 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 } AllowPermissionsTo3rdPartyAPKs(){ echo "[!] allowing MANAGE_EXTERNAL_STORAGE permissions to..." local PKG_NAMES=$(pm list packages -3 | cut -f 2 -d ":") > /dev/null 2>&1 local PKG_NAME="" for PKG_NAME in $PKG_NAMES; do echo "[-] $PKG_NAME" appops set $PKG_NAME MANAGE_EXTERNAL_STORAGE allow done } 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"* ]]; 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" # Compress to save precious ramdisk space if ! $INITLD ; then if $IS32BITONLY || ! $IS64BITONLY ; then PREINITDEVICE=$($BASEDIR/magisk32 --preinit-device) $BASEDIR/magiskboot compress=xz magisk32 magisk32.xz fi if $IS64BITONLY || ! $IS32BITONLY ; then PREINITDEVICE=$($BASEDIR/magisk64 --preinit-device) $BASEDIR/magiskboot compress=xz magisk64 magisk64.xz fi else PREINITDEVICE=$($BASEDIR/magisk --preinit-device) $BASEDIR/magiskboot compress=xz magisk magisk.xz $BASEDIR/magiskboot compress=xz init-ld init-ld.xz fi $INITLD && SKIPLD="" || SKIPLD="#" echo "KEEPVERITY=$KEEPVERITY" > config echo "KEEPFORCEENCRYPT=$KEEPFORCEENCRYPT" >> config echo "RECOVERYMODE=$RECOVERYMODE" >> config if [ -n "$PREINITDEVICE" ]; then echo "[*] Pre-init storage partition: $PREINITDEVICE" echo "PREINITDEVICE=$PREINITDEVICE" >> config fi # 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 $IS64BITONLY && SKIP32="#" || SKIP32="" $IS64BIT && SKIP64="" || SKIP64="#" $INITLD && SKIP32="#" $INITLD && 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" \ "$SKIPLD add 0644 overlay.d/sbin/magisk.xz magisk.xz" \ "$SKIPSTUB add 0644 overlay.d/sbin/stub.xz stub.xz" \ "$SKIPLD add 0644 overlay.d/sbin/init-ld.xz init-ld.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>\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 [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 [context] # if [context] is empty, it will default to "u:object_r:system_file:s0" # for all files in , it will call: # set_perm file owner group filepermission context # for all directories in (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 AllowPermissionsTo3rdPartyAPKs 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, 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 usbhostpermissions 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