diff --git a/loader/build.gradle.kts b/loader/build.gradle.kts index aa352b4..2d82e62 100644 --- a/loader/build.gradle.kts +++ b/loader/build.gradle.kts @@ -28,8 +28,10 @@ val ccachePath by lazy { val defaultCFlags = arrayOf( "-Wall", "-Wextra", "-fno-rtti", "-fno-exceptions", + "-fvisibility=hidden", "-fvisibility-inlines-hidden", "-fno-stack-protector", "-fomit-frame-pointer", - "-Wno-builtin-macro-redefined", "-D__FILE__=__FILE_NAME__" + "-Wno-builtin-macro-redefined", "-D__FILE__=__FILE_NAME__", + "-O0", "-g" ) val releaseFlags = arrayOf( diff --git a/module/build.gradle.kts b/module/build.gradle.kts index b9d327a..378edd8 100644 --- a/module/build.gradle.kts +++ b/module/build.gradle.kts @@ -80,7 +80,7 @@ androidComponents.onVariants { variant -> filter("eol" to FixCrLfFilter.CrLf.newInstance("lf")) } into("bin") { - from(project(":zygiskd").layout.buildDirectory.file("rustJniLibs/android")) + from(project(":zygiskd").layout.buildDirectory.getAsFile().get()) include("**/zygiskd") } into("lib") { diff --git a/zygiskd-new/.gitignore b/zygiskd-new/.gitignore deleted file mode 100644 index 8f961c3..0000000 --- a/zygiskd-new/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -zygiskd64 -zygiskd32 \ No newline at end of file diff --git a/zygiskd-new/LICENSE b/zygiskd-new/LICENSE deleted file mode 100644 index bf86410..0000000 --- a/zygiskd-new/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -BSD 2-Clause License - -Copyright (c) 2024, The PerformanC Organization - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/zygiskd-new/Makefile b/zygiskd-new/Makefile deleted file mode 100644 index da67f95..0000000 --- a/zygiskd-new/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -CC := ~/Android/Sdk/ndk/27.0.11902837/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android34-clang - -# FILES = root_impl/common.c \ -# root_impl/kernelsu.c \ -# companion.c \ -# dl.c \ -# main.c \ -# utils.c \ -# zygiskd.c - -FILES = root_impl/*.c \ - *.c - -CFLAGS = -D_GNU_SOURCE -std=c99 -Wpedantic -Wall -Wextra -Werror -Wformat -Wuninitialized -Wshadow -Wno-zero-length-array -Wno-fixed-enum-extension -Iroot_impl -llog - -all: CFLAGS += -DDEBUG=0 -O3 -flto=thin -Wl,--strip-all -all: - $(CC) $(CFLAGS) $(FILES) -o zygiskd64 - -debug: CFLAGS += -DDEBUG=1 -g -O0 -debug: - $(CC) $(CFLAGS) $(FILES) -o zygiskd64 - -32bit: CFLAGS += -m32 -DDEBUG=0 -O3 -flto=thin -Wl,--strip-all -32bit: - $(CC) $(CFLAGS) $(FILES) -o zygiskd32 - -32bit-debug: CFLAGS += -m32 -DDEBUG=1 -g -O0 -32bit-debug: - $(CC) $(CFLAGS) $(FILES) -o zygiskd32 - -clean: - rm -f zygiskd \ No newline at end of file diff --git a/zygiskd-new/companion.c b/zygiskd-new/companion.c deleted file mode 100644 index b3b8442..0000000 --- a/zygiskd-new/companion.c +++ /dev/null @@ -1,125 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include "companion.h" -#include "dl.h" -#include "utils.h" - -typedef void (*ZygiskCompanionEntryFn)(int); - -ZygiskCompanionEntryFn load_module(int fd) { - char path[PATH_MAX]; - snprintf(path, sizeof(path), "/proc/self/fd/%d", fd); - - void *handle = android_dlopen(path, RTLD_NOW); - void *entry = dlsym(handle, "zygisk_companion_entry"); - if (entry == NULL) return NULL; - - return (ZygiskCompanionEntryFn)entry; -} - -void *ExecuteNew(void *arg) { - int fd = *((int *)arg); - - struct stat st0; - if (fstat(fd, &st0) == -1) { - LOGE("Failed to stat client fd\n"); - - free(arg); - - exit(0); - } - entry(fd); - - // Only close client if it is the same file so we don't - // accidentally close a re-used file descriptor. - // This check is required because the module companion - // handler could've closed the file descriptor already. - struct stat st1; - if (fstat(fd, &st1) == -1) { - LOGE("Failed to stat client fd\n"); - - free(arg); - - exit(0); - } - - if (st0.st_dev != st1.st_dev || st0.st_ino != st1.st_ino) { - close(fd); - } - - free(arg); - - return NULL; -} - - -void entry(int fd) { - LOGI("companion entry fd: |%d|\n", fd); - - char name[256 + 1]; - - /* INFO: Getting stuck here */ - ssize_t ret = read_string(fd, name, sizeof(name) - 1); - if (ret == -1) return; - - name[ret] = '\0'; - - LOGI("Companion process requested for `%s`\n", name); - - int library_fd; - recv_fd(fd, &library_fd); - - LOGI("Library fd: %d\n", library_fd); - - ZygiskCompanionEntryFn entry = load_module(library_fd); - - LOGI("Library loaded\n"); - - close(library_fd); - - LOGI("Library closed\n"); - - if (entry == NULL) { - LOGI("No companion entry for: %s\n", name); - - write(fd, (void *)0, 1); - - return; - } - - LOGI("Companion process created for: %s\n", name); - - uint8_t response = 1; - write(fd, &response, sizeof(response)); - - while (1) { - int client_fd; - recv_fd(fd, &client_fd); - - LOGI("New companion request from module \"%s\" with fd \"%d\"\n", name, client_fd); - - write(fd, &response, sizeof(response)); - - int *client_fd_ptr = malloc(sizeof(int)); - *client_fd_ptr = client_fd; - - LOGI("Creating new thread for companion request\n"); - - pthread_t thread; - pthread_create(&thread, NULL, ExecuteNew, (void *)client_fd_ptr); - pthread_detach(thread); - } -} diff --git a/zygiskd-new/companion.h b/zygiskd-new/companion.h deleted file mode 100644 index 1b931e8..0000000 --- a/zygiskd-new/companion.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef COMPANION_H -#define COMPANION_H - -void entry(int fd); - -#endif /* COMPANION_H */ diff --git a/zygiskd-new/constants.h b/zygiskd-new/constants.h deleted file mode 100644 index 94a7f5a..0000000 --- a/zygiskd-new/constants.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef CONSTANTS_H -#define CONSTANTS_H - -#include - -#define bool _Bool -#define true 1 -#define false 0 - -// #define MIN_APATCH_VERSION (atoi(getenv("MIN_APATCH_VERSION"))) -// #define MIN_KSU_VERSION (atoi(getenv("MIN_KSU_VERSION"))) -// #define MAX_KSU_VERSION (atoi(getenv("MAX_KSU_VERSION"))) -// #define MIN_MAGISK_VERSION (atoi(getenv("MIN_MAGISK_VERSION"))) -// #define ZKSU_VERSION (getenv("ZKSU_VERSION")) - -#define MIN_APATCH_VERSION 0 -// val minKsudVersion by extra(11425) -// val maxKsuVersion by extra(20000) -#define MIN_KSU_VERSION 11425 -#define MAX_KSU_VERSION 20000 -#define MIN_MAGISK_VERSION 0 -#define ZKSU_VERSION "1.0.0" - -#if DEBUG == false - #define MAX_LOG_LEVEL ANDROID_LOG_VERBOSE -#else - #define MAX_LOG_LEVEL ANDROID_LOG_INFO -#endif - -#if (defined(__LP64__) || defined(_LP64)) - #define lp_select(a, b) b -#else - #define lp_select(a, b) a -#endif - -#define ZYGOTE_INJECTED lp_select(5, 4) -#define DAEMON_SET_INFO lp_select(7, 6) -#define DAEMON_SET_ERROR_INFO lp_select(9, 8) -#define SYSTEM_SERVER_STARTED 10 - -enum DaemonSocketAction { - PingHeartbeat, - RequestLogcatFd, - GetProcessFlags, - GetInfo, - ReadModules, - RequestCompanionSocket, - GetModuleDir, - ZygoteRestart, - SystemServerStarted -}; - -enum ProcessFlags: uint32_t { - PROCESS_GRANTED_ROOT = (1u << 0), - PROCESS_ON_DENYLIST = (1u << 1), - PROCESS_IS_MANAGER = (1u << 28), - PROCESS_ROOT_IS_APATCH = (1u << 27), - PROCESS_ROOT_IS_KSU = (1u << 29), - PROCESS_ROOT_IS_MAGISK = (1u << 30), - PROCESS_IS_SYS_UI = (1u << 31), - PROCESS_IS_SYSUI = (1u << 31) -}; - -enum RootImplState { - Supported, - TooOld, - Abnormal -}; - -#endif /* CONSTANTS_H */ diff --git a/zygiskd-new/dl.c b/zygiskd-new/dl.c deleted file mode 100644 index eddcf1f..0000000 --- a/zygiskd-new/dl.c +++ /dev/null @@ -1,58 +0,0 @@ -#include - -#include -#include -#include - -#define ANDROID_NAMESPACE_TYPE_SHARED 0x2 -#define ANDROID_DLEXT_USE_NAMESPACE 0x200 - -struct AndroidNamespace { - u_int8_t _unused[0]; -}; - -struct AndroidDlextinfo { - u_int64_t flags; - void *reserved_addr; - size_t reserved_size; - int relro_fd; - int library_fd; - off64_t library_fd_offset; - struct AndroidNamespace *library_namespace; -}; - -void *android_dlopen_ext(const char *filename, int flags, const struct AndroidDlextinfo *extinfo); - -void *android_dlopen(char *path, u_int32_t flags) { - char *dir = dirname(path); - struct AndroidDlextinfo info = { - .flags = 0, - .reserved_addr = NULL, - .reserved_size = 0, - .relro_fd = 0, - .library_fd = 0, - .library_fd_offset = 0, - .library_namespace = NULL, - }; - - void *android_create_namespace_fn = dlsym(RTLD_DEFAULT, "__loader_android_create_namespace"); - - if (android_create_namespace_fn != NULL) { - void *ns = ((void *(*)(const char *, const char *, const char *, u_int32_t, void *, void *, void *))android_create_namespace_fn)( - path, - dir, - NULL, - ANDROID_NAMESPACE_TYPE_SHARED, - NULL, - NULL, - (void *)&android_dlopen - ); - - if (ns != NULL) { - info.flags = ANDROID_DLEXT_USE_NAMESPACE; - info.library_namespace = ns; - } - } - - return android_dlopen_ext(path, flags, &info); -} diff --git a/zygiskd-new/dl.h b/zygiskd-new/dl.h deleted file mode 100644 index 32cd248..0000000 --- a/zygiskd-new/dl.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef DL_H -#define DL_H - -void *android_dlopen(char *path, u_int32_t flags); - -#endif /* DL_H */ diff --git a/zygiskd-new/main.c b/zygiskd-new/main.c deleted file mode 100644 index a86aa31..0000000 --- a/zygiskd-new/main.c +++ /dev/null @@ -1,86 +0,0 @@ -#include -#include -#include -#include - -#include - -#include "root_impl/common.h" -#include "companion.h" -#include "zygiskd.h" - -#include "utils.h" - -int __android_log_print(int prio, const char *tag, const char *fmt, ...); - -int main(int argc, char *argv[]) { - errno = 0; - /* Initialize android logger */ - LOGI("Initializing zygiskd\n"); - - LOGI("Argc: %d\n", argc); - for (int i = 0; i < argc; i++) { - LOGI("argv[%d] = %s\n", i, argv[i]); - } - - if (argc > 1) { - if (strcmp(argv[1], "companion") == 0) { - if (argc < 3) { - LOGI("Usage: zygiskd companion \n"); - - return 1; - } - - int fd = atoi(argv[2]); - entry(fd); - - return 0; - } - - else if (strcmp(argv[1], "version") == 0) { - LOGI("ReZygisk Daemon %s\n", ZKSU_VERSION); - - return 0; - } - - 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"); - - return 1; - } - - case Multiple: { - LOGI("Multiple root implementations found.\n"); - - return 1; - } - - case KernelSU: { - LOGI("KernelSU root implementation found.\n"); - - return 0; - } - } - - - return 0; - } - - else { - LOGI("Usage: zygiskd [companion|version|root]\n"); - - return 0; - } - } - - switch_mount_namespace((pid_t)1); - root_impls_setup(); - zygiskd_start(); - - return 0; -} diff --git a/zygiskd-new/root_impl/common.c b/zygiskd-new/root_impl/common.c deleted file mode 100644 index ddc75c1..0000000 --- a/zygiskd-new/root_impl/common.c +++ /dev/null @@ -1,54 +0,0 @@ -#include - -#include "kernelsu.h" - -#include "common.h" - -static enum RootImpl ROOT_IMPL = None; - -void root_impls_setup(void) { - enum RootImplState ksu_version = ksu_get_kernel_su(); - - enum RootImpl impl = None; - - if (ksu_version == Supported) impl = KernelSU; - - ROOT_IMPL = impl; -} - -enum RootImpl get_impl(void) { - return ROOT_IMPL; -} - -bool uid_granted_root(uid_t uid) { - switch (get_impl()) { - case KernelSU: { - return ksu_uid_granted_root(uid); - } - default: { - return false; - } - } -} - -bool uid_should_umount(uid_t uid) { - switch (get_impl()) { - case KernelSU: { - return ksu_uid_should_umount(uid); - } - default: { - return false; - } - } -} - -bool uid_is_manager(uid_t uid) { - switch (get_impl()) { - case KernelSU: { - return ksu_uid_is_manager(uid); - } - default: { - return false; - } - } -} diff --git a/zygiskd-new/root_impl/common.h b/zygiskd-new/root_impl/common.h deleted file mode 100644 index 314caf3..0000000 --- a/zygiskd-new/root_impl/common.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef COMMON_H -#define COMMON_H - -#include "../constants.h" - -enum RootImpl { - None, - Multiple, /* INFO: I know. */ - KernelSU -}; - -void root_impls_setup(void); - -enum RootImpl get_impl(void); - -bool uid_granted_root(uid_t uid); - -bool uid_should_umount(uid_t uid); - -bool uid_is_manager(uid_t uid); - -#endif /* COMMON_H */ diff --git a/zygiskd-new/root_impl/kernelsu.c b/zygiskd-new/root_impl/kernelsu.c deleted file mode 100644 index b8f950c..0000000 --- a/zygiskd-new/root_impl/kernelsu.c +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include -#include -#include - -#include "../constants.h" -#include "../utils.h" - -#include "kernelsu.h" - -#define KERNEL_SU_OPTION 0xdeadbeef - -#define CMD_GET_VERSION 2 -#define CMD_UID_GRANTED_ROOT 12 -#define CMD_UID_SHOULD_UMOUNT 13 - -enum RootImplState ksu_get_kernel_su(void) { - int version = 0; - prctl(KERNEL_SU_OPTION, CMD_GET_VERSION, &version, 0, 0); - - errno = 0; - - if (version == 0) return Abnormal; - - if (version >= MIN_KSU_VERSION && version <= MAX_KSU_VERSION) return Supported; - - if (version >= 1 && version <= MIN_KSU_VERSION - 1) return TooOld; - - return Abnormal; -} - -bool ksu_uid_granted_root(uid_t uid) { - uint32_t result = 0; - bool granted = false; - prctl(KERNEL_SU_OPTION, CMD_UID_GRANTED_ROOT, uid, &granted, &result); - - LOGI("ksu_uid_granted_root: %d", granted); - - if (result != KERNEL_SU_OPTION) return false; - - return granted; -} - -bool ksu_uid_should_umount(uid_t uid) { - uint32_t result = 0; - bool umount = false; - prctl(KERNEL_SU_OPTION, CMD_UID_SHOULD_UMOUNT, uid, &umount, &result); - - LOGI("ksu_uid_should_umount: %d", umount); - - if (result != KERNEL_SU_OPTION) return false; - - return umount; -} - -bool ksu_uid_is_manager(uid_t uid) { - - struct stat s; - if (stat("/data/user_de/0/me.weishu.kernelsu", &s) == 0) { - LOGI("ksu_uid_is_manager: %d", uid); - - return s.st_uid == uid; - } - - LOGI("ksu_uid_is_manager: false"); - - return false; -} diff --git a/zygiskd-new/root_impl/kernelsu.h b/zygiskd-new/root_impl/kernelsu.h deleted file mode 100644 index 1f2c494..0000000 --- a/zygiskd-new/root_impl/kernelsu.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef KERNELSU_H -#define KERNELSU_H - -#include "../constants.h" - -enum RootImplState ksu_get_kernel_su(void); - -bool ksu_uid_granted_root(uid_t uid); - -bool ksu_uid_should_umount(uid_t uid); - -bool ksu_uid_is_manager(uid_t uid); - -#endif diff --git a/zygiskd-new/utils.c b/zygiskd-new/utils.c deleted file mode 100644 index 3984876..0000000 --- a/zygiskd-new/utils.c +++ /dev/null @@ -1,295 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include "utils.h" - -void switch_mount_namespace(pid_t pid) { - char current_path[PATH_MAX]; - if (getcwd(current_path, PATH_MAX) == NULL) { - /* TODO: Improve error messages */ - LOGE("getcwd: %s\n", strerror(errno)); - - return; - } - - /* INFO: We will NEVER achieve PATH_MAX value, but this is for ensurance. */ - char path[PATH_MAX]; - snprintf(path, PATH_MAX, "/proc/%d/ns/mnt", pid); - - FILE *mnt_ns = fopen(path, "r"); - if (mnt_ns == NULL) { - /* TODO: Improve error messages */ - LOGE("fopen: %s\n", strerror(errno)); - - return; - } - - if (setns(fileno(mnt_ns), 0) == -1) { - /* TODO: Improve error messages */ - LOGE("setns: %s\n", strerror(errno)); - - return; - } - - fclose(mnt_ns); - - if (chdir(current_path) == -1) { - /* TODO: Improve error messages */ - LOGE("chdir: %s\n", strerror(errno)); - - return; - } -} - -int __system_property_get(const char *, char *); - -void get_property(const char *name, char *output) { - __system_property_get(name, output); -} - -void set_socket_create_context(const char *context) { - char path[PATH_MAX]; - snprintf(path, PATH_MAX, "/proc/thread-self/attr/sockcreate"); - - FILE *sockcreate = fopen(path, "w"); - if (sockcreate == NULL) { - LOGE("fopen: %s\n", strerror(errno)); - - return; - } - - if (fwrite(context, 1, strlen(context), sockcreate) != strlen(context)) { - LOGE("fwrite: %s\n", strerror(errno)); - - return; - } - - fclose(sockcreate); -} - -static void get_current_attr(char *output) { - char path[PATH_MAX]; - snprintf(path, PATH_MAX, "/proc/self/attr/current"); - - FILE *current = fopen(path, "r"); - if (current == NULL) { - LOGE("fopen: %s\n", strerror(errno)); - - return; - } - - if (fgets(output, PATH_MAX, current) == NULL) { - LOGE("fgets: %s\n", strerror(errno)); - - return; - } - - fclose(current); -} - -void unix_datagram_sendto(const char *path, void *buf, size_t len) { - char current_attr[PATH_MAX]; - get_current_attr(current_attr); - - set_socket_create_context(current_attr); - - struct sockaddr_un addr; - addr.sun_family = AF_UNIX; - - strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1); - - int socket_fd = socket(AF_UNIX, SOCK_DGRAM, 0); - if (socket_fd == -1) { - LOGE("socket: %s\n", strerror(errno)); - - return; - } - - if (connect(socket_fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) { - LOGE("connect: %s\n", strerror(errno)); - - return; - } - - if (sendto(socket_fd, buf, len, 0, (struct sockaddr *)&addr, sizeof(addr)) == -1) { - LOGE("sendto: %s\n", strerror(errno)); - - return; - } - - set_socket_create_context("u:r:zygote:s0"); - - close(socket_fd); -} - -int chcon(const char *path, const char *context) { - char command[PATH_MAX]; - snprintf(command, PATH_MAX, "chcon %s %s", context, path); - - return system(command); -} - -int unix_listener_from_path(char *path) { - if (remove(path) == -1 && errno != ENOENT) { - LOGE("remove: %s\n", strerror(errno)); - - return -1; - } - - int socket_fd = socket(AF_UNIX, SOCK_STREAM, 0); - if (socket_fd == -1) { - LOGE("socket: %s\n", strerror(errno)); - - return -1; - } - - struct sockaddr_un addr; - - memset(&addr, 0, sizeof(struct sockaddr_un)); - addr.sun_family = AF_UNIX; - strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1); - - if (bind(socket_fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) == -1) { - LOGE("bind: %s\n", strerror(errno)); - - return -1; - } - - if (listen(socket_fd, 2) == -1) { - LOGE("listen: %s\n", strerror(errno)); - - return -1; - } - - if (chcon(path, "u:object_r:magisk_file:s0") == -1) { - LOGE("chcon: %s\n", strerror(errno)); - - return -1; - } - - return socket_fd; -} - -ssize_t send_fd(int sockfd, int fd) { - char control_buf[CMSG_SPACE(sizeof(int))]; - memset(control_buf, 0, sizeof(control_buf)); - - int cnt = 1; - struct iovec iov = { - .iov_base = &cnt, - .iov_len = sizeof(cnt) - }; - - struct msghdr msg = { - .msg_iov = &iov, - .msg_iovlen = 1, - .msg_control = control_buf, - .msg_controllen = sizeof(control_buf) - }; - - struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - cmsg->cmsg_len = CMSG_LEN(sizeof(int)); - - memcpy(CMSG_DATA(cmsg), &fd, sizeof(int)); - - ssize_t sent_bytes = sendmsg(sockfd, &msg, 0); - if (sent_bytes == -1) { - LOGE("Failed to send fd: %s\n", strerror(errno)); - - return -1; - } - - return sent_bytes; -} - -ssize_t recv_fd(int sockfd, int *fd) { - char control_buf[CMSG_SPACE(sizeof(int))]; - memset(control_buf, 0, sizeof(control_buf)); - - int cnt = 1; - struct iovec iov = { - .iov_base = &cnt, - .iov_len = sizeof(cnt) - }; - - struct msghdr msg = { - .msg_iov = &iov, - .msg_iovlen = 1, - .msg_control = control_buf, - .msg_controllen = sizeof(control_buf) - }; - - ssize_t received_bytes = recvmsg(sockfd, &msg, 0); - if (received_bytes == -1) { - LOGE("Failed to read fd: %s\n", strerror(errno)); - - return -1; - } - - struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - memcpy(fd, CMSG_DATA(cmsg), sizeof(int)); - - return received_bytes; -} - -ssize_t write_string(int fd, const char *str) { - size_t len = strlen(str); - - ssize_t written_bytes = write(fd, &len, sizeof(len)); - if (written_bytes != sizeof(len)) { - LOGE("Failed to write string length: %s\n", strerror(errno)); - - return -1; - } - - written_bytes = write(fd, str, len); - if ((size_t)written_bytes != len) { - LOGE("Failed to write string: Not all bytes were written.\n"); - - return -1; - } - - return written_bytes; -} - -ssize_t read_string(int fd, char *str, size_t len) { - size_t str_len_buf[1]; - - ssize_t read_bytes = read(fd, &str_len_buf, sizeof(str_len_buf)); - if (read_bytes != (ssize_t)sizeof(str_len_buf)) { - LOGE("Failed to read string length: %s\n", strerror(errno)); - - return -1; - } - - size_t str_len = str_len_buf[0]; - - if (str_len > len) { - LOGE("Failed to read string: Buffer is too small (%zu > %zu).\n", str_len, len); - - return -1; - } - - read_bytes = read(fd, str, str_len); - if (read_bytes != (ssize_t)str_len) { - LOGE("Failed to read string: Not all bytes were read (%zd != %zu).\n", read_bytes, str_len); - - return -1; - } - - return read_bytes; -} diff --git a/zygiskd-new/utils.h b/zygiskd-new/utils.h deleted file mode 100644 index b86c869..0000000 --- a/zygiskd-new/utils.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef UTILS_H -#define UTILS_H - -#include - -#include "constants.h" - -#define LOGI(...) \ - __android_log_print(ANDROID_LOG_INFO, lp_select("zygiskd32", "zygiskd64"), __VA_ARGS__); \ - printf(__VA_ARGS__) - -#define LOGE(...) \ - __android_log_print(ANDROID_LOG_INFO , lp_select("zygiskd32", "zygiskd64"), __VA_ARGS__); \ - printf(__VA_ARGS__) - -void switch_mount_namespace(pid_t pid); - -void get_property(const char *name, char *output); - -void set_socket_create_context(const char *context); - -void unix_datagram_sendto(const char *path, void *buf, size_t len); - -int chcon(const char *path, const char *context); - -int unix_listener_from_path(char *path); - -ssize_t send_fd(int sockfd, int fd); - -ssize_t recv_fd(int sockfd, int *fd); - -ssize_t write_string(int fd, const char *str); - -ssize_t read_string(int fd, char *str, size_t len); - -#endif /* UTILS_H */ diff --git a/zygiskd-new/zygiskd.c b/zygiskd-new/zygiskd.c deleted file mode 100644 index 311bf06..0000000 --- a/zygiskd-new/zygiskd.c +++ /dev/null @@ -1,690 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include "root_impl/common.h" -#include "constants.h" -#include "utils.h" - -struct Module { - char *name; - int lib_fd; - int companion; -}; - -struct Context { - struct Module *modules; - int len; -}; - -enum Architecture { - ARM32, - ARM64, - X86, - X86_64, -}; - -#define PATH_MODULES_DIR "/data/adb/modules" -#define TMP_PATH "/data/adb/rezygisk" -#define CONTROLLER_SOCKET TMP_PATH "/init_monitor" -#define PATH_CP_NAME TMP_PATH "/" lp_select("cp32.sock", "cp64.sock") -#define ZYGISKD_FILE "zygiskd" lp_select("32", "64") -#define ZYGISKD_PATH "/data/adb/modules/zygisksu/bin/zygiskd" lp_select("32", "64") - -#define ASSURE_SIZE_WRITE(area_name, subarea_name, sent_size, expected_size) \ - if (sent_size != (ssize_t)(expected_size)) { \ - LOGE("Failed to sent " subarea_name " in " area_name ": Expected %zu, got %zd\n", expected_size, sent_size); \ - \ - return; \ - } - -#define ASSURE_SIZE_READ(area_name, subarea_name, sent_size, expected_size) \ - if (sent_size != (ssize_t)(expected_size)) { \ - LOGE("Failed to read " subarea_name " in " area_name ": Expected %zu, got %zd\n", expected_size, sent_size); \ - \ - return; \ - } - -#define ASSURE_SIZE_WRITE_BREAK(area_name, subarea_name, sent_size, expected_size) \ - if (sent_size != (ssize_t)(expected_size)) { \ - LOGE("Failed to sent " subarea_name " in " area_name ": Expected %zu, got %zd\n", expected_size, sent_size); \ - \ - break; \ - } - -#define ASSURE_SIZE_READ_BREAK(area_name, subarea_name, sent_size, expected_size) \ - if (sent_size != (ssize_t)(expected_size)) { \ - LOGE("Failed to read " subarea_name " in " area_name ": Expected %zu, got %zd\n", expected_size, sent_size); \ - \ - break; \ - } - -#define ASSURE_SIZE_WRITE_WR(area_name, subarea_name, sent_size, expected_size) \ - if (sent_size != (ssize_t)(expected_size)) { \ - LOGE("Failed to sent " subarea_name " in " area_name ": Expected %zu, got %zd\n", expected_size, sent_size); \ - \ - return -1; \ - } - -#define ASSURE_SIZE_READ_WR(area_name, subarea_name, sent_size, expected_size) \ - if (sent_size != (ssize_t)(expected_size)) { \ - LOGE("Failed to read " subarea_name " in " area_name ": Expected %zu, got %zd\n", expected_size, sent_size); \ - \ - return -1; \ - } - -static enum Architecture get_arch(void) { - char system_arch[32]; - get_property("ro.product.cpu.abi", system_arch); - - if (strstr(system_arch, "arm") != NULL) return lp_select(ARM32, ARM64); - if (strstr(system_arch, "x86") != NULL) return lp_select(X86, X86_64); - - LOGE("Unsupported system architecture: %s\n", system_arch); - exit(1); -} - -int create_library_fd(const char *so_path) { - int memfd = memfd_create("jit-cache-zygisk", MFD_ALLOW_SEALING); - if (memfd == -1) { - perror("memfd_create"); - - return -1; - } - - int so_fd = open(so_path, O_RDONLY); - if (so_fd == -1) { - perror("open"); - close(memfd); - - return -1; - } - - struct stat st; - if (fstat(so_fd, &st) == -1) { - perror("fstat"); - close(so_fd); - close(memfd); - - return -1; - } - - if (sendfile(memfd, so_fd, NULL, st.st_size) == -1) { - perror("sendfile"); - close(so_fd); - close(memfd); - - return -1; - } - - close(so_fd); - - if (fcntl(memfd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE | F_SEAL_SEAL) == -1) { - perror("fcntl"); - close(memfd); - - return -1; - } - - return memfd; -} - - -/* WARNING: Dynamic memory based */ -static void load_modules(enum Architecture arch, struct Context *context) { - context->len = 0; - context->modules = malloc(1); - - DIR *dir = opendir(PATH_MODULES_DIR); - if (dir == NULL) { - LOGE("Failed opening modules directory: %s.", PATH_MODULES_DIR); - - return; - } - - char arch_str[32]; - switch (arch) { - case ARM32: { - strcpy(arch_str, "armeabi-v7a"); - - break; - } - case ARM64: { - strcpy(arch_str, "arm64-v8a"); - - break; - } - case X86: { - strcpy(arch_str, "x86"); - - break; - } - case X86_64: { - strcpy(arch_str, "x86_64"); - - break; - } - } - - LOGI("Loading modules for architecture: %s\n", arch_str); - - struct dirent *entry; - while ((entry = readdir(dir)) != NULL) { - if (entry->d_type != DT_DIR) continue; /* INFO: Only directories */ - if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0 || strcmp(entry->d_name, "zygisksu") == 0) continue; - - char *name = entry->d_name; - char so_path[PATH_MAX]; - snprintf(so_path, PATH_MAX, "/data/adb/modules/%s/zygisk/%s.so", name, arch_str); - - struct stat st; - if (stat(so_path, &st) == -1) { - errno = 0; - - continue; - } - - char disabled[PATH_MAX]; - snprintf(disabled, PATH_MAX, "/data/adb/modules/%s/disable", name); - - if (stat(disabled, &st) != -1) { - errno = 0; - - continue; - } - - LOGI("Loading module `%s`...\n", name); - int lib_fd = create_library_fd(so_path); - if (lib_fd == -1) { - LOGE("Failed loading module `%s`\n", name); - - continue; - } - - LOGI("Loaded module lib fd: %d\n", lib_fd); - - context->modules = realloc(context->modules, ((context->len + 1) * sizeof(struct Module))); - context->modules[context->len].name = strdup(name); - context->modules[context->len].lib_fd = lib_fd; - context->modules[context->len].companion = -1; - context->len++; - } -} - -static void free_modules(struct Context *context) { - for (int i = 0; i < context->len; i++) { - free(context->modules[i].name); - if (context->modules[i].companion != -1) close(context->modules[i].companion); - } -} - -static int create_daemon_socket(void) { - set_socket_create_context("u:r:zygote:s0"); - - return unix_listener_from_path(PATH_CP_NAME); -} - -static int spawn_companion(char *name, int lib_fd) { - int sockets[2]; - if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) == -1) { - LOGE("Failed creating socket pair.\n"); - - return -1; - } - - int daemon_fd = sockets[0]; - int companion_fd = sockets[1]; - - LOGI("Companion fd: %d\n", companion_fd); - LOGI("Daemon fd: %d\n", daemon_fd); - - pid_t pid = fork(); - LOGI("Forked: %d\n", pid); - if (pid < 0) { - LOGE("Failed forking companion: %s\n", strerror(errno)); - - close(companion_fd); - close(daemon_fd); - - exit(1); - } else if (pid > 0) { - close(companion_fd); - - LOGI("Waiting for companion to start (%d)\n", pid); - - int status = 0; - // waitpid(pid, &status, 0); - - LOGI("Companion exited with status %d\n", status); - - // if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { - if (write_string(daemon_fd, name) == -1) return -1; - - if (send_fd(daemon_fd, lib_fd) == -1) return -1; - - LOGI("Sent module name and lib fd\n"); - - uint8_t response_buf[1]; - ssize_t ret = read(daemon_fd, &response_buf, sizeof(response_buf)); - ASSURE_SIZE_READ_WR("companion", "response", ret, sizeof(response_buf)); - - uint8_t response = response_buf[0]; - - LOGI("Companion response: %hhu\n", response); - - if (response == 0) return -2; - else if (response == 1) return daemon_fd; - else return -2; - // } else { - // LOGE("Exited with status %d\n", status); - - // close(daemon_fd); - - // return -1; - // } - /* INFO: if pid == 0: */ - } else { - LOGI("Companion started (%d)\n", pid); - /* INFO: There is no case where this will fail with a valid fd. */ - fcntl(companion_fd, F_SETFD, 0); - } - - char companion_fd_str[32]; - snprintf(companion_fd_str, 32, "%d", companion_fd); - - LOGI("Executing companion...\n"); - - char *argv[] = { ZYGISKD_FILE, "companion", companion_fd_str, NULL }; - if (execv(ZYGISKD_PATH, argv) == -1) { - LOGE("Failed executing companion: %s\n", strerror(errno)); - - close(companion_fd); - - exit(1); - } - - exit(0); -} - -/* TODO: Is packed attribute really necessary? */ -struct __attribute__((__packed__)) MsgHead { - unsigned int cmd; - int length; - char data[0]; -}; - -void zygiskd_start(void) { - LOGI("Welcome to ReZygisk %s!", ZKSU_VERSION); - - enum Architecture arch = get_arch(); - - struct Context context; - load_modules(arch, &context); - - struct MsgHead *msg = NULL; - size_t msg_sz = 0; - - switch (get_impl()) { - case None: { - /* INFO: Stop, compiler. */ - - break; - } - case Multiple: { - /* INFO: Stop, compiler. */ - - break; - } - - case KernelSU: { - if (context.len == 0) { - msg_sz = sizeof(struct MsgHead) + strlen("Root: KernelSU, Modules: None") + 1; - msg = malloc(msg_sz); - - msg->cmd = DAEMON_SET_INFO; - msg->length = strlen("Root: KernelSU, Modules: None") + 1; - memcpy(msg->data, "Root: KernelSU, Modules: None", strlen("Root: KernelSU, Modules: None")); - } else { - char *module_list = malloc(1); - 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_sz = sizeof(struct MsgHead) + strlen("Root: KernelSU, Modules: ") + module_list_len + 1; - msg = malloc(msg_sz); - - msg->cmd = DAEMON_SET_INFO; - msg->length = strlen("Root: KernelSU, Modules: ") + module_list_len + 1; - memcpy(msg->data, "Root: KernelSU, Modules: ", strlen("Root: KernelSU, Modules: ")); - memcpy(msg->data + strlen("Root: KernelSU, Modules: "), module_list, module_list_len); - - free(module_list); - } - - break; - } - default: { - msg_sz = sizeof(struct MsgHead) + strlen("Invalid root implementation") + 1; - msg = malloc(msg_sz); - - msg->cmd = DAEMON_SET_ERROR_INFO; - msg->length = strlen("Invalid root implementation") + 1; - memcpy(msg->data, "Invalid root implementation", strlen("Invalid root implementation")); - - break; - } - } - - unix_datagram_sendto(CONTROLLER_SOCKET, (void *)msg, msg_sz); - - free(msg); - - int socket_fd = create_daemon_socket(); - if (socket_fd == -1) { - LOGE("Failed creating daemon socket\n"); - - return; - } - - while (1) { - int client_fd = accept(socket_fd, NULL, NULL); - if (client_fd == -1) { - LOGE("accept: %s\n", strerror(errno)); - - return; - } - - LOGI("Accepted client: %d\n", client_fd); - - unsigned char buf[1]; - ssize_t len = read(client_fd, buf, sizeof(buf)); - if (len == -1) { - LOGE("read: %s\n", strerror(errno)); - - return; - } else if (len == 0) { - LOGI("Client disconnected\n"); - - return; - } - - LOGI("Action: %hhu\n", (uint8_t)buf[0]); - enum DaemonSocketAction action = (enum DaemonSocketAction)buf[0]; - - switch (action) { - case PingHeartbeat: { - enum DaemonSocketAction msgr = ZYGOTE_INJECTED; - unix_datagram_sendto(CONTROLLER_SOCKET, &msgr, sizeof(enum DaemonSocketAction)); - - break; - } - case ZygoteRestart: { - LOGI("Zygote restart\n"); - - for (int i = 0; i < context.len; i++) { - if (context.modules[i].companion != -1) { - close(context.modules[i].companion); - context.modules[i].companion = -1; - } - } - - break; - } - case SystemServerStarted: { - enum DaemonSocketAction msgr = SYSTEM_SERVER_STARTED; - unix_datagram_sendto(CONTROLLER_SOCKET, &msgr, sizeof(enum DaemonSocketAction)); - - break; - } - case RequestLogcatFd: { - char level_buf[1]; - ssize_t ret = read(client_fd, &level_buf, sizeof(level_buf)); - ASSURE_SIZE_READ_BREAK("RequestLogcatFd", "level", ret, sizeof(level_buf)); - - char level = level_buf[0]; - - char tag[128 + 1]; - ret = read_string(client_fd, tag, sizeof(tag) - 1); - if (ret == -1) break; - - tag[ret] = '\0'; - - char message[1024]; - ret = read_string(client_fd, message, sizeof(message)); - if (ret == -1) break; - - __android_log_print(level, tag, "%.*s", (int)ret, message); - - break; - } - case GetProcessFlags: { - LOGI("Getting process flags\n"); - - uid_t uid_buf[1]; - ssize_t ret = read(client_fd, &uid_buf, sizeof(uid_buf)); - ASSURE_SIZE_READ_BREAK("GetProcessFlags", "uid", ret, sizeof(uid_buf)); - - uid_t uid = uid_buf[0]; - - LOGI("Checking flags for uid: %d\n", uid); - - uint32_t flags = 0; - if (uid_is_manager(uid)) { - flags |= PROCESS_IS_MANAGER; - } else { - if (uid_granted_root(uid)) { - flags |= PROCESS_GRANTED_ROOT; - } - if (uid_should_umount(uid)) { - flags |= PROCESS_ON_DENYLIST; - } - } - - LOGI("Flags for uid %d: %d\n", uid, flags); - - switch (get_impl()) { - case None: { - break; - } - case Multiple: { - break; - } - case KernelSU: { - flags |= PROCESS_ROOT_IS_KSU; - } - } - - // LOGI("Flags for uid %d: %d\n", uid, flags); - - LOGI("Sending flags\n"); - - ret = write(client_fd, &flags, sizeof(flags)); - // ASSURE_SIZE_WRITE_BREAK("GetProcessFlags", "flags", ret, sizeof(flags)); - - LOGI("Sent flags\n"); - - break; - } - case GetInfo: { - uint32_t flags = 0; - - LOGI("Getting info\n"); - - switch (get_impl()) { - case None: { - break; - } - case Multiple: { - break; - } - case KernelSU: { - flags |= PROCESS_ROOT_IS_KSU; - } - } - - LOGI("Flags: %d\n", flags); - - ssize_t ret = write(client_fd, &flags, sizeof(flags)); - ASSURE_SIZE_WRITE_BREAK("GetInfo", "flags", ret, sizeof(flags)); - - pid_t pid = getpid(); - - LOGI("Getting pid: %d\n", pid); - - ret = write(client_fd, &pid, sizeof(pid)); - ASSURE_SIZE_WRITE_BREAK("GetInfo", "pid", ret, sizeof(pid)); - - LOGI("Sent pid\n"); - - break; - } - case ReadModules: { - LOGI("Reading modules to stream\n"); - - size_t clen = context.len; - ssize_t ret = write(client_fd, &clen, sizeof(clen)); - ASSURE_SIZE_WRITE_BREAK("ReadModules", "len", ret, sizeof(clen)); - - for (int i = 0; i < (int)clen; i++) { - LOGI("Hey, we're talking about: %d\n", i); - LOGI("Writing module `%s` to stream\n", context.modules[i].name); - LOGI("Lib fd: %d\n", context.modules[i].lib_fd); - - size_t name_len = strlen(context.modules[i].name); - - LOGI("Name length: %zu\n", name_len); - ret = write(client_fd, &name_len, sizeof(name_len)); - ASSURE_SIZE_WRITE_BREAK("ReadModules", "name length", ret, sizeof(name_len)); - - LOGI("Writing name: %s\n", context.modules[i].name); - ret = write(client_fd, context.modules[i].name, name_len); - ASSURE_SIZE_WRITE_BREAK("ReadModules", "name", ret, name_len); - - LOGI("Writing lib fd: %d\n", context.modules[i].lib_fd); - if (send_fd(client_fd, context.modules[i].lib_fd) == -1) break; - } - - LOGI("Finished reading modules to stream\n"); - - break; - } - case RequestCompanionSocket: { - LOGI("Requesting companion socket\n"); - - size_t index_buf[1]; - ssize_t ret = read(client_fd, &index_buf, sizeof(index_buf)); - ASSURE_SIZE_READ_BREAK("RequestCompanionSocket", "index", ret, sizeof(index_buf)); - - size_t index = index_buf[0]; - - struct Module *module = &context.modules[index]; - int companion_fd = module->companion; - - if (companion_fd != -1) { - LOGI("Companion for module `%s` already exists\n", module->name); - - if (fcntl(companion_fd, F_GETFD) == -1) { - LOGE("Poll companion for module `%s` crashed\n", module->name); - close(companion_fd); - - module->companion = -1; - } - } - - if (companion_fd == -1) { - LOGI("Spawning companion for `%s`\n", module->name); - - companion_fd = spawn_companion(module->name, module->lib_fd); - - if (companion_fd != -1) { - LOGI("Spawned companion for `%s`\n", module->name); - - module->companion = companion_fd; - - if (send_fd(client_fd, companion_fd) == -1) break; - } else if (companion_fd == -2) { - LOGI("Could not spawn companion for `%s` as it has no entry\n", module->name); - - /* TODO: Avoid duplicated code -- Merge this and the one below. */ - uint8_t response = 0; - ret = write(client_fd, &response, sizeof(response)); - ASSURE_SIZE_WRITE_BREAK("RequestCompanionSocket", "response", ret, sizeof(response)); - } else { - LOGE("Failed to spawn companion for `%s`\n", module->name); - - uint8_t response = 0; - ret = write(client_fd, &response, sizeof(response)); - ASSURE_SIZE_WRITE_BREAK("RequestCompanionSocket", "response", ret, sizeof(response)); - } - - LOGI("Companion fd: %d\n", companion_fd); - } - - break; - } - case GetModuleDir: { - LOGI("Getting module directory\n"); - - size_t index_buf[1]; - ssize_t ret = read(client_fd, &index_buf, sizeof(index_buf)); - ASSURE_SIZE_READ_BREAK("GetModuleDir", "index", ret, sizeof(index_buf)); - - size_t index = index_buf[0]; - - LOGI("Index: %zu\n", index); - - char dir[PATH_MAX]; - snprintf(dir, PATH_MAX, "%s/%s", PATH_MODULES_DIR, context.modules[index].name); - - LOGI("Module directory: %s\n", dir); - int dir_fd = open(dir, O_RDONLY); - - LOGI("Module directory fd: %d\n", dir_fd); - - if (send_fd(client_fd, dir_fd) == -1) break; - - LOGI("Sent module directory fd\n"); - - break; - } - - - - close(client_fd); - } - - continue; - } - - close(socket_fd); - free_modules(&context); -} diff --git a/zygiskd-new/zygiskd.h b/zygiskd-new/zygiskd.h deleted file mode 100644 index 9492a50..0000000 --- a/zygiskd-new/zygiskd.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef ZYGISKD_H -#define ZYGISKD_H - -void zygiskd_start(void); - -#endif /* ZYGISKD_H */ diff --git a/zygiskd/build.gradle.kts b/zygiskd/build.gradle.kts new file mode 100644 index 0000000..e5ed214 --- /dev/null +++ b/zygiskd/build.gradle.kts @@ -0,0 +1,127 @@ +import java.nio.file.Paths +import org.gradle.internal.os.OperatingSystem + +fun getLatestNDKPath(): String { + val android_home = System.getenv("ANDROID_HOME") + if (android_home == null) { + throw Exception("ANDROID_HOME not set") + } + + val ndkPath = android_home + "/ndk" + + val ndkDir = Paths.get(ndkPath) + if (!ndkDir.toFile().exists()) { + throw Exception("NDK not found at $ndkPath") + } + + val ndkVersion = ndkDir.toFile().listFiles().filter { it.isDirectory }.map { it.name }.sorted().last() + return ndkPath + "/" + ndkVersion +} + +val minAPatchVersion: Int by rootProject.extra +val minKsuVersion: Int by rootProject.extra +val maxKsuVersion: Int by rootProject.extra +val minMagiskVersion: Int by rootProject.extra +val verCode: Int by rootProject.extra +val verName: String by rootProject.extra +val commitHash: String by rootProject.extra + +val CFlagsRelease = arrayOf( + "-D_GNU_SOURCE", "-std=c99", "-Wpedantic", "-Wall", "-Wextra", "-Werror", + "-Wformat", "-Wuninitialized", "-Wshadow", "-Wno-zero-length-array", + "-Wno-fixed-enum-extension", "-Iroot_impl", "-llog" +) + +val CFlagsDebug = arrayOf( + "-D_GNU_SOURCE", "-std=c99", "-Wpedantic", "-Wall", "-Wextra", "-Werror", + "-Wformat", "-Wuninitialized", "-Wshadow", "-Wno-zero-length-array", + "-Wno-fixed-enum-extension", "-Iroot_impl", "-llog", "-g" +) + +val Files = arrayOf( + "root_impl/common.c", + "root_impl/kernelsu.c", + "companion.c", + "dl.c", + "main.c", + "utils.c", + "zygiskd.c" +) + +task("buildAndStrip") { + group = "build" + description = "Build the native library and strip the debug symbols." + + val isDebug = gradle.startParameter.taskNames.any { it.lowercase().contains("debug") } + doLast { + val ndkPath = getLatestNDKPath() + + val aarch64Compiler = Paths.get(ndkPath, "toolchains", "llvm", "prebuilt", "linux-x86_64", "bin", "aarch64-linux-android34-clang").toString() + val armv7aCompiler = Paths.get(ndkPath, "toolchains", "llvm", "prebuilt", "linux-x86_64", "bin", "armv7a-linux-androideabi34-clang").toString() + + if (!Paths.get(aarch64Compiler).toFile().exists()) { + throw Exception("aarch64 compiler not found at $aarch64Compiler") + } + + if (!Paths.get(armv7aCompiler).toFile().exists()) { + throw Exception("armv7a compiler not found at $armv7aCompiler") + } + + val Files = Files.map { Paths.get(project.projectDir.toString(), "src", it).toString() }.toTypedArray() + + val buildDir = getLayout().getBuildDirectory().getAsFile().get() + buildDir.mkdirs() + + val compileArgs = if (isDebug) CFlagsDebug else CFlagsRelease + + val execFile = { command: Array -> + val process = Runtime.getRuntime().exec(command) + val output = process.inputStream.bufferedReader().readText() + process.waitFor() + output + } + + val aarch64OutputDir = Paths.get(buildDir.toString(), "arm64-v8a").toFile() + aarch64OutputDir.mkdirs() + + /* INFO: Compile for aarch64 */ + val aarch64Command = arrayOf(aarch64Compiler, "-o", Paths.get(aarch64OutputDir.toString(), "zygiskd").toString(), *compileArgs, *Files) + val aarch64CommandResult = execFile(aarch64Command) + if (aarch64CommandResult.isNotEmpty()) { + println(aarch64CommandResult) + } + + val armv7aOutputDir = Paths.get(buildDir.toString(), "armeabi-v7a").toFile() + armv7aOutputDir.mkdirs() + + /* INFO: Compile for armv7a */ + val armv7aCommand = arrayOf(armv7aCompiler, "-o", Paths.get(armv7aOutputDir.toString(), "zygiskd").toString(), *compileArgs, *Files) + val armv7aCommandResult = execFile(armv7aCommand) + if (armv7aCommandResult.isNotEmpty()) { + println(armv7aCommandResult) + } + + val x86OutputDir = Paths.get(buildDir.toString(), "x86").toFile() + x86OutputDir.mkdirs() + + /* INFO: Compile for x86 */ + val x86Compiler = Paths.get(ndkPath, "toolchains", "llvm", "prebuilt", "linux-x86_64", "bin", "i686-linux-android34-clang").toString() + val x86Command = arrayOf(x86Compiler, "-o", Paths.get(x86OutputDir.toString(), "zygiskd").toString(), *compileArgs, *Files) + val x86CommandResult = execFile(x86Command) + if (x86CommandResult.isNotEmpty()) { + println(x86CommandResult) + } + + val x86_64OutputDir = Paths.get(buildDir.toString(), "x86_64").toFile() + x86_64OutputDir.mkdirs() + + /* INFO: Compile for x86_64 */ + val x86_64Compiler = Paths.get(ndkPath, "toolchains", "llvm", "prebuilt", "linux-x86_64", "bin", "x86_64-linux-android34-clang").toString() + val x86_64Command = arrayOf(x86_64Compiler, "-o", Paths.get(x86_64OutputDir.toString(), "zygiskd").toString(), *compileArgs, *Files) + val x86_64CommandResult = execFile(x86_64Command) + if (x86_64CommandResult.isNotEmpty()) { + println(x86_64CommandResult) + } + } +} + diff --git a/zygiskd/build.gradlew.kts b/zygiskd/build.gradlew.kts deleted file mode 100644 index 697ed96..0000000 --- a/zygiskd/build.gradlew.kts +++ /dev/null @@ -1,85 +0,0 @@ -import java.nio.file.Paths -import org.gradle.internal.os.OperatingSystem - -plugins { - alias(libs.plugins.agp.lib) -} - -val verCode: Int by rootProject.extra -val verName: String by rootProject.extra -val commitHash: String by rootProject.extra - -fun Project.findInPath(executable: String, property: String): String? { - val pathEnv = System.getenv("PATH") - return pathEnv.split(File.pathSeparator).map { folder -> - Paths.get("${folder}${File.separator}${executable}${if (OperatingSystem.current().isWindows) ".exe" else ""}") - .toFile() - }.firstOrNull { path -> - path.exists() - }?.absolutePath ?: properties.getOrDefault(property, null) as? String? -} - -val ccachePath by lazy { - project.findInPath("ccache", "ccache.path")?.also { - println("loader: Use ccache: $it") - } -} - -val defaultCFlags = arrayOf( - "-Wall", "-Wextra", - "-fno-rtti", "-fno-exceptions", - "-fno-stack-protector", "-fomit-frame-pointer", - "-Wno-builtin-macro-redefined", "-D__FILE__=__FILE_NAME__", - "-O0", "-g" -) - -val releaseFlags = arrayOf( - "-Oz", "-flto", - "-Wno-unused", "-Wno-unused-parameter", - "-fvisibility=hidden", "-fvisibility-inlines-hidden", - "-fno-unwind-tables", "-fno-asynchronous-unwind-tables", - "-Wl,--exclude-libs,ALL", "-Wl,--gc-sections", "-Wl,--strip-all" -) - -android { - buildFeatures { - androidResources = false - buildConfig = false - prefab = true - } - - externalNativeBuild.cmake { - path("src/CMakeLists.txt") - } - - defaultConfig { - externalNativeBuild.cmake { - arguments += "-DANDROID_STL=none" - arguments += "-DLSPLT_STANDALONE=ON" - cFlags("-std=c18", *defaultCFlags) - cppFlags("-std=c++20", *defaultCFlags) - ccachePath?.let { - arguments += "-DNDK_CCACHE=$it" - } - } - } - - buildTypes { - debug { - externalNativeBuild.cmake { - arguments += "-DZKSU_VERSION=$verName-$verCode-$commitHash-debug" - } - } - release { - externalNativeBuild.cmake { - cFlags += releaseFlags - cppFlags += releaseFlags - arguments += "-DZKSU_VERSION=$verName-$verCode-$commitHash-release" - } - } - } -} - -dependencies { - implementation("dev.rikka.ndk.thirdparty:cxx:1.2.0") -} diff --git a/zygiskd/src/CMakeLists.txt b/zygiskd/src/CMakeLists.txt deleted file mode 100644 index b3c9ec5..0000000 --- a/zygiskd/src/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -cmake_minimum_required(VERSION 3.22.1) -project("zygiskd") - -find_package(cxx REQUIRED CONFIG) - -add_definitions(-DZKSU_VERSION=\"${ZKSU_VERSION}\") - -aux_source_directory(common COMMON_SRC_LIST) -add_library(common STATIC ${COMMON_SRC_LIST}) -target_include_directories(common PRIVATE include) -target_link_libraries(log) - -aux_source_directory(ptracer PTRACER_SRC_LIST) -add_executable(libzygisk_ptrace.so ${PTRACER_SRC_LIST}) -target_include_directories(libzygisk_ptrace.so PRIVATE include) -target_link_libraries(libzygisk_ptrace.so cxx::cxx log common)