diff --git a/native/jni/core/magisk.cpp b/native/jni/core/magisk.cpp index 7d7dc9896..73e3127c9 100644 --- a/native/jni/core/magisk.cpp +++ b/native/jni/core/magisk.cpp @@ -21,10 +21,11 @@ Options: -v print running daemon version -V print running daemon version code --list list all available applets - --daemon manually start magisk daemon --remove-modules remove all modules and reboot + --install-module ZIP install a module zip file Advanced Options (Internal APIs): + --daemon manually start magisk daemon --[init trigger] start service for init trigger Supported init triggers: post-fs-data, service, boot-complete @@ -116,6 +117,8 @@ int magisk_main(int argc, char *argv[]) { char *path = read_string(fd); printf("%s\n", path); return 0; + } else if (argc >= 3 && argv[1] == "--install-module"sv) { + install_module(argv[2]); } #if 0 /* Entry point for testing stuffs */ diff --git a/native/jni/core/scripting.cpp b/native/jni/core/scripting.cpp index 27ef16d6c..199e6dd03 100644 --- a/native/jni/core/scripting.cpp +++ b/native/jni/core/scripting.cpp @@ -92,3 +92,40 @@ void install_apk(const char *apk) { sprintf(cmds, install_script, apk); exec_command_sync(exec, BBEXEC_CMD, "-c", cmds); } + +[[noreturn]] static void abort(const char *msg) { + fprintf(stderr, "%s\n\n", msg); + exit(1); +} + +constexpr char install_module_script[] = R"EOF( +. /data/adb/magisk/util_functions.sh +install_module +exit 0 +)EOF"; + +void install_module(const char *file) { + if (getuid() != 0) + abort("Run this command with root"); + if (access(DATABIN, F_OK) || + access(DATABIN "/busybox", X_OK) || + access(DATABIN "/util_functions.sh", F_OK)) + abort("Incomplete Magisk install"); + if (access(file, F_OK)) { + char msg[4096]; + sprintf(msg, "'%s' does not exist", file); + abort(msg); + } + + setenv("OUTFD", "1", true); + setenv("ZIPFILE", file, true); + setenv("ASH_STANDALONE", "1", 1); + + int fd = xopen("/dev/null", O_RDONLY); + xdup2(fd, STDERR_FILENO); + close(fd); + + const char *argv[] = { BBEXEC_CMD, "-c", install_module_script }; + execve(argv[0], (char **) argv, environ); + abort("Failed to execute BusyBox shell"); +} diff --git a/native/jni/include/daemon.hpp b/native/jni/include/daemon.hpp index a3fc7e6d7..37ca76bfb 100644 --- a/native/jni/include/daemon.hpp +++ b/native/jni/include/daemon.hpp @@ -69,3 +69,4 @@ void exec_script(const char *script); void exec_common_scripts(const char *stage); void exec_module_scripts(const char *stage, const std::vector &module_list); void install_apk(const char *apk); +[[noreturn]] void install_module(const char *file);