add: 32-bit only environment support

This commit adds support for devices that are only capable of running 32-bit code, be it due to Android ROM limitations of CPU limitations. It also makes ReZygisk only install necessary libraries, so if a device is 64-bit only, it won't extract 32-bit libraries.
This commit is contained in:
ThePedroo
2025-04-26 20:41:45 -03:00
parent 0d60dc0ec0
commit 96123aa53c
5 changed files with 214 additions and 147 deletions

View File

@@ -48,10 +48,20 @@ struct rezygiskd_status {
};
struct rezygiskd_status status64 = {
.daemon_pid = -1
.supported = false,
.zygote_injected = false,
.daemon_running = false,
.daemon_pid = -1,
.daemon_info = NULL,
.daemon_error_info = NULL
};
struct rezygiskd_status status32 = {
.daemon_pid = -1
.supported = false,
.zygote_injected = false,
.daemon_running = false,
.daemon_pid = -1,
.daemon_info = NULL,
.daemon_error_info = NULL
};
int monitor_epoll_fd;
@@ -156,64 +166,51 @@ bool rezygiskd_listener_init() {
return true;
}
void rezygiskd_listener_callback() {
struct [[gnu::packed]] MsgHead {
enum rezygiskd_command cmd;
struct __attribute__((__packed__)) MsgHead {
unsigned int cmd;
int length;
char data[0];
};
};
void rezygiskd_listener_callback() {
while (1) {
struct MsgHead *msg = (struct MsgHead *)malloc(sizeof(struct MsgHead));
struct MsgHead msg = { 0 };
ssize_t real_size;
ssize_t nread = recv(monitor_sock_fd, msg, sizeof(struct MsgHead), MSG_PEEK);
if (nread == -1) {
if (errno == EAGAIN) break;
size_t nread;
again:
nread = read(monitor_sock_fd, &msg, sizeof(msg));
if ((int)nread == -1) {
if (errno == EAGAIN || errno == EWOULDBLOCK) goto again;
PLOGE("read socket");
}
if ((size_t)nread < sizeof(enum rezygiskd_command)) {
LOGE("read %zu < %zu", nread, sizeof(enum rezygiskd_command));
continue;
}
if (msg->cmd >= DAEMON64_SET_INFO && msg->cmd != SYSTEM_SERVER_STARTED) {
if (nread != sizeof(msg)) {
LOGE("cmd %d size %zu != %zu", msg->cmd, nread, sizeof(struct MsgHead));
continue;
}
real_size = sizeof(struct MsgHead) + msg->length;
} else {
if (nread != sizeof(enum rezygiskd_command)) {
LOGE("cmd %d size %zu != %zu", msg->cmd, nread, sizeof(enum rezygiskd_command));
char *msg_data = NULL;
if (msg.length != 0) {
msg_data = malloc(msg.length);
if (!msg_data) {
LOGE("malloc msg data failed");
continue;
}
real_size = sizeof(enum rezygiskd_command);
}
again_msg_data:
nread = read(monitor_sock_fd, msg_data, msg.length);
if ((int)nread == -1) {
if (errno == EAGAIN || errno == EWOULDBLOCK) goto again_msg_data;
msg = (struct MsgHead *)realloc(msg, real_size);
nread = recv(monitor_sock_fd, msg, real_size, 0);
PLOGE("read socket");
if (nread == -1) {
if (errno == EAGAIN) break;
PLOGE("recv");
continue;
}
if (nread != real_size) {
LOGE("real size %zu != %zu", real_size, nread);
free(msg_data);
continue;
}
}
switch (msg->cmd) {
switch (msg.cmd) {
case START: {
if (tracing_state == STOPPING) tracing_state = TRACING;
else if (tracing_state == STOPPED) {
@@ -267,7 +264,7 @@ void rezygiskd_listener_callback() {
break;
}
case DAEMON64_SET_INFO: {
LOGD("received daemon64 info %s", msg->data);
LOGD("received daemon64 info %s", msg_data);
/* Will only happen if somehow the daemon restarts */
if (status64.daemon_info) {
@@ -275,42 +272,42 @@ void rezygiskd_listener_callback() {
status64.daemon_info = NULL;
}
status64.daemon_info = (char *)malloc(msg->length);
status64.daemon_info = (char *)malloc(msg.length);
if (!status64.daemon_info) {
PLOGE("malloc daemon64 info");
break;
}
strcpy(status64.daemon_info, msg->data);
strcpy(status64.daemon_info, msg_data);
update_status(NULL);
break;
}
case DAEMON32_SET_INFO: {
LOGD("received daemon32 info %s", msg->data);
LOGD("received daemon32 info %s", msg_data);
if (status32.daemon_info) {
free(status32.daemon_info);
status32.daemon_info = NULL;
}
status32.daemon_info = (char *)malloc(msg->length);
status32.daemon_info = (char *)malloc(msg.length);
if (!status32.daemon_info) {
PLOGE("malloc daemon32 info");
break;
}
strcpy(status32.daemon_info, msg->data);
strcpy(status32.daemon_info, msg_data);
update_status(NULL);
break;
}
case DAEMON64_SET_ERROR_INFO: {
LOGD("received daemon64 error info %s", msg->data);
LOGD("received daemon64 error info %s", msg_data);
status64.daemon_running = false;
@@ -319,21 +316,21 @@ void rezygiskd_listener_callback() {
status64.daemon_error_info = NULL;
}
status64.daemon_error_info = (char *)malloc(msg->length);
status64.daemon_error_info = (char *)malloc(msg.length);
if (!status64.daemon_error_info) {
PLOGE("malloc daemon64 error info");
break;
}
strcpy(status64.daemon_error_info, msg->data);
strcpy(status64.daemon_error_info, msg_data);
update_status(NULL);
break;
}
case DAEMON32_SET_ERROR_INFO: {
LOGD("received daemon32 error info %s", msg->data);
LOGD("received daemon32 error info %s", msg_data);
status32.daemon_running = false;
@@ -342,14 +339,14 @@ void rezygiskd_listener_callback() {
status32.daemon_error_info = NULL;
}
status32.daemon_error_info = (char *)malloc(msg->length);
status32.daemon_error_info = (char *)malloc(msg.length);
if (!status32.daemon_error_info) {
PLOGE("malloc daemon32 error info");
break;
}
strcpy(status32.daemon_error_info, msg->data);
strcpy(status32.daemon_error_info, msg_data);
update_status(NULL);
@@ -366,7 +363,9 @@ void rezygiskd_listener_callback() {
}
}
free(msg);
if (msg_data) free(msg_data);
break;
}
}
@@ -402,21 +401,27 @@ CREATE_ZYGOTE_START_COUNTER(32)
static bool ensure_daemon_created(bool is_64bit) {
struct rezygiskd_status *status = is_64bit ? &status64 : &status32;
if (is_64bit) {
if (is_64bit || (!is_64bit && !status64.supported)) {
LOGD("new zygote started.");
umount2("/data/adb/modules/zygisksu/module.prop", MNT_DETACH);
}
status->zygote_injected = false;
if (status->daemon_pid != -1) {
LOGI("daemon%s already running", is_64bit ? "64" : "32");
return status->daemon_running;
}
if (status->daemon_pid == -1) {
pid_t pid = fork();
if (pid < 0) {
PLOGE("create daemon%s", is_64bit ? "64" : "32");
return false;
} else if (pid == 0) {
}
if (pid == 0) {
char daemon_name[PATH_MAX] = "./bin/zygiskd";
strcat(daemon_name, is_64bit ? "64" : "32");
@@ -425,16 +430,13 @@ static bool ensure_daemon_created(bool is_64bit) {
PLOGE("exec daemon %s failed", daemon_name);
exit(1);
} else {
}
status->supported = true;
status->daemon_pid = pid;
status->daemon_running = true;
return true;
}
} else {
return status->daemon_running;
}
}
#define CHECK_DAEMON_EXIT(abi) \
@@ -845,20 +847,33 @@ void init_monitor() {
monitor_events_init();
rezygiskd_listener_init();
struct monitor_event_cbs listener_cbs = {
.callback = rezygiskd_listener_callback,
.stop_callback = rezygiskd_listener_stop
};
monitor_events_register_event(&listener_cbs, monitor_sock_fd, EPOLLIN | EPOLLET);
if (!rezygiskd_listener_init()) {
LOGE("failed to create socket");
sigchld_listener_init();
close(monitor_epoll_fd);
exit(1);
}
monitor_events_register_event(&listener_cbs, monitor_sock_fd, EPOLLIN | EPOLLET);
struct monitor_event_cbs sigchld_cbs = {
.callback = sigchld_listener_callback,
.stop_callback = sigchld_listener_stop
};
if (sigchld_listener_init() == false) {
LOGE("failed to create signalfd");
rezygiskd_listener_stop();
close(monitor_epoll_fd);
exit(1);
}
monitor_events_register_event(&sigchld_cbs, sigchld_signal_fd, EPOLLIN | EPOLLET);
monitor_events_loop();

View File

@@ -107,40 +107,69 @@ extract "$ZIPFILE" 'uninstall.sh' "$MODPATH"
mv "$TMPDIR/sepolicy.rule" "$MODPATH"
mkdir "$MODPATH/bin"
mkdir "$MODPATH/lib"
mkdir "$MODPATH/lib64"
CPU_ABIS=$(getprop ro.product.cpu.abilist)
SUPPORTS_32BIT=false
SUPPORTS_64BIT=false
if [[ "$CPU_ABIS" == *"x86"* && "$CPU_ABIS" != "x86_64" || "$CPU_ABIS" == *"armeabi"* ]]; then
SUPPORTS_32BIT=true
ui_print "- Device supports 32-bit"
fi
if [[ "$CPU_ABIS" == *"x86_64"* || "$CPU_ABIS" == *"arm64-v8a"* ]]; then
SUPPORTS_64BIT=true
ui_print "- Device supports 64-bit"
fi
if [ "$SUPPORTS_32BIT" = true ]; then
mkdir "$MODPATH/lib"
fi
if [ "$SUPPORTS_64BIT" = true ]; then
mkdir "$MODPATH/lib64"
fi
if [ "$ARCH" = "x86" ] || [ "$ARCH" = "x64" ]; then
if [ "$SUPPORTS_32BIT" = true ]; then
ui_print "- Extracting x86 libraries"
extract "$ZIPFILE" 'bin/x86/zygiskd' "$MODPATH/bin" true
mv "$MODPATH/bin/zygiskd" "$MODPATH/bin/zygiskd32"
extract "$ZIPFILE" 'lib/x86/libzygisk.so' "$MODPATH/lib" true
extract "$ZIPFILE" 'lib/x86/libzygisk_ptrace.so' "$MODPATH/bin" true
mv "$MODPATH/bin/libzygisk_ptrace.so" "$MODPATH/bin/zygisk-ptrace32"
fi
if [ "$SUPPORTS_64BIT" = true ]; then
ui_print "- Extracting x64 libraries"
extract "$ZIPFILE" 'bin/x86_64/zygiskd' "$MODPATH/bin" true
mv "$MODPATH/bin/zygiskd" "$MODPATH/bin/zygiskd64"
extract "$ZIPFILE" 'lib/x86_64/libzygisk.so' "$MODPATH/lib64" true
extract "$ZIPFILE" 'lib/x86_64/libzygisk_ptrace.so' "$MODPATH/bin" true
mv "$MODPATH/bin/libzygisk_ptrace.so" "$MODPATH/bin/zygisk-ptrace64"
fi
extract "$ZIPFILE" 'machikado.x86' "$MODPATH" true
mv "$MODPATH/machikado.x86" "$MODPATH/machikado"
else
if [ "$SUPPORTS_32BIT" = true ]; then
ui_print "- Extracting arm libraries"
extract "$ZIPFILE" 'bin/armeabi-v7a/zygiskd' "$MODPATH/bin" true
mv "$MODPATH/bin/zygiskd" "$MODPATH/bin/zygiskd32"
extract "$ZIPFILE" 'lib/armeabi-v7a/libzygisk.so' "$MODPATH/lib" true
extract "$ZIPFILE" 'lib/armeabi-v7a/libzygisk_ptrace.so' "$MODPATH/bin" true
mv "$MODPATH/bin/libzygisk_ptrace.so" "$MODPATH/bin/zygisk-ptrace32"
fi
if [ "$SUPPORTS_64BIT" = true ]; then
ui_print "- Extracting arm64 libraries"
extract "$ZIPFILE" 'bin/arm64-v8a/zygiskd' "$MODPATH/bin" true
mv "$MODPATH/bin/zygiskd" "$MODPATH/bin/zygiskd64"
extract "$ZIPFILE" 'lib/arm64-v8a/libzygisk.so' "$MODPATH/lib64" true
extract "$ZIPFILE" 'lib/arm64-v8a/libzygisk_ptrace.so' "$MODPATH/bin" true
mv "$MODPATH/bin/libzygisk_ptrace.so" "$MODPATH/bin/zygisk-ptrace64"
fi
extract "$ZIPFILE" 'machikado.arm' "$MODPATH" true
mv "$MODPATH/machikado.arm" "$MODPATH/machikado"
@@ -148,8 +177,14 @@ fi
ui_print "- Setting permissions"
set_perm_recursive "$MODPATH/bin" 0 0 0755 0755
set_perm_recursive "$MODPATH/lib" 0 0 0755 0644 u:object_r:system_lib_file:s0
set_perm_recursive "$MODPATH/lib64" 0 0 0755 0644 u:object_r:system_lib_file:s0
if [ "$SUPPORTS_32BIT" = true ]; then
set_perm_recursive "$MODPATH/lib" 0 0 0755 0644 u:object_r:system_lib_file:s0
fi
if [ "$SUPPORTS_64BIT" = true ]; then
set_perm_recursive "$MODPATH/lib64" 0 0 0755 0644 u:object_r:system_lib_file:s0
fi
# If Huawei's Maple is enabled, system_server is created with a special way which is out of Zygisk's control
HUAWEI_MAPLE_ENABLED=$(grep_prop ro.maple.enable)

View File

@@ -46,5 +46,12 @@ if [ -f $MODDIR/lib/libzygisk.so ];then
chcon u:object_r:system_file:s0 $TMP_PATH/lib/libzygisk.so
fi
[ "$DEBUG" = true ] && export RUST_BACKTRACE=1
./bin/zygisk-ptrace64 monitor &
CPU_ABIS=$(getprop ro.product.cpu.abilist)
if [[ "$CPU_ABIS" == *"arm64-v8a"* || "$CPU_ABIS" == *"x86_64"* ]]; then
./bin/zygisk-ptrace64 monitor &
else
# INFO: Device is 32-bit only
./bin/zygisk-ptrace32 monitor &
fi

View File

@@ -10,6 +10,7 @@ allow zygote su {lnk_file file} read
allow zygote adb_data_file dir search
allow zygote adb_data_file file *
allow zygote proc file {read open}
allow zygote zygote process execmem
allow system_server system_server process execmem
allow zygote tmpfs file *

View File

@@ -49,7 +49,7 @@ enum Architecture {
static enum Architecture get_arch(void) {
char system_arch[32];
get_property("ro.product.cpu.abi", system_arch);
get_property("ro.product.cpu.abilist", 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);
@@ -255,7 +255,6 @@ static int spawn_companion(char *restrict argv[], char *restrict name, int lib_f
struct __attribute__((__packed__)) MsgHead {
unsigned int cmd;
int length;
char data[0];
};
/* WARNING: Dynamic memory based */
@@ -268,29 +267,20 @@ void zygiskd_start(char *restrict argv[]) {
struct root_impl impl;
get_impl(&impl);
if (impl.impl == None || impl.impl == Multiple) {
struct MsgHead *msg = NULL;
char *msg_data = NULL;
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");
if (impl.impl == None) msg_data = "Unsupported environment: Unknown root implementation";
else msg_data = "Unsupported environment: Multiple root implementations found";
return;
}
struct MsgHead msg = {
.cmd = DAEMON_SET_ERROR_INFO,
.length = (int)strlen(msg_data) + 1
};
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, &msg, sizeof(struct MsgHead));
unix_datagram_sendto(CONTROLLER_SOCKET, msg_data, (size_t)msg.length);
unix_datagram_sendto(CONTROLLER_SOCKET, (void *)msg, (size_t)((int)sizeof(struct MsgHead) + msg->length));
free(msg);
free(msg_data);
} else {
enum Architecture arch = get_arch();
load_modules(arch, &context);
@@ -337,13 +327,24 @@ void zygiskd_start(char *restrict argv[]) {
size_t msg_length = strlen("Root: , Modules: ") + strlen(impl_name) + module_list_len + 1;
struct MsgHead *msg = malloc(sizeof(struct MsgHead) + msg_length);
msg->length = snprintf(msg->data, msg_length, "Root: %s, Modules: %s", impl_name, module_list) + 1;
msg->cmd = DAEMON_SET_INFO;
struct MsgHead msg = {
.cmd = DAEMON_SET_INFO,
.length = (int)msg_length
};
unix_datagram_sendto(CONTROLLER_SOCKET, (void *)msg, (size_t)((int)sizeof(struct MsgHead) + msg->length));
char *msg_data = malloc(msg_length);
if (msg_data == NULL) {
LOGE("Failed allocating memory for message data.\n");
free(msg);
return;
}
snprintf(msg_data, msg_length, "Root: %s, Modules: %s", impl_name, module_list);
unix_datagram_sendto(CONTROLLER_SOCKET, &msg, sizeof(struct MsgHead));
unix_datagram_sendto(CONTROLLER_SOCKET, msg_data, msg_length);
free(msg_data);
free(module_list);
}
@@ -379,8 +380,12 @@ void zygiskd_start(char *restrict argv[]) {
switch (action) {
case PingHeartbeat: {
enum DaemonSocketAction msgr = ZYGOTE_INJECTED;
unix_datagram_sendto(CONTROLLER_SOCKET, &msgr, sizeof(enum DaemonSocketAction));
struct MsgHead msg = {
.cmd = ZYGOTE_INJECTED,
.length = 0
};
unix_datagram_sendto(CONTROLLER_SOCKET, &msg, sizeof(struct MsgHead));
break;
}
@@ -395,8 +400,12 @@ void zygiskd_start(char *restrict argv[]) {
break;
}
case SystemServerStarted: {
enum DaemonSocketAction msgr = SYSTEM_SERVER_STARTED;
unix_datagram_sendto(CONTROLLER_SOCKET, &msgr, sizeof(enum DaemonSocketAction));
struct MsgHead msg = {
.cmd = SYSTEM_SERVER_STARTED,
.length = 0
};
unix_datagram_sendto(CONTROLLER_SOCKET, &msg, sizeof(struct MsgHead));
if (impl.impl == None || impl.impl == Multiple) {
LOGI("Unsupported environment detected. Exiting.\n");