Stop embedding magisk in magiskinit

This commit is contained in:
topjohnwu 2021-01-18 04:25:26 -08:00
parent 42278f12ff
commit 5a71998b4e
11 changed files with 140 additions and 136 deletions

View File

@ -65,6 +65,16 @@ abstract class MagiskInstallImpl : KoinComponent {
logs = NOPList.getInstance()
}
companion object {
private val ABI_MAP = TreeMap<String, String>()
init {
ABI_MAP["armeabi-v7a"] = "arm"
ABI_MAP["arm64-v8a"] = "arm64"
ABI_MAP["x86"] = "x86"
ABI_MAP["x86_64"] = "x64"
}
}
protected constructor(zip: Uri, out: MutableList<String>, err: MutableList<String>) {
console = out
logs = err
@ -103,44 +113,52 @@ abstract class MagiskInstallImpl : KoinComponent {
@Suppress("DEPRECATION")
private fun extractZip(): Boolean {
val arch = if (Build.VERSION.SDK_INT >= 21) {
val abis = listOf(*Build.SUPPORTED_ABIS)
if (abis.contains("x86")) "x86" else "arm"
val arch: String
val arch32: String
if (Build.VERSION.SDK_INT >= 21) {
arch = ABI_MAP[Build.SUPPORTED_ABIS[0]]!!
arch32 = ABI_MAP[Build.SUPPORTED_32_BIT_ABIS[0]]!!
} else {
if (Build.CPU_ABI == "x86") "x86" else "arm"
arch = ABI_MAP[Build.CPU_ABI]!!
arch32 = arch
}
console.add("- Device platform: " + Build.CPU_ABI)
console.add("- Device platform: $arch")
console.add("- Magisk Manager: ${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})")
console.add("- Install target: ${Info.remote.magisk.version} (${Info.remote.magisk.versionCode})")
fun newFile(name: String): File {
return if (installDir is SuFile)
SuFile(installDir, name)
else
File(installDir, name)
}
try {
ZipInputStream(zipUri.inputStream().buffered()).use { zi ->
lateinit var ze: ZipEntry
while (zi.nextEntry?.let { ze = it } != null) {
if (ze.isDirectory)
continue
var name: String? = null
val names = arrayOf("$arch/", "common/", "META-INF/com/google/android/update-binary")
for (n in names) {
ze.name.run {
if (startsWith(n)) {
name = substring(lastIndexOf('/') + 1)
if (ze.name.startsWith("chromeos/")) {
name = ze.name
} else {
for (n in listOf("$arch32/", "common/", "META-INF/com/google/android/update-binary")) {
if (ze.name.startsWith(n)) {
name = ze.name.substring(ze.name.lastIndexOf('/') + 1)
break
}
}
name ?: continue
break
}
if (name == null && ze.name.startsWith("chromeos/"))
name = ze.name
name?.also {
val dest = if (installDir is SuFile)
SuFile(installDir, it)
else
File(installDir, it)
dest.parentFile!!.mkdirs()
SuFileOutputStream(dest).use { s -> zi.copyTo(s) }
} ?: continue
name ?: continue
val dest = newFile(name)
dest.parentFile!!.mkdirs()
SuFileOutputStream(dest).use { s -> zi.copyTo(s) }
}
}
} catch (e: IOException) {
@ -149,9 +167,9 @@ abstract class MagiskInstallImpl : KoinComponent {
return false
}
val init64 = SuFile.open(installDir, "magiskinit64")
if (Build.VERSION.SDK_INT >= 21 && Build.SUPPORTED_64_BIT_ABIS.isNotEmpty()) {
init64.renameTo(SuFile.open(installDir, "magiskinit"))
val init64 = newFile("magiskinit64")
if (init64.exists() && arch != arch32) {
init64.renameTo(newFile("magiskinit"))
} else {
init64.delete()
}
@ -324,9 +342,12 @@ abstract class MagiskInstallImpl : KoinComponent {
return false
}
if (!("KEEPFORCEENCRYPT=${Config.keepEnc} KEEPVERITY=${Config.keepVerity} " +
"RECOVERYMODE=${Config.recovery} sh update-binary " +
"sh boot_patch.sh $srcBoot").sh().isSuccess) {
val FLAGS =
"KEEPFORCEENCRYPT=${Config.keepEnc} " +
"KEEPVERITY=${Config.keepVerity} " +
"RECOVERYMODE=${Config.recovery}"
if (!("$FLAGS sh update-binary sh boot_patch.sh $srcBoot").sh().isSuccess) {
return false
}

View File

@ -7,7 +7,7 @@ run_delay() {
}
env_check() {
for file in busybox magisk magiskboot magiskinit util_functions.sh boot_patch.sh; do
for file in busybox magiskboot magiskinit util_functions.sh boot_patch.sh; do
[ -f $MAGISKBIN/$file ] || return 1
done
return 0

View File

@ -287,18 +287,6 @@ def run_ndk_build(flags):
def dump_bin_headers():
for arch in archs:
bin_file = op.join('native', 'out', arch, 'magisk')
if not op.exists(bin_file):
error('Build "magisk" before building "magiskinit"')
with open(op.join('native', 'out', arch, 'binaries_arch.h'), 'w') as out:
with open(bin_file, 'rb') as src:
binary_dump(src, out, 'magisk_xz')
for arch, arch32 in list(zip(arch64, archs)):
bin_file = op.join('native', 'out', arch, 'magisk')
with open(op.join('native', 'out', arch32, 'binaries_arch64.h'), 'w') as out:
with open(bin_file, 'rb') as src:
binary_dump(src, out, 'magisk_xz')
stub = op.join(config['outdir'], 'stub-release.apk')
if not op.exists(stub):
error('Build stub APK before building "magiskinit"')
@ -347,26 +335,31 @@ def build_binary(args):
run_ndk_build('B_MAGISK=1 B_64BIT=1')
clean_elf()
if 'magiskinit' in args.target:
dump_bin_headers()
run_ndk_build('B_INIT=1')
run_ndk_build('B_INIT64=1')
if 'magiskpolicy' in args.target:
run_ndk_build('B_POLICY=1')
if 'resetprop' in args.target:
run_ndk_build('B_PROP=1')
if 'magiskboot' in args.target:
run_ndk_build('B_BOOT=1')
if 'busybox' in args.target:
run_ndk_build('B_BB=1')
if 'test' in args.target:
run_ndk_build('B_TEST=1 B_64BIT=1')
# 32-bit only targets can be built in one command
flag = ''
if 'magiskinit' in args.target:
dump_bin_headers()
flag += ' B_INIT=1'
if 'magiskpolicy' in args.target:
flag += ' B_POLICY=1'
if 'resetprop' in args.target:
flag += ' B_PROP=1'
if 'magiskboot' in args.target:
flag += ' B_BOOT=1'
if 'busybox' in args.target:
flag += ' B_BB=1'
if flag:
run_ndk_build(flag)
def build_apk(args, module):
build_type = 'Release' if args.release or module == 'stub' else 'Debug'
@ -440,12 +433,17 @@ def zip_main(args):
zip_with_msg(zipf, source, target)
# Binaries
for lib_dir, zip_dir in [('armeabi-v7a', 'arm'), ('x86', 'x86')]:
for binary in ['magiskinit', 'magiskinit64', 'magiskboot']:
for lib_dir, zip_dir in zip(archs, ('arm', 'x86')):
for binary in ['magiskinit', 'magiskboot', 'magisk']:
source = op.join('native', 'out', lib_dir, binary)
target = op.join(zip_dir, binary)
target = op.join(zip_dir, 'magisk32' if binary == 'magisk' else binary)
zip_with_msg(zipf, source, target)
for lib_dir, zip_dir in zip(arch64, ('arm', 'x86')):
source = op.join('native', 'out', lib_dir, 'magisk')
target = op.join(zip_dir, 'magisk64')
zip_with_msg(zipf, source, target)
# APK
source = op.join(
config['outdir'], 'app-release.apk' if args.release else 'app-debug.apk')

View File

@ -54,21 +54,10 @@ endif
include $(CLEAR_VARS)
ifdef B_INIT
LOCAL_MODULE := magiskinit
BB_INIT := 1
else ifdef B_INIT64
LOCAL_MODULE := magiskinit64
LOCAL_CPPFLAGS += -DUSE_64BIT
BB_INIT := 1
endif
ifdef BB_INIT
LOCAL_STATIC_LIBRARIES := libsepol libxz libutils
LOCAL_C_INCLUDES := \
jni/include \
out \
out/$(TARGET_ARCH_ABI)
LOCAL_C_INCLUDES := jni/include out
LOCAL_SRC_FILES := \
init/init.cpp \

View File

@ -10,12 +10,6 @@
#include <utils.hpp>
#include "binaries.h"
#ifdef USE_64BIT
#include "binaries_arch64.h"
#else
#include "binaries_arch.h"
#endif
#include "init.hpp"
using namespace std;
@ -26,7 +20,7 @@ using namespace std;
constexpr int (*init_applet_main[])(int, char *[]) =
{ magiskpolicy_main, magiskpolicy_main, nullptr };
static bool unxz(int fd, const uint8_t *buf, size_t size) {
bool unxz(int fd, const uint8_t *buf, size_t size) {
uint8_t out[8192];
xz_crc32_init();
struct xz_dec *dec = xz_dec_init(XZ_DYNALLOC, 1 << 26);
@ -49,16 +43,6 @@ static bool unxz(int fd, const uint8_t *buf, size_t size) {
return true;
}
int dump_magisk(const char *path, mode_t mode) {
int fd = xopen(path, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, mode);
if (fd < 0)
return 1;
if (!unxz(fd, magisk_xz, sizeof(magisk_xz)))
return 1;
close(fd);
return 0;
}
static int dump_manager(const char *path, mode_t mode) {
int fd = xopen(path, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, mode);
if (fd < 0)
@ -147,10 +131,9 @@ int main(int argc, char *argv[]) {
#endif
if (argc > 1 && argv[1] == "-x"sv) {
if (argv[2] == "magisk"sv)
return dump_magisk(argv[3], 0755);
else if (argv[2] == "manager"sv)
if (argc > 2 && argv[2] == "manager"sv)
return dump_manager(argv[3], 0644);
return 1;
}
if (getpid() != 1)
@ -166,18 +149,16 @@ int main(int argc, char *argv[]) {
// This will also mount /sys and /proc
load_kernel_info(&cmd);
if (cmd.skip_initramfs) {
if (cmd.skip_initramfs)
init = new SARInit(argv, &cmd);
} else {
if (cmd.force_normal_boot)
init = new FirstStageInit(argv, &cmd);
else if (access("/sbin/recovery", F_OK) == 0 || access("/system/bin/recovery", F_OK) == 0)
init = new RecoveryInit(argv, &cmd);
else if (check_two_stage())
init = new FirstStageInit(argv, &cmd);
else
init = new RootFSInit(argv, &cmd);
}
else if (cmd.force_normal_boot)
init = new FirstStageInit(argv, &cmd);
else if (access("/sbin/recovery", F_OK) == 0 || access("/system/bin/recovery", F_OK) == 0)
init = new RecoveryInit(argv, &cmd);
else if (check_two_stage())
init = new FirstStageInit(argv, &cmd);
else
init = new RootFSInit(argv, &cmd);
}
// Run the main routine

View File

@ -31,9 +31,9 @@ struct fstab_entry {
extern std::vector<std::string> mount_list;
bool unxz(int fd, const uint8_t *buf, size_t size);
void load_kernel_info(cmdline *cmd);
bool check_two_stage();
int dump_magisk(const char *path, mode_t mode);
void setup_klog();
/***************

View File

@ -378,13 +378,6 @@ void BaseInit::exec_init() {
exit(1);
}
static void patch_socket_name(const char *path) {
char rstr[16];
gen_rand_str(rstr, sizeof(rstr));
auto bin = mmap_data::rw(path);
bin.patch({ make_pair(MAIN_SOCKET, rstr) });
}
void MagiskInit::setup_tmp(const char *path) {
LOGD("Setup Magisk tmp at %s\n", path);
xmount("tmpfs", path, "tmpfs", 0, "mode=755");
@ -401,8 +394,8 @@ void MagiskInit::setup_tmp(const char *path) {
fd = xopen("magiskinit", O_WRONLY | O_CREAT, 0755);
xwrite(fd, self.buf, self.sz);
close(fd);
dump_magisk("magisk", 0755);
patch_socket_name("magisk");
// The magisk binary will be handled later
// Create applet symlinks
for (int i = 0; applet_names[i]; ++i)

View File

@ -174,6 +174,13 @@ static void magic_mount(const string &sdir, const string &ddir = "") {
}
}
static void patch_socket_name(const char *path) {
char rstr[16];
gen_rand_str(rstr, sizeof(rstr));
auto bin = mmap_data::rw(path);
bin.patch({ make_pair(MAIN_SOCKET, rstr) });
}
#define ROOTMIR MIRRDIR "/system_root"
#define MONOPOLICY "/sepolicy"
#define NEW_INITRC "/system/etc/init/hw/init.rc"
@ -280,9 +287,19 @@ void SARBase::patch_rootdir() {
patch_init_rc(NEW_INITRC, ROOTOVL NEW_INITRC, tmp_dir.data());
}
// Extract magisk
{
auto magisk = mmap_data::ro("magisk.xz");
unlink("magisk.xz");
int fd = xopen("magisk", O_WRONLY | O_CREAT, 0755);
unxz(fd, magisk.buf, magisk.sz);
close(fd);
patch_socket_name("magisk");
}
// Mount rootdir
magic_mount(ROOTOVL);
int dest = xopen(ROOTMNT, O_WRONLY | O_CREAT | O_CLOEXEC, 0);
int dest = xopen(ROOTMNT, O_WRONLY | O_CREAT, 0);
write(dest, magic_mount_list.data(), magic_mount_list.length());
close(dest);
@ -335,15 +352,23 @@ void MagiskProxy::start() {
// Backup stuffs before removing them
self = mmap_data::ro("/sbin/magisk");
config = mmap_data::ro("/.backup/.magisk");
auto magisk = mmap_data::ro("/sbin/magisk.xz");
char custom_rules_dir[64];
custom_rules_dir[0] = '\0';
xreadlink(TMP_RULESDIR, custom_rules_dir, sizeof(custom_rules_dir));
unlink("/sbin/magisk");
unlink("/sbin/magisk.xz");
rm_rf("/.backup");
setup_tmp("/sbin");
// Extract magisk
int fd = xopen("/sbin/magisk", O_WRONLY | O_CREAT, 0755);
unxz(fd, magisk.buf, magisk.sz);
close(fd);
patch_socket_name("/sbin/magisk");
// Create symlinks pointing back to /root
recreate_sbin("/root", false);

View File

@ -53,6 +53,8 @@ if [ -z $SOURCEDMODE ]; then
cd "`getdir "${BASH_SOURCE:-$0}"`"
# Load utility functions
. ./util_functions.sh
# Detect version and architecture
api_level_arch_detect
fi
BOOTIMAGE="$1"
@ -67,9 +69,6 @@ export KEEPFORCEENCRYPT
chmod -R 755 .
# Extract magisk if doesn't exist
[ -e magisk ] || ./magiskinit -x magisk magisk
#########
# Unpack
#########
@ -135,14 +134,24 @@ echo "KEEPFORCEENCRYPT=$KEEPFORCEENCRYPT" >> config
echo "RECOVERYMODE=$RECOVERYMODE" >> config
[ ! -z $SHA1 ] && echo "SHA1=$SHA1" >> config
# Compress to save precious ramdisk space
if $IS64BIT; then
./magiskboot compress=xz magisk64 magisk.xz
else
./magiskboot compress=xz magisk32 magisk.xz
fi
./magiskboot cpio ramdisk.cpio \
"add 750 init magiskinit" \
"mkdir 0750 overlay.d" \
"mkdir 0750 overlay.d/sbin" \
"add 750 overlay.d/sbin/magisk.xz magisk.xz" \
"patch" \
"backup ramdisk.cpio.orig" \
"mkdir 000 .backup" \
"add 000 .backup/.magisk config"
rm -f ramdisk.cpio.orig config
rm -f ramdisk.cpio.orig config magisk.xz
#################
# Binary Patches

View File

@ -28,14 +28,8 @@ mount_sbin() {
if [ ! -f /system/build.prop ]; then
# Running on PC
cd "`dirname "$0"`/.."
adb push native/out/x86/busybox scripts/emulator.sh /data/local/tmp
emu_arch=`adb shell uname -m`
if [ "$emu_arch" = "x86_64" ]; then
adb push native/out/x86/magiskinit64 /data/local/tmp/magiskinit
else
adb push native/out/x86/magiskinit /data/local/tmp
fi
cd "$(dirname "$0")/.."
adb push native/out/x86/busybox scripts/emulator.sh native/out/x86/magiskinit native/out/x86_64/magisk /data/local/tmp
adb shell sh /data/local/tmp/emulator.sh
exit 0
fi
@ -43,7 +37,7 @@ fi
cd /data/local/tmp
chmod 777 busybox
chmod 777 magiskinit
./magiskinit -x magisk magisk
chmod 777 magisk
if [ -z "$FIRST_STAGE" ]; then
export FIRST_STAGE=1
@ -113,7 +107,7 @@ else
fi
# Magisk stuffs
./magiskinit -x magisk $BINDIR/magisk
cp -af ./magisk $BINDIR/magisk
chmod 755 $BINDIR/magisk
ln -s ./magisk $BINDIR/su
ln -s ./magisk $BINDIR/resetprop

View File

@ -445,12 +445,6 @@ install_magisk() {
$BOOTSIGNED && ui_print "- Boot image is signed with AVB 1.0"
fi
if $IS64BIT; then
mv -f magiskinit64 magiskinit 2>/dev/null
else
rm -f magiskinit64
fi
# Source the boot patcher
SOURCEDMODE=true
. ./boot_patch.sh "$BOOTIMAGE"