diff --git a/native/src/core/applets.cpp b/native/src/core/applets.cpp index 8d0d81446..9ce77c35e 100644 --- a/native/src/core/applets.cpp +++ b/native/src/core/applets.cpp @@ -8,45 +8,68 @@ using namespace std; -using main_fun = int (*)(int, char *[]); +struct Applet { + string_view name; + int (*fn)(int, char *[]); +}; -constexpr const char *applets[] = { "su", "resetprop", "zygisk", nullptr }; -static main_fun applet_mains[] = { su_client_main, resetprop_main, zygisk_main, nullptr }; +constexpr Applet applets[] = { + { "su", su_client_main }, + { "resetprop", resetprop_main }, +}; -static int call_applet(int argc, char *argv[]) { - // Applets - string_view base = basename(argv[0]); - for (int i = 0; applets[i]; ++i) { - if (base == applets[i]) { - return (*applet_mains[i])(argc, argv); - } - } - fprintf(stderr, "%s: applet not found\n", base.data()); - return 1; -} +constexpr Applet private_applets[] = { + { "zygisk", zygisk_main }, +}; int main(int argc, char *argv[]) { + if (argc < 1) + return 1; + enable_selinux(); cmdline_logging(); init_argv0(argc, argv); - string_view base = basename(argv[0]); + string_view argv0 = basename(argv[0]); // app_process is actually not an applet - if (str_starts(base, "app_process")) { + if (argv0.starts_with("app_process")) { return app_process_main(argc, argv); } umask(0); - if (base == "magisk" || base == "magisk32" || base == "magisk64") { + + if (argv[0][0] == '\0') { + // When argv[0] is an empty string, we're calling private applets + if (argc < 2) + return 1; + --argc; + ++argv; + for (const auto &app : private_applets) { + if (argv[0] == app.name) { + return app.fn(argc, argv); + } + } + fprintf(stderr, "%s: applet not found\n", argv[0]); + return 1; + } + + if (argv0 == "magisk" || argv0 == "magisk32" || argv0 == "magisk64") { if (argc > 1 && argv[1][0] != '-') { - // Calling applet via magisk [applet] args + // Calling applet with "magisk [applet] args..." --argc; ++argv; + argv0 = argv[0]; } else { return magisk_main(argc, argv); } } - return call_applet(argc, argv); + for (const auto &app : applets) { + if (argv0 == app.name) { + return app.fn(argc, argv); + } + } + fprintf(stderr, "%s: applet not found\n", argv0.data()); + return 1; } diff --git a/native/src/zygisk/entry.cpp b/native/src/zygisk/entry.cpp index 9d2667f69..c3604c3c7 100644 --- a/native/src/zygisk/entry.cpp +++ b/native/src/zygisk/entry.cpp @@ -177,7 +177,7 @@ static void connect_companion(int client, bool is_64_bit) { fcntl(fds[1], F_SETFD, 0); char buf[16]; snprintf(buf, sizeof(buf), "%d", fds[1]); - execl(exe.data(), "zygisk", "companion", buf, (char *) nullptr); + execl(exe.data(), "", "zygisk", "companion", buf, (char *) nullptr); exit(-1); } close(fds[1]); diff --git a/native/src/zygisk/main.cpp b/native/src/zygisk/main.cpp index 58d058039..ab645d1fa 100644 --- a/native/src/zygisk/main.cpp +++ b/native/src/zygisk/main.cpp @@ -46,17 +46,16 @@ int app_process_main(int argc, char *argv[]) { fcntl(fds[1], F_SETFD, 0); snprintf(buf, sizeof(buf), "%d", fds[1]); #if defined(__LP64__) - execlp("magisk", "zygisk", "passthrough", buf, "1", (char *) nullptr); + execlp("magisk", "", "zygisk", "passthrough", buf, "1", (char *) nullptr); #else - execlp("magisk", "zygisk", "passthrough", buf, "0", (char *) nullptr); + execlp("magisk", "", "zygisk", "passthrough", buf, "0", (char *) nullptr); #endif exit(-1); } close(fds[1]); if (read_int(fds[0]) != 0) { - fprintf(stderr, "Failed to connect magisk daemon, " - "try umount %s or reboot.\n", argv[0]); + fprintf(stderr, "Failed to connect magiskd, try umount %s or reboot.\n", argv[0]); return 1; } int app_proc_fd = recv_fd(fds[0]); @@ -131,8 +130,8 @@ static void zygiskd(int socket) { struct stat s{}; if (fstat(fd, &s) == 0 && S_ISREG(s.st_mode)) { android_dlextinfo info { - .flags = ANDROID_DLEXT_USE_LIBRARY_FD, - .library_fd = fd, + .flags = ANDROID_DLEXT_USE_LIBRARY_FD, + .library_fd = fd, }; if (void *h = android_dlopen_ext("/jit-cache", RTLD_LAZY, &info)) { *(void **) &entry = dlsym(h, "zygisk_companion_entry");