Integrate MagiskHide into Magisk Daemon
This commit is contained in:
parent
054a1e5ea4
commit
144ff5e716
@ -37,7 +37,7 @@ LOCAL_SRC_FILES := \
|
|||||||
# su/utils.c \
|
# su/utils.c \
|
||||||
# su/pts.c
|
# su/pts.c
|
||||||
|
|
||||||
LOCAL_CFLAGS := -Wno-implicit-exception-spec-mismatch
|
LOCAL_CFLAGS := -Wno-implicit-exception-spec-mismatch -DDEBUG
|
||||||
LOCAL_LDLIBS := -llog
|
LOCAL_LDLIBS := -llog
|
||||||
|
|
||||||
include $(BUILD_EXECUTABLE)
|
include $(BUILD_EXECUTABLE)
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
@ -18,12 +19,33 @@
|
|||||||
#include "daemon.h"
|
#include "daemon.h"
|
||||||
|
|
||||||
static void request_handler(int client) {
|
static void request_handler(int client) {
|
||||||
/* TODO: Put all function entrypoints here
|
client_request req = read_int(client);
|
||||||
it'll currently just log the input string */
|
char *s;
|
||||||
char *s = read_string(client);
|
int pid, status, code;
|
||||||
|
switch (req) {
|
||||||
|
case LAUNCH_MAGISKHIDE:
|
||||||
|
launch_magiskhide(client);
|
||||||
|
break;
|
||||||
|
case STOP_MAGISKHIDE:
|
||||||
|
stop_magiskhide(client);
|
||||||
|
break;
|
||||||
|
case ADD_HIDELIST:
|
||||||
|
// TODO: Add hidelist
|
||||||
|
break;
|
||||||
|
case RM_HIDELIST:
|
||||||
|
// TODO: Remove hidelist
|
||||||
|
break;
|
||||||
|
case SUPERUSER:
|
||||||
|
// TODO: Run su
|
||||||
|
break;
|
||||||
|
case TEST:
|
||||||
|
s = read_string(client);
|
||||||
|
LOGI("%s\n", s);
|
||||||
|
free(s);
|
||||||
|
write_int(client, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
close(client);
|
close(client);
|
||||||
LOGI("%s\n", s);
|
|
||||||
free(s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup the address and return socket fd */
|
/* Setup the address and return socket fd */
|
||||||
@ -39,10 +61,14 @@ static int setup_socket(struct sockaddr_un *sun) {
|
|||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void do_nothing() {}
|
||||||
|
|
||||||
void start_daemon() {
|
void start_daemon() {
|
||||||
// Launch the daemon, create new session, set proper context
|
// Launch the daemon, create new session, set proper context
|
||||||
if (getuid() != AID_ROOT || getgid() != AID_ROOT) {
|
if (getuid() != AID_ROOT || getgid() != AID_ROOT) {
|
||||||
PLOGE("daemon requires root. uid/gid not root");
|
fprintf(stderr, "Starting daemon requires root: %s\n", strerror(errno));
|
||||||
|
PLOGE("start daemon");
|
||||||
}
|
}
|
||||||
switch (fork()) {
|
switch (fork()) {
|
||||||
case -1:
|
case -1:
|
||||||
@ -63,6 +89,12 @@ void start_daemon() {
|
|||||||
|
|
||||||
// Change process name
|
// Change process name
|
||||||
strcpy(argv0, "magisk_daemon");
|
strcpy(argv0, "magisk_daemon");
|
||||||
|
// The root daemon should not do anything if an error occurs
|
||||||
|
// It should stay intact in any circumstances
|
||||||
|
err_handler = do_nothing;
|
||||||
|
|
||||||
|
// Start log monitor
|
||||||
|
monitor_logs();
|
||||||
|
|
||||||
// Loop forever to listen to requests
|
// Loop forever to listen to requests
|
||||||
while(1) {
|
while(1) {
|
||||||
|
@ -1,7 +1,24 @@
|
|||||||
/* daemon.h - Utility functions for daemon-client communication
|
/* daemon.h - Utility functions for daemon-client communication
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// Commands require connecting to daemon
|
||||||
|
typedef enum {
|
||||||
|
LAUNCH_MAGISKHIDE,
|
||||||
|
STOP_MAGISKHIDE,
|
||||||
|
ADD_HIDELIST,
|
||||||
|
RM_HIDELIST,
|
||||||
|
SUPERUSER,
|
||||||
|
TEST
|
||||||
|
} client_request;
|
||||||
|
|
||||||
|
// daemon.c
|
||||||
|
|
||||||
|
void start_daemon();
|
||||||
|
int connect_daemon();
|
||||||
|
|
||||||
// socket_trans.c
|
// socket_trans.c
|
||||||
|
|
||||||
int recv_fd(int sockfd);
|
int recv_fd(int sockfd);
|
||||||
void send_fd(int sockfd, int fd);
|
void send_fd(int sockfd, int fd);
|
||||||
int read_int(int fd);
|
int read_int(int fd);
|
||||||
|
23
jni/magisk.h
23
jni/magisk.h
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <pthread.h>
|
||||||
#include <android/log.h>
|
#include <android/log.h>
|
||||||
|
|
||||||
#define AID_SHELL (get_shell_uid())
|
#define AID_SHELL (get_shell_uid())
|
||||||
@ -21,6 +22,13 @@
|
|||||||
|
|
||||||
#define LOG_TAG "Magisk"
|
#define LOG_TAG "Magisk"
|
||||||
|
|
||||||
|
// Global handler for PLOGE
|
||||||
|
extern __thread void (*err_handler)(void);
|
||||||
|
|
||||||
|
// Two common error handlers
|
||||||
|
void exit_proc();
|
||||||
|
void exit_thread();
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
|
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
@ -30,14 +38,14 @@
|
|||||||
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
|
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
|
||||||
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
|
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
|
||||||
|
|
||||||
#define PLOGE(fmt, args...) LOGE(fmt " failed with %d: %s", ##args, errno, strerror(errno)); exit(1)
|
#define PLOGE(fmt, args...) LOGE(fmt " failed with %d: %s", ##args, errno, strerror(errno)); err_handler()
|
||||||
#define PLOGEV(fmt, err, args...) LOGE(fmt " failed with %d: %s", ##args, err, strerror(err)); exit(1)
|
|
||||||
|
|
||||||
void stub(const char *fmt, ...);
|
void stub(const char *fmt, ...);
|
||||||
|
|
||||||
// Global buffer (only for main thread!!)
|
// Global buffer (only for main thread!!)
|
||||||
#define BUF_SIZE 4096
|
#define BUF_SIZE 4096
|
||||||
extern char magiskbuf[BUF_SIZE];
|
extern char magiskbuf[BUF_SIZE];
|
||||||
|
|
||||||
extern char *argv0; /* For changing process name */
|
extern char *argv0; /* For changing process name */
|
||||||
|
|
||||||
// Multi-call entrypoints
|
// Multi-call entrypoints
|
||||||
@ -53,19 +61,12 @@ int resetprop_main(int argc, char *argv[]);
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*****************
|
|
||||||
* Magisk Daemon *
|
|
||||||
*****************/
|
|
||||||
|
|
||||||
void start_daemon();
|
|
||||||
int connect_daemon();
|
|
||||||
|
|
||||||
/**************
|
/**************
|
||||||
* MagiskHide *
|
* MagiskHide *
|
||||||
**************/
|
**************/
|
||||||
|
|
||||||
void launch_magiskhide();
|
void launch_magiskhide(int client);
|
||||||
void stop_magiskhide();
|
void stop_magiskhide(int client);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "magiskhide.h"
|
#include "magiskhide.h"
|
||||||
|
|
||||||
static int isMocked = 0;
|
static int isMocked = 0, pid;
|
||||||
|
|
||||||
static void manage_selinux() {
|
static void manage_selinux() {
|
||||||
if (isMocked) return;
|
if (isMocked) return;
|
||||||
@ -43,23 +43,36 @@ static void lazy_unmount(const char* mountpoint) {
|
|||||||
LOGI("hide_daemon: Unmount Failed (%s)\n", mountpoint);
|
LOGI("hide_daemon: Unmount Failed (%s)\n", mountpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hide_daemon() {
|
static void hide_daemon_err() {
|
||||||
|
LOGD("hide_daemon: error occured, stopping magiskhide services\n");
|
||||||
|
// Resume process if possible
|
||||||
|
kill(pid, SIGCONT);
|
||||||
|
int err = 1;
|
||||||
|
write(sv[1], &err, sizeof(err));
|
||||||
|
_exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int hide_daemon() {
|
||||||
// Fork to a new process
|
// Fork to a new process
|
||||||
switch(fork()) {
|
hide_pid = fork();
|
||||||
|
switch(hide_pid) {
|
||||||
case -1:
|
case -1:
|
||||||
PLOGE("fork");
|
PLOGE("fork");
|
||||||
|
return 1;
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
close(pipefd[1]);
|
close(sv[0]);
|
||||||
|
|
||||||
// Set the process name
|
// Set the process name
|
||||||
strcpy(argv0, "magiskhide_daemon");
|
strcpy(argv0, "magiskhide_daemon");
|
||||||
|
// When an error occurs, report its failure to main process
|
||||||
|
err_handler = hide_daemon_err;
|
||||||
|
|
||||||
int pid, fd;
|
int fd;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char cache_block[256], *line;
|
char cache_block[256], *line;
|
||||||
struct vector mount_list;
|
struct vector mount_list;
|
||||||
@ -67,9 +80,12 @@ void hide_daemon() {
|
|||||||
cache_block[0] = '\0';
|
cache_block[0] = '\0';
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
xxread(pipefd[0], &pid, sizeof(pid));
|
xxread(sv[1], &pid, sizeof(pid));
|
||||||
// Termination called
|
// Termination called
|
||||||
if(pid == -1) exit(0);
|
if(pid == -1) {
|
||||||
|
LOGD("hide_daemon: received termination request\n");
|
||||||
|
_exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
snprintf(magiskbuf, BUF_SIZE, "/proc/%d/ns/mnt", pid);
|
snprintf(magiskbuf, BUF_SIZE, "/proc/%d/ns/mnt", pid);
|
||||||
if(access(magiskbuf, F_OK) == -1) continue; // Maybe process died..
|
if(access(magiskbuf, F_OK) == -1) continue; // Maybe process died..
|
||||||
@ -95,7 +111,7 @@ void hide_daemon() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// First unmount the dummy skeletons, cache mounts, and /sbin links
|
// First unmount the dummy skeletons, cache mounts, and /sbin links
|
||||||
vec_for_each_r(&mount_list, line) {
|
vec_for_each_r(&mount_list, line) {
|
||||||
if (strstr(line, "tmpfs /system") || strstr(line, "tmpfs /vendor") || strstr(line, "tmpfs /sbin")
|
if (strstr(line, "tmpfs /system") || strstr(line, "tmpfs /vendor") || strstr(line, "tmpfs /sbin")
|
||||||
@ -125,6 +141,10 @@ void hide_daemon() {
|
|||||||
|
|
||||||
// All done, send resume signal
|
// All done, send resume signal
|
||||||
kill(pid, SIGCONT);
|
kill(pid, SIGCONT);
|
||||||
|
|
||||||
|
// Tell main process all is well
|
||||||
|
pid = 0;
|
||||||
|
xwrite(sv[1], &pid, sizeof(pid));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should never go here
|
// Should never go here
|
||||||
|
@ -8,38 +8,67 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include "magisk.h"
|
#include "magisk.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "magiskhide.h"
|
#include "magiskhide.h"
|
||||||
|
#include "daemon.h"
|
||||||
|
|
||||||
int pipefd[2];
|
int sv[2], hide_pid;
|
||||||
struct vector *hide_list, *new_list;
|
struct vector *hide_list, *new_list;
|
||||||
|
|
||||||
|
int isEnabled = 0;
|
||||||
static pthread_t proc_monitor_thread;
|
static pthread_t proc_monitor_thread;
|
||||||
|
|
||||||
static void kill_proc(int pid) {
|
void kill_proc(int pid) {
|
||||||
kill(pid, SIGTERM);
|
kill(pid, SIGTERM);
|
||||||
}
|
}
|
||||||
|
|
||||||
void launch_magiskhide() {
|
static void usage(char *arg0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s [--options [arguments...] ]\n\n"
|
||||||
|
"Options:\n"
|
||||||
|
" --enable: Start the magiskhide daemon\n"
|
||||||
|
" --disable: Stop the magiskhide daemon\n"
|
||||||
|
" --add <process name>: Add <process name> to the list\n"
|
||||||
|
" --rm <process name>: Remove <process name> from the list\n"
|
||||||
|
" --ls: Print out the current hide list\n"
|
||||||
|
, arg0);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void launch_magiskhide(int client) {
|
||||||
|
if (isEnabled) {
|
||||||
|
write_int(client, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* The setns system call do not support multithread processes
|
* The setns system call do not support multithread processes
|
||||||
* We have to fork a new process, and communicate with pipe
|
* We have to fork a new process, and communicate with pipe
|
||||||
*/
|
*/
|
||||||
|
|
||||||
xpipe(pipefd);
|
LOGI("* Starting MagiskHide\n");
|
||||||
|
|
||||||
|
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sv) == -1)
|
||||||
|
goto error;
|
||||||
|
|
||||||
// Launch the hide daemon
|
// Launch the hide daemon
|
||||||
hide_daemon();
|
if (hide_daemon())
|
||||||
|
goto error;
|
||||||
|
|
||||||
close(pipefd[0]);
|
close(sv[1]);
|
||||||
|
|
||||||
// Initialize the hide list
|
// Initialize the hide list
|
||||||
hide_list = new_list = malloc(sizeof(*hide_list));
|
hide_list = new_list = xmalloc(sizeof(*hide_list));
|
||||||
|
if (hide_list == NULL)
|
||||||
|
goto error;
|
||||||
vec_init(hide_list);
|
vec_init(hide_list);
|
||||||
FILE *fp = xfopen(HIDELIST, "r");
|
FILE *fp = xfopen(HIDELIST, "r");
|
||||||
|
if (fp == NULL)
|
||||||
|
goto error;
|
||||||
file_to_vector(hide_list, fp);
|
file_to_vector(hide_list, fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
char *line;
|
char *line;
|
||||||
@ -49,20 +78,66 @@ void launch_magiskhide() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Start a new thread to monitor processes
|
// Start a new thread to monitor processes
|
||||||
pthread_create(&proc_monitor_thread, NULL, proc_monitor, NULL);
|
if (xpthread_create(&proc_monitor_thread, NULL, proc_monitor, NULL))
|
||||||
pthread_join(proc_monitor_thread, NULL);
|
goto error;
|
||||||
|
|
||||||
|
isEnabled = 1;
|
||||||
|
write_int(client, 0);
|
||||||
|
return;
|
||||||
|
error:
|
||||||
|
write_int(client, 1);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void stop_magiskhide() {
|
void stop_magiskhide(int client) {
|
||||||
|
if (!isEnabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
LOGI("* Stopping MagiskHide\n");
|
||||||
|
|
||||||
int kill = -1;
|
int kill = -1;
|
||||||
// Terminate hide daemon
|
// Terminate hide daemon
|
||||||
xwrite(pipefd[1], &kill, sizeof(kill));
|
write(sv[0], &kill, sizeof(kill));
|
||||||
|
close(sv[0]);
|
||||||
|
waitpid(hide_pid, NULL, 0);
|
||||||
// Stop process monitor
|
// Stop process monitor
|
||||||
pthread_kill(proc_monitor_thread, SIGUSR1);
|
pthread_kill(proc_monitor_thread, SIGUSR1);
|
||||||
pthread_join(proc_monitor_thread, NULL);
|
pthread_join(proc_monitor_thread, NULL);
|
||||||
|
|
||||||
|
isEnabled = 0;
|
||||||
|
write_int(client, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int magiskhide_main(int argc, char *argv[]) {
|
int magiskhide_main(int argc, char *argv[]) {
|
||||||
launch_magiskhide();
|
if (argc < 2) {
|
||||||
return 0;
|
usage(argv[0]);
|
||||||
|
}
|
||||||
|
client_request req;
|
||||||
|
if (strcmp(argv[1], "--enable") == 0) {
|
||||||
|
req = LAUNCH_MAGISKHIDE;
|
||||||
|
} else if (strcmp(argv[1], "--disable") == 0) {
|
||||||
|
req = STOP_MAGISKHIDE;
|
||||||
|
} else if (strcmp(argv[1], "--add") == 0 && argc > 2) {
|
||||||
|
req = ADD_HIDELIST;
|
||||||
|
} else if (strcmp(argv[1], "--rm") == 0 && argc > 2) {
|
||||||
|
req = RM_HIDELIST;
|
||||||
|
} else if (strcmp(argv[1], "--ls") == 0) {
|
||||||
|
FILE *fp = xfopen(HIDELIST, "r");
|
||||||
|
while (fgets(magiskbuf, BUF_SIZE, fp)) {
|
||||||
|
printf("%s", magiskbuf);
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int fd = connect_daemon();
|
||||||
|
write_int(fd, req);
|
||||||
|
if (req == ADD_HIDELIST || req == RM_HIDELIST) {
|
||||||
|
write_string(fd, argv[2]);
|
||||||
|
}
|
||||||
|
int code = read_int(fd);
|
||||||
|
close(fd);
|
||||||
|
if (code) {
|
||||||
|
fprintf(stderr, "Error occured in MagiskHide daemon\n");
|
||||||
|
}
|
||||||
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -6,13 +6,16 @@
|
|||||||
#define ENFORCE_FILE "/sys/fs/selinux/enforce"
|
#define ENFORCE_FILE "/sys/fs/selinux/enforce"
|
||||||
#define POLICY_FILE "/sys/fs/selinux/policy"
|
#define POLICY_FILE "/sys/fs/selinux/policy"
|
||||||
|
|
||||||
|
// Kill process
|
||||||
|
void kill_proc(int pid);
|
||||||
|
|
||||||
// Hide daemon
|
// Hide daemon
|
||||||
void hide_daemon();
|
int hide_daemon();
|
||||||
|
|
||||||
// Process monitor
|
// Process monitor
|
||||||
void *proc_monitor(void *args);
|
void *proc_monitor(void *args);
|
||||||
|
|
||||||
extern int pipefd[2];
|
extern int sv[2], hide_pid, isEnabled;
|
||||||
extern struct vector *hide_list, *new_list;
|
extern struct vector *hide_list, *new_list;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -11,15 +11,12 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
#include "magisk.h"
|
#include "magisk.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "magiskhide.h"
|
#include "magiskhide.h"
|
||||||
|
|
||||||
/* WTF... the macro in the NDK pthread.h is broken.... */
|
|
||||||
#define pthread_cleanup_push_fix(routine, arg) \
|
|
||||||
pthread_cleanup_push(routine, arg) } while(0);
|
|
||||||
|
|
||||||
static int zygote_num = 0;
|
static int zygote_num = 0;
|
||||||
static char init_ns[32], zygote_ns[2][32];
|
static char init_ns[32], zygote_ns[2][32];
|
||||||
|
|
||||||
@ -32,15 +29,21 @@ static void read_namespace(const int pid, char* target, const size_t size) {
|
|||||||
|
|
||||||
// Workaround for the lack of pthread_cancel
|
// Workaround for the lack of pthread_cancel
|
||||||
static void quit_pthread(int sig) {
|
static void quit_pthread(int sig) {
|
||||||
pthread_exit(NULL);
|
LOGD("proc_monitor: running cleanup\n");
|
||||||
}
|
char *line;
|
||||||
|
vec_for_each(hide_list, line) {
|
||||||
static void cleanup_handler(void *arg) {
|
ps_filter_proc_name(line, kill_proc);
|
||||||
|
}
|
||||||
vec_deep_destroy(hide_list);
|
vec_deep_destroy(hide_list);
|
||||||
vec_deep_destroy(new_list);
|
|
||||||
free(hide_list);
|
free(hide_list);
|
||||||
free(new_list);
|
if (new_list != hide_list) {
|
||||||
|
vec_deep_destroy(new_list);
|
||||||
|
free(new_list);
|
||||||
|
}
|
||||||
hide_list = new_list = NULL;
|
hide_list = new_list = NULL;
|
||||||
|
isEnabled = 0;
|
||||||
|
LOGD("proc_monitor: terminating...\n");
|
||||||
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void store_zygote_ns(int pid) {
|
static void store_zygote_ns(int pid) {
|
||||||
@ -51,10 +54,21 @@ static void store_zygote_ns(int pid) {
|
|||||||
++zygote_num;
|
++zygote_num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void proc_monitor_err() {
|
||||||
|
LOGD("proc_monitor: error occured, stopping magiskhide services\n");
|
||||||
|
int kill = -1;
|
||||||
|
// If process monitor dies, kill hide daemon too
|
||||||
|
write(sv[0], &kill, sizeof(kill));
|
||||||
|
close(sv[0]);
|
||||||
|
waitpid(hide_pid, NULL, 0);
|
||||||
|
quit_pthread(SIGUSR1);
|
||||||
|
}
|
||||||
|
|
||||||
void *proc_monitor(void *args) {
|
void *proc_monitor(void *args) {
|
||||||
// Register the cancel signal
|
// Register the cancel signal
|
||||||
signal(SIGUSR1, quit_pthread);
|
signal(SIGUSR1, quit_pthread);
|
||||||
pthread_cleanup_push_fix(cleanup_handler, NULL);
|
// The error handler should only exit the thread, not the whole process
|
||||||
|
err_handler = proc_monitor_err;
|
||||||
|
|
||||||
int pid;
|
int pid;
|
||||||
char buffer[512];
|
char buffer[512];
|
||||||
@ -106,6 +120,8 @@ void *proc_monitor(void *args) {
|
|||||||
hide_list = new_list;
|
hide_list = new_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
vec_for_each(hide_list, line) {
|
vec_for_each(hide_list, line) {
|
||||||
if (strcmp(processName, line) == 0) {
|
if (strcmp(processName, line) == 0) {
|
||||||
read_namespace(pid, buffer, 32);
|
read_namespace(pid, buffer, 32);
|
||||||
@ -121,13 +137,19 @@ void *proc_monitor(void *args) {
|
|||||||
if (ret) break;
|
if (ret) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
// Send pause signal ASAP
|
// Send pause signal ASAP
|
||||||
if (kill(pid, SIGSTOP) == -1) continue;
|
if (kill(pid, SIGSTOP) == -1) continue;
|
||||||
|
|
||||||
LOGI("proc_monitor: %s(PID=%d ns=%s)\n", processName, pid, buffer);
|
LOGI("proc_monitor: %s(PID=%d ns=%s)\n", processName, pid, buffer);
|
||||||
|
|
||||||
// Unmount start
|
// Unmount start
|
||||||
xwrite(pipefd[1], &pid, sizeof(pid));
|
xwrite(sv[0], &pid, sizeof(pid));
|
||||||
|
|
||||||
|
// Get the hide daemon return code
|
||||||
|
xxread(sv[0], &ret, sizeof(ret));
|
||||||
|
LOGD("proc_monitor: hide daemon response code: %d\n", ret);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -135,10 +157,15 @@ void *proc_monitor(void *args) {
|
|||||||
vec_deep_destroy(temp);
|
vec_deep_destroy(temp);
|
||||||
free(temp);
|
free(temp);
|
||||||
}
|
}
|
||||||
|
if (ret) {
|
||||||
|
// Wait hide process to kill itself
|
||||||
|
waitpid(hide_pid, NULL, 0);
|
||||||
|
quit_pthread(SIGUSR1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should never be here
|
// Should never be here
|
||||||
pclose(p);
|
pclose(p);
|
||||||
quit_pthread(SIGUSR1);
|
pthread_exit(NULL);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
20
jni/main.c
20
jni/main.c
@ -1,6 +1,9 @@
|
|||||||
/* main.c - The entry point, should be multi-call
|
/* main.c - The entry point, should be multi-call
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "magisk.h"
|
#include "magisk.h"
|
||||||
#include "daemon.h"
|
#include "daemon.h"
|
||||||
@ -10,8 +13,22 @@ char *argv0;
|
|||||||
|
|
||||||
void stub(const char *fmt, ...) {}
|
void stub(const char *fmt, ...) {}
|
||||||
|
|
||||||
|
// Global error hander function
|
||||||
|
// Should be changed each thread/process
|
||||||
|
__thread void (*err_handler)(void);
|
||||||
|
|
||||||
|
void exit_proc() {
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void exit_thread() {
|
||||||
|
pthread_exit(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
argv0 = argv[0];
|
argv0 = argv[0];
|
||||||
|
// Exit the whole app if error occurs by default
|
||||||
|
err_handler = exit_proc;
|
||||||
char * arg = strrchr(argv[0], '/');
|
char * arg = strrchr(argv[0], '/');
|
||||||
if (arg) ++arg;
|
if (arg) ++arg;
|
||||||
if (strcmp(arg, "magisk") == 0) {
|
if (strcmp(arg, "magisk") == 0) {
|
||||||
@ -27,8 +44,9 @@ int main(int argc, char *argv[]) {
|
|||||||
} else if (strcmp(argv[1], "--test") == 0) {
|
} else if (strcmp(argv[1], "--test") == 0) {
|
||||||
// Temporary testing entry
|
// Temporary testing entry
|
||||||
int fd = connect_daemon();
|
int fd = connect_daemon();
|
||||||
|
write_int(fd, TEST);
|
||||||
write_string(fd, argv[2]);
|
write_string(fd, argv[2]);
|
||||||
return 0;
|
return read_int(fd);
|
||||||
} else {
|
} else {
|
||||||
// It's calling applets
|
// It's calling applets
|
||||||
--argc;
|
--argc;
|
||||||
|
@ -12,8 +12,8 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
static void *logger_thread(void *args) {
|
static void *logger_thread(void *args) {
|
||||||
rename("/cache/magisk.log", "/cache/last_magisk.log");
|
// rename("/cache/magisk.log", "/cache/last_magisk.log");
|
||||||
FILE *logfile = xfopen("/cache/magisk.log", "w");
|
FILE *logfile = xfopen("/cache/magisk_test.log", "w");
|
||||||
// Disable buffering
|
// Disable buffering
|
||||||
setbuf(logfile, NULL);
|
setbuf(logfile, NULL);
|
||||||
// Start logcat
|
// Start logcat
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#include <pthread.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
|
||||||
@ -34,6 +35,9 @@ void *xcalloc(size_t nmemb, size_t size);
|
|||||||
void *xrealloc(void *ptr, size_t size);
|
void *xrealloc(void *ptr, size_t size);
|
||||||
ssize_t xsendmsg(int sockfd, const struct msghdr *msg, int flags);
|
ssize_t xsendmsg(int sockfd, const struct msghdr *msg, int flags);
|
||||||
ssize_t xrecvmsg(int sockfd, struct msghdr *msg, int flags);
|
ssize_t xrecvmsg(int sockfd, struct msghdr *msg, int flags);
|
||||||
|
int xpthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||||
|
void *(*start_routine) (void *), void *arg);
|
||||||
|
int xsocketpair(int domain, int type, int protocol, int sv[2]);
|
||||||
|
|
||||||
// log_monitor.c
|
// log_monitor.c
|
||||||
|
|
||||||
@ -48,4 +52,4 @@ ssize_t fdreadline(int fd, char *buf, size_t size);
|
|||||||
void ps(void (*func)(int));
|
void ps(void (*func)(int));
|
||||||
void ps_filter_proc_name(const char *filter, void (*func)(int));
|
void ps_filter_proc_name(const char *filter, void (*func)(int));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -39,10 +39,11 @@ int xopen(const char *pathname, int flags) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ssize_t xwrite(int fd, const void *buf, size_t count) {
|
ssize_t xwrite(int fd, const void *buf, size_t count) {
|
||||||
if (count != write(fd, buf, count)) {
|
int ret = write(fd, buf, count);
|
||||||
|
if (count != ret) {
|
||||||
PLOGE("write");
|
PLOGE("write");
|
||||||
}
|
}
|
||||||
return count;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read error other than EOF
|
// Read error other than EOF
|
||||||
@ -56,24 +57,27 @@ ssize_t xread(int fd, void *buf, size_t count) {
|
|||||||
|
|
||||||
// Read exact same size as count
|
// Read exact same size as count
|
||||||
ssize_t xxread(int fd, void *buf, size_t count) {
|
ssize_t xxread(int fd, void *buf, size_t count) {
|
||||||
if (count != read(fd, buf, count)) {
|
int ret = read(fd, buf, count);
|
||||||
|
if (count != ret) {
|
||||||
PLOGE("read");
|
PLOGE("read");
|
||||||
}
|
}
|
||||||
return count;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int xpipe(int pipefd[2]) {
|
int xpipe(int pipefd[2]) {
|
||||||
if (pipe(pipefd) == -1) {
|
int ret = pipe(pipefd);
|
||||||
|
if (ret == -1) {
|
||||||
PLOGE("pipe");
|
PLOGE("pipe");
|
||||||
}
|
}
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int xsetns(int fd, int nstype) {
|
int xsetns(int fd, int nstype) {
|
||||||
if (setns(fd, nstype) == -1) {
|
int ret = setns(fd, nstype);
|
||||||
|
if (ret == -1) {
|
||||||
PLOGE("setns");
|
PLOGE("setns");
|
||||||
}
|
}
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
DIR *xopendir(const char *name) {
|
DIR *xopendir(const char *name) {
|
||||||
@ -102,10 +106,11 @@ pid_t xsetsid() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int xsetcon(char *context) {
|
int xsetcon(char *context) {
|
||||||
if (setcon(context) == -1) {
|
int ret = setcon(context);
|
||||||
|
if (ret == -1) {
|
||||||
PLOGE("setcon: %s", context);
|
PLOGE("setcon: %s", context);
|
||||||
}
|
}
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int xsocket(int domain, int type, int protocol) {
|
int xsocket(int domain, int type, int protocol) {
|
||||||
@ -117,24 +122,27 @@ int xsocket(int domain, int type, int protocol) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int xbind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
|
int xbind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
|
||||||
if (bind(sockfd, addr, addrlen) == -1) {
|
int ret = bind(sockfd, addr, addrlen);
|
||||||
|
if (ret == -1) {
|
||||||
PLOGE("bind");
|
PLOGE("bind");
|
||||||
}
|
}
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int xconnect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
|
int xconnect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
|
||||||
if (connect(sockfd, addr, addrlen) == -1) {
|
int ret = connect(sockfd, addr, addrlen);
|
||||||
|
if (ret == -1) {
|
||||||
PLOGE("bind");
|
PLOGE("bind");
|
||||||
}
|
}
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int xlisten(int sockfd, int backlog) {
|
int xlisten(int sockfd, int backlog) {
|
||||||
if (listen(sockfd, backlog) == -1) {
|
int ret = listen(sockfd, backlog);
|
||||||
|
if (ret == -1) {
|
||||||
PLOGE("listen");
|
PLOGE("listen");
|
||||||
}
|
}
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int xaccept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
|
int xaccept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
|
||||||
@ -185,4 +193,21 @@ ssize_t xrecvmsg(int sockfd, struct msghdr *msg, int flags) {
|
|||||||
return rec;
|
return rec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int xpthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||||
|
void *(*start_routine) (void *), void *arg) {
|
||||||
|
errno = pthread_create(thread, attr, start_routine, arg);
|
||||||
|
if (errno) {
|
||||||
|
PLOGE("pthread_create");
|
||||||
|
}
|
||||||
|
return errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
int xsocketpair(int domain, int type, int protocol, int sv[2]) {
|
||||||
|
int ret = socketpair(domain, type, protocol, sv);
|
||||||
|
if (ret == -1) {
|
||||||
|
PLOGE("socketpair");
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user