From b37bad35c28470904fe9a616e4c7332cc6d0032b Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Wed, 2 Aug 2017 02:21:50 +0800 Subject: [PATCH] Fuse busybox into update-binary and remove from Magisk Manager APK --- MagiskManager | 2 +- build.py | 101 +++++++++++++++++++--------------- jni/daemon/bootstages.c | 21 +++---- scripts/flash_script.sh | 12 +--- scripts/magisk_uninstaller.sh | 10 ++-- scripts/uninstaller_loader.sh | 12 ++-- scripts/update_binary.sh | 15 +++++ scripts/util_functions.sh | 12 ++-- 8 files changed, 105 insertions(+), 80 deletions(-) create mode 100644 scripts/update_binary.sh diff --git a/MagiskManager b/MagiskManager index 3550d1e61..8195a4d61 160000 --- a/MagiskManager +++ b/MagiskManager @@ -1 +1 @@ -Subproject commit 3550d1e61cba0cf482e1d3cf8e92b0f74aae38f9 +Subproject commit 8195a4d6161dd16d67ece6e643670ae9d3118cdb diff --git a/build.py b/build.py index 6acbab9b4..1ef0f13fe 100755 --- a/build.py +++ b/build.py @@ -35,6 +35,8 @@ import zipfile import datetime import errno import shutil +import gzip +import base64 def silentremove(file): try: @@ -58,11 +60,8 @@ def build_all(args): def build_binary(args): header('* Building Magisk binaries') - # Force update Android.mk footprint to trigger recompilation - with open(os.path.join('jni', 'Android.mk'), 'r') as makefile: - content = makefile.read() - with open(os.path.join('jni', 'Android.mk'), 'w') as makefile: - makefile.write(content) + # Force update Android.mk timestamp to trigger recompilation + os.utime(os.path.join('jni', 'Android.mk')) ndk_build = os.path.join(os.environ['ANDROID_HOME'], 'ndk-bundle', 'ndk-build') debug_flag = '' if args.release else '-DMAGISK_DEBUG' @@ -74,17 +73,6 @@ def build_binary(args): def build_apk(args): header('* Building Magisk Manager') - for arch in ['armeabi-v7a', 'x86']: - source = os.path.join('libs', arch, 'busybox') - target = os.path.join('MagiskManager', 'app', 'src', 'main', 'jniLibs', arch) - if not os.path.exists(source): - error('{} does not exist! Please build \'binary\' before building apk'.format(source)) - if not os.path.exists(target): - os.makedirs(target) - target = os.path.join(target, 'libbusybox.so') - print('cp: {} -> {}'.format(source, target)) - shutil.copyfile(source, target) - for key in ['public.certificate.x509.pem', 'private.key.pk8']: source = os.path.join('ziptools', key) target = os.path.join('MagiskManager', 'app', 'src', 'main', 'assets', key) @@ -174,11 +162,40 @@ def sign_adjust_zip(unsigned, output): silentremove('tmp_signed.zip') silentremove('tmp_adjusted.zip') +def gen_update_binary(): + update_bin = [] + bb = os.path.join('libs', 'armeabi-v7a', 'busybox') + if not os.path.exists(bb): + error('{} does not exist! Please build \'binary\' before zipping!'.format(bb)) + with open(bb, 'rb') as busybox: + update_bin.append('#! /sbin/sh\nBB_ARM=') + update_bin.append(base64.b64encode(gzip.compress(busybox.read())).decode('ascii')) + bb = os.path.join('libs', 'x86', 'busybox') + if not os.path.exists(bb): + error('{} does not exist! Please build \'binary\' before zipping!'.format(bb)) + with open(bb, 'rb') as busybox: + update_bin.append('\nBB_X86=') + update_bin.append(base64.b64encode(gzip.compress(busybox.read())).decode('ascii')) + update_bin.append('\n') + with open(os.path.join('scripts', 'update_binary.sh'), 'r') as script: + update_bin.append(script.read()) + return ''.join(update_bin) + def zip_main(args): header('* Packing Flashable Zip') - with zipfile.ZipFile('tmp_unsigned.zip', 'w', compression=zipfile.ZIP_DEFLATED) as zipf: - # Compiled Binaries + with zipfile.ZipFile('tmp_unsigned.zip', 'w', compression=zipfile.ZIP_DEFLATED, allowZip64=False) as zipf: + # META-INF + # update-binary + target = os.path.join('META-INF', 'com', 'google', 'android', 'update-binary') + print('zip: ' + target) + zipf.writestr(target, gen_update_binary()) + # updater-script + source = os.path.join('scripts', 'flash_script.sh') + target = os.path.join('META-INF', 'com', 'google', 'android', 'updater-script') + zip_with_msg(zipf, source, target) + + # Binaries for lib_dir, zip_dir in [('arm64-v8a', 'arm64'), ('armeabi-v7a', 'arm'), ('x86', 'x86'), ('x86_64', 'x64')]: for binary in ['magisk', 'magiskboot']: source = os.path.join('libs', lib_dir, binary) @@ -192,22 +209,6 @@ def zip_main(args): zip_with_msg(zipf, source, target) # Scripts - # flash_script.sh - source = os.path.join('scripts', 'flash_script.sh') - target = os.path.join('META-INF', 'com', 'google', 'android', 'update-binary') - zip_with_msg(zipf, source, target) - # addon.d.sh - source = os.path.join('scripts', 'addon.d.sh') - target = os.path.join('addon.d', '99-magisk.sh') - zip_with_msg(zipf, source, target) - # updater-script - target = os.path.join('META-INF', 'com', 'google', 'android', 'updater-script') - print('zip: ' + target) - zipf.writestr(target, '#MAGISK\n') - # init.magisk.rc - source = os.path.join('scripts', 'init.magisk.rc') - target = os.path.join('common', 'init.magisk.rc') - zip_with_msg(zipf, source, target) # boot_patch.sh source = os.path.join('scripts', 'boot_patch.sh') target = os.path.join('common', 'boot_patch.sh') @@ -221,6 +222,15 @@ def zip_main(args): target = os.path.join('common', 'util_functions.sh') print('zip: ' + source + ' -> ' + target) zipf.writestr(target, util_func) + # addon.d.sh + source = os.path.join('scripts', 'addon.d.sh') + target = os.path.join('addon.d', '99-magisk.sh') + zip_with_msg(zipf, source, target) + # init.magisk.rc + source = os.path.join('scripts', 'init.magisk.rc') + target = os.path.join('common', 'init.magisk.rc') + zip_with_msg(zipf, source, target) + # Prebuilts for chromeos in ['futility', 'kernel_data_key.vbprivk', 'kernel.keyblock']: source = os.path.join('chromeos', chromeos) @@ -234,8 +244,18 @@ def zip_main(args): def zip_uninstaller(args): header('* Packing Uninstaller Zip') - with zipfile.ZipFile('tmp_unsigned.zip', 'w', compression=zipfile.ZIP_DEFLATED) as zipf: - # Compiled Binaries + with zipfile.ZipFile('tmp_unsigned.zip', 'w', compression=zipfile.ZIP_DEFLATED, allowZip64=False) as zipf: + # META-INF + # update-binary + target = os.path.join('META-INF', 'com', 'google', 'android', 'update-binary') + print('zip: ' + target) + zipf.writestr(target, gen_update_binary()) + # updater-script + source = os.path.join('scripts', 'uninstaller_loader.sh') + target = os.path.join('META-INF', 'com', 'google', 'android', 'updater-script') + zip_with_msg(zipf, source, target) + + # Binaries for lib_dir, zip_dir in [('arm64-v8a', 'arm64'), ('armeabi-v7a', 'arm'), ('x86', 'x86'), ('x86_64', 'x64')]: source = os.path.join('libs', lib_dir, 'magiskboot') target = os.path.join(zip_dir, 'magiskboot') @@ -245,6 +265,7 @@ def zip_uninstaller(args): target = 'magisk_uninstaller.sh' zip_with_msg(zipf, source, target) + # Scripts # util_functions.sh source = os.path.join('scripts', 'util_functions.sh') with open(source, 'r') as script: @@ -255,14 +276,6 @@ def zip_uninstaller(args): print('zip: ' + source + ' -> ' + target) zipf.writestr(target, util_func) - source = os.path.join('scripts', 'uninstaller_loader.sh') - target = os.path.join('META-INF', 'com', 'google', 'android', 'update-binary') - zip_with_msg(zipf, source, target) - - target = os.path.join('META-INF', 'com', 'google', 'android', 'updater-script') - print('zip: ' + target) - zipf.writestr(target, '#MAGISK\n') - # Prebuilts for chromeos in ['futility', 'kernel_data_key.vbprivk', 'kernel.keyblock']: source = os.path.join('chromeos', chromeos) diff --git a/jni/daemon/bootstages.c b/jni/daemon/bootstages.c index 9a8438540..5024f98a1 100644 --- a/jni/daemon/bootstages.c +++ b/jni/daemon/bootstages.c @@ -502,13 +502,6 @@ void post_fs_data(int client) { LOGI("** post-fs-data mode running\n"); - // uninstaller - if (access(UNINSTALLER, F_OK) == 0) { - close(open(UNBLOCKFILE, O_RDONLY | O_CREAT)); - system("(BOOTMODE=true sh " UNINSTALLER ") &"); - return; - } - // Allocate buffer if (buf == NULL) buf = xmalloc(PATH_MAX); if (buf2 == NULL) buf2 = xmalloc(PATH_MAX); @@ -538,6 +531,17 @@ void post_fs_data(int client) { goto unblock; } + // Link busybox + link_busybox(); + + // uninstaller + if (access(UNINSTALLER, F_OK) == 0) { + close(open(UNBLOCKFILE, O_RDONLY | O_CREAT)); + bb_path(); + system("(BOOTMODE=true sh " UNINSTALLER ") &"); + return; + } + int new_img = 0; if (access(MAINIMG, F_OK) == -1) { @@ -559,9 +563,6 @@ void post_fs_data(int client) { xmkdir(COREDIR "/props", 0755); } - // Link busybox - link_busybox(); - // Core only mode if (access(DISABLEFILE, F_OK) == 0) goto core_only; diff --git a/scripts/flash_script.sh b/scripts/flash_script.sh index 0f22f1be6..f1e96a33b 100644 --- a/scripts/flash_script.sh +++ b/scripts/flash_script.sh @@ -1,4 +1,4 @@ -#!/sbin/sh +#MAGISK ########################################################################################## # # Magisk Flash Script @@ -31,10 +31,6 @@ umask 022 OUTFD=$2 ZIP=$3 -rm -rf $TMPDIR 2>/dev/null -mkdir -p $INSTALLER -unzip -o "$ZIP" -d $INSTALLER 2>/dev/null - if [ ! -d "$COMMONDIR" ]; then echo "! Unable to extract zip file!" exit 1 @@ -92,16 +88,14 @@ rm -rf $MAGISKBIN 2>/dev/null mkdir -p $MAGISKBIN cp -af $BINDIR/. $COMMONDIR/. $MAGISKBIN cp -af $CHROMEDIR $MAGISKBIN -# Extract busybox -[ $ARCH = "arm" -o $ARCH = "arm64" ] && BBPATH=lib/armeabi-v7a || BBPATH=lib/x86 -unzip -p $INSTALLER/common/magisk.apk $BBPATH/libbusybox.so > $MAGISKBIN/busybox +cp -af $TMPDIR/bin/busybox $MAGISKBIN/busybox chmod -R 755 $MAGISKBIN # addon.d if [ -d /system/addon.d ]; then ui_print "- Adding addon.d survival script" mount -o rw,remount /system - cp $INSTALLER/addon.d/99-magisk.sh /system/addon.d/99-magisk.sh + cp -af $INSTALLER/addon.d/99-magisk.sh /system/addon.d/99-magisk.sh chmod 755 /system/addon.d/99-magisk.sh fi diff --git a/scripts/magisk_uninstaller.sh b/scripts/magisk_uninstaller.sh index f63a33aef..961561229 100644 --- a/scripts/magisk_uninstaller.sh +++ b/scripts/magisk_uninstaller.sh @@ -39,11 +39,6 @@ abort_wrap() { fi } -if [ ! -d $MAGISKBIN -o ! -f $MAGISKBIN/magiskboot -o ! -f $MAGISKBIN/util_functions.sh ]; then - ui_print_wrap "! Cannot find $MAGISKBIN" - exit 1 -fi - [ -z $BOOTMODE ] && BOOTMODE=false MAGISKBIN=/data/magisk @@ -52,6 +47,11 @@ CHROMEDIR=$MAGISKBIN/chromeos # Default permissions umask 022 +if [ ! -f $MAGISKBIN/magiskboot -o ! -f $MAGISKBIN/util_functions.sh ]; then + ui_print_wrap "! Cannot find $MAGISKBIN" + exit 1 +fi + # Load utility functions . $MAGISKBIN/util_functions.sh diff --git a/scripts/uninstaller_loader.sh b/scripts/uninstaller_loader.sh index aba2338f9..1ebbc5afd 100644 --- a/scripts/uninstaller_loader.sh +++ b/scripts/uninstaller_loader.sh @@ -3,7 +3,7 @@ # # Magisk Uninstaller (used in recovery) # by topjohnwu -# +# # This script will load the real uninstaller in a flashable zip # ########################################################################################## @@ -13,17 +13,16 @@ ########################################################################################## BOOTMODE=false -INSTALLER=/tmp/uninstall +# This path should work in any cases +TMPDIR=/dev/tmp + +INSTALLER=$TMPDIR/install # Default permissions umask 022 OUTFD=$2 ZIP=$3 -rm -rf $INSTALLER 2>/dev/null -mkdir -p $INSTALLER -unzip -o "$ZIP" -d $INSTALLER 2>/dev/null - if [ ! -f $INSTALLER/util_functions.sh ]; then echo "! Failed: Unable to extract zip file!" exit 1 @@ -68,6 +67,7 @@ if is_mounted /data; then mkdir -p $MAGISKBIN cp -af $BINDIR/. $MAGISKBIN cp -af $CHROMEDIR $MAGISKBIN + cp -af $TMPDIR/bin/busybox $MAGISKBIN/busybox cp -af $INSTALLER/util_functions.sh $MAGISKBIN chmod -R 755 $MAGISKBIN # Run the acttual uninstallation diff --git a/scripts/update_binary.sh b/scripts/update_binary.sh new file mode 100644 index 000000000..ea4fa3855 --- /dev/null +++ b/scripts/update_binary.sh @@ -0,0 +1,15 @@ +# BB_ARM and BB_X86 should be generated in build.py +TMPDIR=/dev/tmp +INSTALLER=$TMPDIR/install +BBDIR=$TMPDIR/bin +BBBIN=$BBDIR/busybox +rm -rf $TMPDIR 2>/dev/null; mkdir -p $BBDIR; touch $BBBIN; chmod 755 $BBBIN +echo $BB_ARM | base64 -d | gzip -d > $BBBIN +if ! $BBBIN --install -s $TMPDIR/bin >/dev/null 2>&1; then + echo $BB_X86 | base64 -d | gzip -d > $BBBIN + $BBBIN --install -s $TMPDIR/bin >/dev/null 2>&1 || exit 1 +fi +export PATH=$BBDIR:$PATH +mkdir -p $INSTALLER +unzip -o "$3" -d $INSTALLER +exec sh $INSTALLER/META-INF/com/google/android/updater-script $@ diff --git a/scripts/util_functions.sh b/scripts/util_functions.sh index 0da951afa..17e6e2f4b 100644 --- a/scripts/util_functions.sh +++ b/scripts/util_functions.sh @@ -127,11 +127,13 @@ recovery_actions() { # Preserve environment varibles OLD_PATH=$PATH OLD_LD_PATH=$LD_LIBRARY_PATH - # Add busybox to PATH - mkdir -p $TMPDIR/bin - ln -s $MAGISKBIN/busybox $TMPDIR/bin/busybox - $MAGISKBIN/busybox --install -s $TMPDIR/bin - export PATH=$TMPDIR/bin:$PATH + if [ ! -d $TMPDIR/bin ]; then + # Add busybox to PATH + mkdir -p $TMPDIR/bin + ln -s $MAGISKBIN/busybox $TMPDIR/bin/busybox + $MAGISKBIN/busybox --install -s $TMPDIR/bin + export PATH=$TMPDIR/bin:$PATH + fi # Temporarily block out all custom recovery binaries/libs mv /sbin /sbin_tmp # Add all possible library paths