mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-06-13 05:37:47 +02:00
New method of communication
Introduce a new communication method between Magisk and Magisk Manager. Magisk used to hardcode classnames and send broadcast/start activities to specific components. This new method makes no assumption of any class names, so Magisk Manager can easily be fully obfuscated. In addition, the new method connects Magisk and Magisk Manager with random abstract Linux sockets instead of socket files in filesystems, bypassing file system complexities (selinux, permissions and such)
This commit is contained in:
@ -111,9 +111,9 @@ void main_daemon() {
|
||||
check_and_start_logger();
|
||||
|
||||
struct sockaddr_un sun;
|
||||
fd = setup_socket(&sun, MAIN_DAEMON);
|
||||
|
||||
if (xbind(fd, (struct sockaddr*) &sun, sizeof(sun.sun_family) + strlen(sun.sun_path + 1) + 1))
|
||||
socklen_t len = setup_sockaddr(&sun, MAIN_DAEMON);
|
||||
fd = xsocket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
|
||||
if (xbind(fd, (struct sockaddr*) &sun, len))
|
||||
exit(1);
|
||||
xlisten(fd, 10);
|
||||
LOGI("Magisk v" xstr(MAGISK_VERSION) "(" xstr(MAGISK_VER_CODE) ") daemon started\n");
|
||||
@ -148,8 +148,8 @@ void main_daemon() {
|
||||
/* Connect the daemon, set sockfd, and return if new daemon is spawned */
|
||||
int connect_daemon2(daemon_t d, int *sockfd) {
|
||||
struct sockaddr_un sun;
|
||||
*sockfd = setup_socket(&sun, d);
|
||||
socklen_t len = sizeof(sun.sun_family) + strlen(sun.sun_path + 1) + 1;
|
||||
socklen_t len = setup_sockaddr(&sun, d);
|
||||
*sockfd = xsocket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
|
||||
if (connect(*sockfd, (struct sockaddr*) &sun, len)) {
|
||||
if (getuid() != UID_ROOT || getgid() != UID_ROOT) {
|
||||
fprintf(stderr, "No daemon is currently running!\n");
|
||||
|
@ -123,8 +123,9 @@ int check_and_start_logger() {
|
||||
void log_daemon() {
|
||||
setsid();
|
||||
struct sockaddr_un sun;
|
||||
sockfd = setup_socket(&sun, LOG_DAEMON);
|
||||
if (xbind(sockfd, (struct sockaddr*) &sun, sizeof(sun.sun_family) + strlen(sun.sun_path + 1) + 1))
|
||||
socklen_t len = setup_sockaddr(&sun, LOG_DAEMON);
|
||||
sockfd = xsocket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
|
||||
if (xbind(sockfd, (struct sockaddr*) &sun, len))
|
||||
exit(1);
|
||||
xlisten(sockfd, 10);
|
||||
LOGI("Magisk v" xstr(MAGISK_VERSION) "(" xstr(MAGISK_VER_CODE) ") logger started\n");
|
||||
|
@ -2,18 +2,18 @@
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <endian.h>
|
||||
|
||||
#include "daemon.h"
|
||||
#include "logging.h"
|
||||
#include "utils.h"
|
||||
#include "magisk.h"
|
||||
|
||||
/* Setup the address and return socket fd */
|
||||
int setup_socket(struct sockaddr_un *sun, daemon_t d) {
|
||||
int fd = xsocket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
|
||||
#define ABS_SOCKET_LEN(sun) (sizeof(sun->sun_family) + strlen(sun->sun_path + 1) + 1)
|
||||
|
||||
socklen_t setup_sockaddr(struct sockaddr_un *sun, daemon_t d) {
|
||||
memset(sun, 0, sizeof(*sun));
|
||||
sun->sun_family = AF_LOCAL;
|
||||
sun->sun_path[0] = '\0';
|
||||
const char *name;
|
||||
switch (d) {
|
||||
case MAIN_DAEMON:
|
||||
@ -24,9 +24,39 @@ int setup_socket(struct sockaddr_un *sun, daemon_t d) {
|
||||
break;
|
||||
}
|
||||
strcpy(sun->sun_path + 1, name);
|
||||
return ABS_SOCKET_LEN(sun);
|
||||
}
|
||||
|
||||
int create_rand_socket(struct sockaddr_un *sun) {
|
||||
memset(sun, 0, sizeof(*sun));
|
||||
sun->sun_family = AF_LOCAL;
|
||||
gen_rand_str(sun->sun_path + 1, 9);
|
||||
int fd = xsocket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
|
||||
xbind(fd, (struct sockaddr*) sun, ABS_SOCKET_LEN(sun));
|
||||
xlisten(fd, 1);
|
||||
return fd;
|
||||
}
|
||||
|
||||
int socket_accept(int serv_fd, int timeout) {
|
||||
struct timeval tv;
|
||||
fd_set fds;
|
||||
int rc;
|
||||
|
||||
tv.tv_sec = timeout;
|
||||
tv.tv_usec = 0;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(serv_fd, &fds);
|
||||
do {
|
||||
rc = select(serv_fd + 1, &fds, NULL, NULL, &tv);
|
||||
} while (rc < 0 && errno == EINTR);
|
||||
if (rc < 1) {
|
||||
PLOGE("select");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
return xaccept4(serv_fd, NULL, NULL, SOCK_CLOEXEC);
|
||||
}
|
||||
|
||||
/*
|
||||
* Receive a file descriptor from a Unix socket.
|
||||
* Contributed by @mkasick
|
||||
@ -136,26 +166,59 @@ int read_int(int fd) {
|
||||
return val;
|
||||
}
|
||||
|
||||
int read_int_be(int fd) {
|
||||
uint32_t val;
|
||||
xxread(fd, &val, sizeof(val));
|
||||
return ntohl(val);
|
||||
}
|
||||
|
||||
void write_int(int fd, int val) {
|
||||
if (fd < 0) return;
|
||||
xwrite(fd, &val, sizeof(int));
|
||||
}
|
||||
|
||||
char* read_string(int fd) {
|
||||
int len = read_int(fd);
|
||||
if (len > PATH_MAX || len < 0) {
|
||||
LOGE("invalid string length %d", len);
|
||||
exit(1);
|
||||
}
|
||||
void write_int_be(int fd, int val) {
|
||||
uint32_t nl = htonl(val);
|
||||
xwrite(fd, &nl, sizeof(nl));
|
||||
}
|
||||
|
||||
static char *rd_str(int fd, int len) {
|
||||
char* val = xmalloc(sizeof(char) * (len + 1));
|
||||
xxread(fd, val, len);
|
||||
val[len] = '\0';
|
||||
return val;
|
||||
}
|
||||
|
||||
void write_string(int fd, const char* val) {
|
||||
char* read_string(int fd) {
|
||||
int len = read_int(fd);
|
||||
return rd_str(fd, len);
|
||||
}
|
||||
|
||||
char* read_string_be(int fd) {
|
||||
int len = read_int_be(fd);
|
||||
return rd_str(fd, len);
|
||||
}
|
||||
|
||||
void write_string(int fd, const char *val) {
|
||||
if (fd < 0) return;
|
||||
int len = strlen(val);
|
||||
write_int(fd, len);
|
||||
xwrite(fd, val, len);
|
||||
}
|
||||
|
||||
void write_string_be(int fd, const char *val) {
|
||||
int len = strlen(val);
|
||||
write_int_be(fd, len);
|
||||
xwrite(fd, val, len);
|
||||
}
|
||||
|
||||
void write_key_value(int fd, const char *key, const char *val) {
|
||||
write_string_be(fd, key);
|
||||
write_string_be(fd, val);
|
||||
}
|
||||
|
||||
void write_key_token(int fd, const char *key, int tok) {
|
||||
char val[16];
|
||||
sprintf(val, "%d", tok);
|
||||
write_key_value(fd, key, val);
|
||||
}
|
||||
|
Reference in New Issue
Block a user