diff --git a/zygiskd/src/main.c b/zygiskd/src/main.c index 7c9a857..2fa7992 100644 --- a/zygiskd/src/main.c +++ b/zygiskd/src/main.c @@ -14,7 +14,11 @@ int __android_log_print(int prio, const char *tag, const char *fmt, ...); int main(int argc, char *argv[]) { - LOGI("Initializing zygiskd: %s\n", argv[0]); + #ifdef __LP64__ + LOGI("Welcome to ReZygisk %s Zygiskd64!\n", ZKSU_VERSION); + #else + LOGI("Welcome to ReZygisk %s Zygiskd32!\n", ZKSU_VERSION); + #endif if (argc > 1) { if (strcmp(argv[1], "companion") == 0) { @@ -38,37 +42,14 @@ int main(int argc, char *argv[]) { else if (strcmp(argv[1], "root") == 0) { root_impls_setup(); - enum RootImpl impl = get_impl(); - switch (impl) { - case None: { - LOGI("No root implementation found.\n"); + struct root_impl impl; + get_impl(&impl); - return 1; - } + char impl_name[LONGEST_ROOT_IMPL_NAME]; + stringify_root_impl_name(impl, impl_name); - case Multiple: { - LOGI("Multiple root implementations found.\n"); - - return 1; - } - - case KernelSU: { - LOGI("KernelSU root implementation found.\n"); - - return 0; - } - case APatch: { - LOGI("APatch root implementation found.\n"); - - return 0; - } - case Magisk: { - LOGI("Magisk root implementation found.\n"); - - return 0; - } - } + LOGI("Root implementation: %s\n", impl_name); return 0; } diff --git a/zygiskd/src/root_impl/apatch.c b/zygiskd/src/root_impl/apatch.c index 331a967..3b9a000 100644 --- a/zygiskd/src/root_impl/apatch.c +++ b/zygiskd/src/root_impl/apatch.c @@ -6,10 +6,11 @@ #include "../constants.h" #include "../utils.h" +#include "common.h" #include "apatch.h" -enum RootImplState apatch_get_existence(void) { +void apatch_get_existence(struct root_impl_state *state) { struct stat s; if (stat("/data/adb/apd", &s) != 0) { if (errno != ENOENT) { @@ -17,7 +18,9 @@ enum RootImplState apatch_get_existence(void) { } errno = 0; - return Inexistent; + state->state = Inexistent; + + return; } char *PATH = getenv("PATH"); @@ -25,13 +28,17 @@ enum RootImplState apatch_get_existence(void) { LOGE("Failed to get PATH environment variable: %s\n", strerror(errno)); errno = 0; - return Inexistent; + state->state = Inexistent; + + return; } if (strstr(PATH, "/data/adb/ap/bin") == NULL) { LOGE("APatch's APD binary is not in PATH\n"); - return Inexistent; + state->state = Inexistent; + + return; } char apatch_version[32]; @@ -41,16 +48,17 @@ enum RootImplState apatch_get_existence(void) { LOGE("Failed to execute apd binary: %s\n", strerror(errno)); errno = 0; - return Inexistent; + state->state = Inexistent; + + return; } int version = atoi(apatch_version + strlen("apd ")); - if (version == 0) return Abnormal; - if (version >= MIN_APATCH_VERSION && version <= 999999) return Supported; - if (version >= 1 && version <= MIN_APATCH_VERSION - 1) return TooOld; - - return Inexistent; + if (version == 0) state->state = Abnormal; + else if (version >= MIN_APATCH_VERSION && version <= 999999) state->state = Supported; + else if (version >= 1 && version <= MIN_APATCH_VERSION - 1) state->state = TooOld; + else state->state = Abnormal; } struct package_config { diff --git a/zygiskd/src/root_impl/apatch.h b/zygiskd/src/root_impl/apatch.h index e45fc17..74e20bf 100644 --- a/zygiskd/src/root_impl/apatch.h +++ b/zygiskd/src/root_impl/apatch.h @@ -3,7 +3,7 @@ #include "../constants.h" -enum RootImplState apatch_get_existence(void); +void apatch_get_existence(struct root_impl_state *state); bool apatch_uid_granted_root(uid_t uid); diff --git a/zygiskd/src/root_impl/common.c b/zygiskd/src/root_impl/common.c index 92eb18e..e679f55 100644 --- a/zygiskd/src/root_impl/common.c +++ b/zygiskd/src/root_impl/common.c @@ -9,15 +9,34 @@ #include "common.h" -static enum RootImpl ROOT_IMPL = None; +static struct root_impl impl; void root_impls_setup(void) { - if (ksu_get_existence() == Supported) ROOT_IMPL = KernelSU; - else if (apatch_get_existence() == Supported) ROOT_IMPL = APatch; - else if (magisk_get_existence() == Supported) ROOT_IMPL = Magisk; - else ROOT_IMPL = None; + struct root_impl_state state_ksu; + ksu_get_existence(&state_ksu); - switch (ROOT_IMPL) { + struct root_impl_state state_apatch; + apatch_get_existence(&state_apatch); + + struct root_impl_state state_magisk; + magisk_get_existence(&state_magisk); + + /* INFO: Check if it's only one supported, if not, it's multile and that's bad. + Remember that true here is equal to the integer 1. */ + if ((state_ksu.state == Supported ? 1 : 0) + (state_apatch.state == Supported ? 1 : 0) + (state_magisk.state == Supported ? 1 : 0) >= 2) { + impl.impl = Multiple; + } else if (state_ksu.state == Supported) { + impl.impl = KernelSU; + } else if (state_apatch.state == Supported) { + impl.impl = APatch; + } else if (state_magisk.state == Supported) { + impl.impl = Magisk; + impl.variant = state_magisk.variant; + } else { + impl.impl = None; + } + + switch (impl.impl) { case None: { LOGI("No root implementation found.\n"); @@ -39,19 +58,24 @@ void root_impls_setup(void) { break; } case Magisk: { - LOGI("Magisk root implementation found.\n"); + if (state_magisk.variant == 0) { + LOGI("Magisk Official root implementation found.\n"); + } else { + LOGI("Magisk Kitsune root implementation found.\n"); + } break; } } } -enum RootImpl get_impl(void) { - return ROOT_IMPL; +void get_impl(struct root_impl *uimpl) { + uimpl->impl = impl.impl; + uimpl->variant = impl.variant; } bool uid_granted_root(uid_t uid) { - switch (get_impl()) { + switch (impl.impl) { case KernelSU: { return ksu_uid_granted_root(uid); } @@ -68,7 +92,7 @@ bool uid_granted_root(uid_t uid) { } bool uid_should_umount(uid_t uid) { - switch (get_impl()) { + switch (impl.impl) { case KernelSU: { return ksu_uid_should_umount(uid); } @@ -85,7 +109,7 @@ bool uid_should_umount(uid_t uid) { } bool uid_is_manager(uid_t uid) { - switch (get_impl()) { + switch (impl.impl) { case KernelSU: { return ksu_uid_is_manager(uid); } diff --git a/zygiskd/src/root_impl/common.h b/zygiskd/src/root_impl/common.h index 13bef4e..69893fc 100644 --- a/zygiskd/src/root_impl/common.h +++ b/zygiskd/src/root_impl/common.h @@ -1,9 +1,11 @@ #ifndef COMMON_H #define COMMON_H +#include + #include "../constants.h" -enum RootImpl { +enum root_impls { None, Multiple, KernelSU, @@ -11,9 +13,21 @@ enum RootImpl { Magisk }; +struct root_impl_state { + enum RootImplState state; + uint8_t variant; +}; + +struct root_impl { + enum root_impls impl; + uint8_t variant; +}; + +#define LONGEST_ROOT_IMPL_NAME sizeof("Magisk Kitsune") + void root_impls_setup(void); -enum RootImpl get_impl(void); +void get_impl(struct root_impl *uimpl); bool uid_granted_root(uid_t uid); diff --git a/zygiskd/src/root_impl/kernelsu.c b/zygiskd/src/root_impl/kernelsu.c index 578cedc..775b1c6 100644 --- a/zygiskd/src/root_impl/kernelsu.c +++ b/zygiskd/src/root_impl/kernelsu.c @@ -6,6 +6,7 @@ #include "../constants.h" #include "../utils.h" +#include "common.h" #include "kernelsu.h" @@ -19,15 +20,31 @@ #define CMD_UID_GRANTED_ROOT 12 #define CMD_UID_SHOULD_UMOUNT 13 -enum RootImplState ksu_get_existence(void) { +void ksu_get_existence(struct root_impl_state *state) { int version = 0; prctl((signed int)KERNEL_SU_OPTION, CMD_GET_VERSION, &version, 0, 0); - if (version == 0) return Inexistent; - if (version >= MIN_KSU_VERSION && version <= MAX_KSU_VERSION) return Supported; - if (version >= 1 && version <= MIN_KSU_VERSION - 1) return TooOld; + if (version == 0) state->state = Abnormal; + else if (version >= MIN_KSU_VERSION && version <= MAX_KSU_VERSION) { + /* INFO: Some custom kernels for custom ROMs have pre-installed KernelSU. + Some users don't want to use KernelSU, but, for example, Magisk. + This if allows this to happen, as it checks if "ksud" exists, + which in case it doesn't, it won't be considered as supported. */ + struct stat s; + if (stat("/data/adb/ksud", &s) == -1) { + if (errno != ENOENT) { + LOGE("Failed to stat KSU daemon: %s\n", strerror(errno)); + } + errno = 0; + state->state = Abnormal; - return Abnormal; + return; + } + + state->state = Supported; + } + else if (version >= 1 && version <= MIN_KSU_VERSION - 1) state->state = TooOld; + else state->state = Abnormal; } bool ksu_uid_granted_root(uid_t uid) { diff --git a/zygiskd/src/root_impl/kernelsu.h b/zygiskd/src/root_impl/kernelsu.h index 83d01bb..96a4c72 100644 --- a/zygiskd/src/root_impl/kernelsu.h +++ b/zygiskd/src/root_impl/kernelsu.h @@ -3,7 +3,7 @@ #include "../constants.h" -enum RootImplState ksu_get_existence(void); +void ksu_get_existence(struct root_impl_state *state); bool ksu_uid_granted_root(uid_t uid); diff --git a/zygiskd/src/root_impl/magisk.c b/zygiskd/src/root_impl/magisk.c index 89467fa..768f849 100644 --- a/zygiskd/src/root_impl/magisk.c +++ b/zygiskd/src/root_impl/magisk.c @@ -10,6 +10,7 @@ #include "../constants.h" #include "../utils.h" +#include "common.h" #include "magisk.h" @@ -30,7 +31,7 @@ enum magisk_variants variant = Official; /* INFO: Longest path */ static char path_to_magisk[sizeof(DEBUG_RAMDISK_MAGISK)]; -enum RootImplState magisk_get_existence(void) { +void magisk_get_existence(struct root_impl_state *state) { struct stat s; if (stat(SBIN_MAGISK, &s) != 0) { if (errno != ENOENT) { @@ -50,7 +51,9 @@ enum RootImplState magisk_get_existence(void) { } errno = 0; - return Inexistent; + state->state = Inexistent; + + return; } /* INFO: /debug_ramdisk/magisk64 (or 32) doesn't exist but /debug_ramdisk/magisk does */ @@ -71,11 +74,20 @@ enum RootImplState magisk_get_existence(void) { LOGE("Failed to execute magisk binary: %s\n", strerror(errno)); errno = 0; - return Abnormal; + state->state = Abnormal; + + return; } + state->variant = (uint8_t)Official; + for (unsigned long i = 0; i < sizeof(supported_variants) / sizeof(supported_variants[0]); i++) { - if (strstr(magisk_info, supported_variants[i])) variant = (enum magisk_variants)(i + 1); + if (strstr(magisk_info, supported_variants[i])) { + variant = (enum magisk_variants)(i + 1); + state->variant = (uint8_t)variant; + + break; + } } argv[1] = "-V"; @@ -85,11 +97,13 @@ enum RootImplState magisk_get_existence(void) { LOGE("Failed to execute magisk binary: %s\n", strerror(errno)); errno = 0; - return Abnormal; + state->state = Abnormal; + + return; } - if (atoi(magisk_version) >= MIN_MAGISK_VERSION) return Supported; - else return TooOld; + if (atoi(magisk_version) >= MIN_MAGISK_VERSION) state->state = Supported; + else state->state = TooOld; } bool magisk_uid_granted_root(uid_t uid) { diff --git a/zygiskd/src/root_impl/magisk.h b/zygiskd/src/root_impl/magisk.h index 0260d7a..0d47646 100644 --- a/zygiskd/src/root_impl/magisk.h +++ b/zygiskd/src/root_impl/magisk.h @@ -8,7 +8,7 @@ enum magisk_variants { Kitsune }; -enum RootImplState magisk_get_existence(void); +void magisk_get_existence(struct root_impl_state *state); bool magisk_uid_granted_root(uid_t uid); diff --git a/zygiskd/src/utils.c b/zygiskd/src/utils.c index b695d29..647e8ea 100644 --- a/zygiskd/src/utils.c +++ b/zygiskd/src/utils.c @@ -17,6 +17,7 @@ #include #include "utils.h" +#include "root_impl/common.h" bool switch_mount_namespace(pid_t pid) { char path[PATH_MAX]; @@ -411,3 +412,37 @@ int non_blocking_execv(const char *restrict file, char *const argv[]) { return -1; } + +void stringify_root_impl_name(struct root_impl impl, char *restrict output) { + switch (impl.impl) { + case None: { + strcpy(output, "None"); + + break; + } + case Multiple: { + strcpy(output, "Multiple"); + + break; + } + case KernelSU: { + strcpy(output, "KernelSU"); + + break; + } + case APatch: { + strcpy(output, "APatch"); + + break; + } + case Magisk: { + if (impl.variant == 0) { + strcpy(output, "Magisk Official"); + } else { + strcpy(output, "Magisk Kitsune"); + } + + break; + } + } +} diff --git a/zygiskd/src/utils.h b/zygiskd/src/utils.h index e5dac56..b799b5e 100644 --- a/zygiskd/src/utils.h +++ b/zygiskd/src/utils.h @@ -4,6 +4,7 @@ #include #include "constants.h" +#include "root_impl/common.h" #define CONCAT_(x,y) x##y #define CONCAT(x,y) CONCAT_(x,y) @@ -101,4 +102,6 @@ bool check_unix_socket(int fd, bool block); int non_blocking_execv(const char *restrict file, char *const argv[]); +void stringify_root_impl_name(struct root_impl impl, char *restrict output); + #endif /* UTILS_H */ diff --git a/zygiskd/src/zygiskd.c b/zygiskd/src/zygiskd.c index 364e23f..c2d1e3c 100644 --- a/zygiskd/src/zygiskd.c +++ b/zygiskd/src/zygiskd.c @@ -316,175 +316,92 @@ struct __attribute__((__packed__)) MsgHead { /* WARNING: Dynamic memory based */ void zygiskd_start(char *restrict argv[]) { - LOGI("Welcome to ReZygisk %s Zygiskd!\n", ZKSU_VERSION); + /* INFO: When implementation is None or Multiple, it won't set the values + for the context, causing it to have garbage values. In response + to that, "= { 0 }" is used to ensure that the values are clean. */ + struct Context context = { 0 }; - enum RootImpl impl = get_impl(); - if (impl == None) { - struct MsgHead *msg = malloc(sizeof(struct MsgHead) + sizeof("No root implementation found.")); - if (msg == NULL) { - LOGE("Failed allocating memory for message.\n"); - - return; - } - - msg->cmd = DAEMON_SET_ERROR_INFO; - msg->length = sizeof("No root implementation found."); - memcpy(msg->data, "No root implementation found.", msg->length); - - unix_datagram_sendto(CONTROLLER_SOCKET, &msg, sizeof(struct MsgHead) + msg->length); - - free(msg); - } else if (impl == Multiple) { - struct MsgHead *msg = malloc(sizeof(struct MsgHead) + sizeof("Multiple root implementations found. Not supported yet.")); - if (msg == NULL) { - LOGE("Failed allocating memory for message.\n"); - - return; - } + struct root_impl impl; + get_impl(&impl); + if (impl.impl == None || impl.impl == Multiple) { + struct MsgHead *msg = NULL; - msg->cmd = DAEMON_SET_ERROR_INFO; - msg->length = sizeof("Multiple root implementations found. Not supported yet."); - memcpy(msg->data, "Multiple root implementations found. Not supported yet.", msg->length); + if (impl.impl == None) { + msg = malloc(sizeof(struct MsgHead) + strlen("Unsupported environment: Unknown root implementation") + 1); + } else { + msg = malloc(sizeof(struct MsgHead) + strlen("Unsupported environment: Multiple root implementations found") + 1); + } + if (msg == NULL) { + LOGE("Failed allocating memory for message.\n"); - unix_datagram_sendto(CONTROLLER_SOCKET, &msg, sizeof(struct MsgHead) + msg->length); + return; + } + + msg->cmd = DAEMON_SET_ERROR_INFO; + if (impl.impl == None) { + msg->length = sprintf(msg->data, "Unsupported environment: Unknown root implementation"); + } else { + msg->length = sprintf(msg->data, "Unsupported environment: Multiple root implementations found"); + } + + unix_datagram_sendto(CONTROLLER_SOCKET, (void *)msg, sizeof(struct MsgHead) + msg->length); free(msg); - } + } else { + enum Architecture arch = get_arch(); + load_modules(arch, &context); - enum Architecture arch = get_arch(); + char *module_list = NULL; + size_t module_list_len = 0; + if (context.len == 0) { + module_list = strdup("None"); + module_list_len = strlen("None"); + } else { + for (int i = 0; i < context.len; i++) { + if (i != context.len - 1) { + module_list = realloc(module_list, module_list_len + strlen(context.modules[i].name) + strlen(", ") + 1); + if (module_list == NULL) { + LOGE("Failed reallocating memory for module list.\n"); - struct Context context; - load_modules(arch, &context); + return; + } - struct MsgHead *msg = NULL; + strcpy(module_list + module_list_len, context.modules[i].name); - switch (impl) { - case None: { break; } - case Multiple: { break; } - case KernelSU: - case APatch: - case Magisk: { - size_t root_impl_len = 0; - switch (impl) { - case None: { break; } - case Multiple: { break; } - case KernelSU: { - root_impl_len = strlen("KernelSU"); + module_list_len += strlen(context.modules[i].name); - break; - } - case APatch: { - root_impl_len = strlen("APatch"); + strcpy(module_list + module_list_len, ", "); - break; - } - case Magisk: { - root_impl_len = strlen("Magisk"); + module_list_len += strlen(", "); + } else { + module_list = realloc(module_list, module_list_len + strlen(context.modules[i].name) + 1); + if (module_list == NULL) { + LOGE("Failed reallocating memory for module list.\n"); - break; + return; + } + + strcpy(module_list + module_list_len, context.modules[i].name); + + module_list_len += strlen(context.modules[i].name); } } - - if (context.len == 0) { - msg = malloc(sizeof(struct MsgHead) + strlen("Root: , Modules: None") + root_impl_len + 1); - if (msg == NULL) { - LOGE("Failed allocating memory for message.\n"); - - return; - } - - msg->cmd = DAEMON_SET_INFO; - msg->length = strlen("Root: , Modules: None") + root_impl_len + 1; - - switch (impl) { - case None: { break; } - case Multiple: { break; } - case KernelSU: { - memcpy(msg->data, "Root: KernelSU, Modules: None", strlen("Root: KernelSU, Modules: None")); - - break; - } - case APatch: { - memcpy(msg->data, "Root: APatch, Modules: None", strlen("Root: APatch, Modules: None")); - - break; - } - case Magisk: { - memcpy(msg->data, "Root: Magisk, Modules: None", strlen("Root: Magisk, Modules: None")); - - break; - } - } - } else { - char *module_list = malloc(1); - if (module_list == NULL) { - LOGE("Failed allocating memory for module list.\n"); - - return; - } - - size_t module_list_len = 0; - - for (int i = 0; i < context.len; i++) { - if (i != context.len - 1) { - module_list = realloc(module_list, module_list_len + strlen(context.modules[i].name) + strlen(", ") + 1); - memcpy(module_list + module_list_len, context.modules[i].name, strlen(context.modules[i].name)); - - module_list_len += strlen(context.modules[i].name); - - memcpy(module_list + module_list_len, ", ", strlen(", ")); - - module_list_len += strlen(", "); - } else { - module_list = realloc(module_list, module_list_len + strlen(context.modules[i].name) + 1); - memcpy(module_list + module_list_len, context.modules[i].name, strlen(context.modules[i].name)); - - module_list_len += strlen(context.modules[i].name); - } - } - - msg = malloc(sizeof(struct MsgHead) + strlen("Root: , Modules: ") + root_impl_len + module_list_len + 1); - if (msg == NULL) { - LOGE("Failed allocating memory for message.\n"); - - return; - } - - msg->cmd = DAEMON_SET_INFO; - msg->length = strlen("Root: , Modules: ") + root_impl_len + module_list_len + 1; - - switch (impl) { - case None: { break; } - case Multiple: { break; } - case KernelSU: { - memcpy(msg->data, "Root: KernelSU, Modules: ", strlen("Root: KernelSU, Modules: ")); - - break; - } - case APatch: { - memcpy(msg->data, "Root: APatch, Modules: ", strlen("Root: APatch, Modules: ")); - - break; - } - case Magisk: { - memcpy(msg->data, "Root: Magisk, Modules: ", strlen("Root: Magisk, Modules: ")); - - break; - } - } - memcpy(msg->data + strlen("Root: , Modules: ") + root_impl_len, module_list, module_list_len); - - free(module_list); - } - - break; } + + char impl_name[LONGEST_ROOT_IMPL_NAME]; + stringify_root_impl_name(impl, impl_name); + + struct MsgHead *msg = NULL; + msg = malloc(sizeof(struct MsgHead) + strlen("Root: , Modules: ") + strlen(impl_name) + module_list_len + 1); + msg->length = sprintf(msg->data, "Root: %s, Modules: %s", impl_name, module_list); + msg->cmd = DAEMON_SET_INFO; + + unix_datagram_sendto(CONTROLLER_SOCKET, (void *)msg, sizeof(struct MsgHead) + msg->length); + + free(msg); + free(module_list); } - unix_datagram_sendto(CONTROLLER_SOCKET, (void *)msg, sizeof(struct MsgHead) + msg->length); - - free(msg); - int socket_fd = create_daemon_socket(); if (socket_fd == -1) { LOGE("Failed creating daemon socket\n"); @@ -535,6 +452,16 @@ void zygiskd_start(char *restrict argv[]) { enum DaemonSocketAction msgr = SYSTEM_SERVER_STARTED; unix_datagram_sendto(CONTROLLER_SOCKET, &msgr, sizeof(enum DaemonSocketAction)); + if (impl.impl == None || impl.impl == Multiple) { + LOGI("Unsupported environment detected. Exiting.\n"); + + close(client_fd); + close(socket_fd); + free_modules(&context); + + exit(1); + } + break; } case RequestLogcatFd: { @@ -586,7 +513,7 @@ void zygiskd_start(char *restrict argv[]) { } } - switch (get_impl()) { + switch (impl.impl) { case None: { break; } case Multiple: { break; } case KernelSU: { @@ -614,7 +541,7 @@ void zygiskd_start(char *restrict argv[]) { case GetInfo: { uint32_t flags = 0; - switch (get_impl()) { + switch (impl.impl) { case None: { break; } case Multiple: { break; } case KernelSU: {