Add magiskhide list management
This commit is contained in:
parent
e4f3fb36f3
commit
2a985ce6c0
@ -29,6 +29,7 @@ LOCAL_SRC_FILES := \
|
||||
magiskhide/hide_daemon.c \
|
||||
magiskhide/proc_monitor.c \
|
||||
magiskhide/pre_process.c \
|
||||
magiskhide/list_manager.c \
|
||||
magiskpolicy/magiskpolicy.c \
|
||||
magiskpolicy/rules.c \
|
||||
magiskpolicy/sepolicy.c \
|
||||
|
@ -35,10 +35,10 @@ static void request_handler(int client) {
|
||||
stop_magiskhide(client);
|
||||
break;
|
||||
case ADD_HIDELIST:
|
||||
// TODO: Add hidelist
|
||||
add_hide_list(client);
|
||||
break;
|
||||
case RM_HIDELIST:
|
||||
// TODO: Remove hidelist
|
||||
rm_hide_list(client);
|
||||
break;
|
||||
case SUPERUSER:
|
||||
su_daemon_receiver(client);
|
||||
@ -135,7 +135,7 @@ void start_daemon() {
|
||||
// Start log monitor
|
||||
monitor_logs();
|
||||
|
||||
LOGI("Magisk v" xstr(VERSION) " daemon started\n");
|
||||
LOGI("Magisk v" xstr(MAGISK_VERSION) " daemon started\n");
|
||||
|
||||
// Unlock all blocks for rw
|
||||
unlock_blocks();
|
||||
|
@ -55,6 +55,8 @@ void late_start(int client);
|
||||
|
||||
void launch_magiskhide(int client);
|
||||
void stop_magiskhide(int client);
|
||||
void add_hide_list(int client);
|
||||
void rm_hide_list(int client);
|
||||
|
||||
/*************
|
||||
* Superuser *
|
||||
|
@ -83,9 +83,8 @@ int hide_daemon() {
|
||||
close(fd);
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "/proc/%d/mounts", pid);
|
||||
fp = xfopen(buffer, "r");
|
||||
vec_init(&mount_list);
|
||||
file_to_vector(&mount_list, fp);
|
||||
file_to_vector(buffer, &mount_list);
|
||||
|
||||
// Find the cache block name if not found yet
|
||||
if (strlen(cache_block) == 0) {
|
||||
@ -109,10 +108,9 @@ int hide_daemon() {
|
||||
vec_destroy(&mount_list);
|
||||
|
||||
// Re-read mount infos
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
snprintf(buffer, sizeof(buffer), "/proc/%d/mounts", pid);
|
||||
vec_init(&mount_list);
|
||||
file_to_vector(&mount_list, fp);
|
||||
fclose(fp);
|
||||
file_to_vector(buffer, &mount_list);
|
||||
|
||||
// Unmount loop mounts
|
||||
vec_for_each_r(&mount_list, line) {
|
||||
|
130
jni/magiskhide/list_manager.c
Normal file
130
jni/magiskhide/list_manager.c
Normal file
@ -0,0 +1,130 @@
|
||||
/* list_manager.c - Hide list management
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "magisk.h"
|
||||
#include "utils.h"
|
||||
#include "daemon.h"
|
||||
#include "magiskhide.h"
|
||||
|
||||
int add_list(char *proc) {
|
||||
if (!hideEnabled)
|
||||
return 1;
|
||||
|
||||
char *line;
|
||||
struct vector *new_list, *temp = hide_list;
|
||||
new_list = xmalloc(sizeof(*new_list));
|
||||
if (new_list == NULL)
|
||||
return 1;
|
||||
vec_init(new_list);
|
||||
|
||||
vec_for_each(hide_list, line) {
|
||||
// They should be unique
|
||||
if (strcmp(line, proc) == 0) {
|
||||
free(proc);
|
||||
vec_destroy(new_list);
|
||||
free(new_list);
|
||||
return 2;
|
||||
}
|
||||
vec_push_back(new_list, line);
|
||||
}
|
||||
|
||||
vec_push_back(new_list, proc);
|
||||
LOGI("hide_list add: [%s]\n", proc);
|
||||
ps_filter_proc_name(proc, kill_proc);
|
||||
|
||||
// Critical region
|
||||
pthread_mutex_lock(&lock);
|
||||
hide_list = new_list;
|
||||
pthread_mutex_unlock(&lock);
|
||||
|
||||
// Free old list
|
||||
vec_destroy(temp);
|
||||
free(temp);
|
||||
if (vector_to_file(HIDELIST, hide_list))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rm_list(char *proc) {
|
||||
if (!hideEnabled)
|
||||
return 1;
|
||||
|
||||
char *line;
|
||||
struct vector *new_list, *temp;
|
||||
temp = new_list = xmalloc(sizeof(*new_list));
|
||||
if (new_list == NULL)
|
||||
return 1;
|
||||
vec_init(new_list);
|
||||
|
||||
vec_for_each(hide_list, line) {
|
||||
if (strcmp(line, proc) == 0) {
|
||||
free(proc);
|
||||
proc = line;
|
||||
temp = hide_list;
|
||||
continue;
|
||||
}
|
||||
vec_push_back(new_list, line);
|
||||
}
|
||||
|
||||
if (temp == hide_list) {
|
||||
LOGI("hide_list rm: [%s]\n", proc);
|
||||
ps_filter_proc_name(proc, kill_proc);
|
||||
// Critical region
|
||||
pthread_mutex_lock(&lock);
|
||||
hide_list = new_list;
|
||||
pthread_mutex_unlock(&lock);
|
||||
if (vector_to_file(HIDELIST, hide_list))
|
||||
return 1;
|
||||
}
|
||||
|
||||
free(proc);
|
||||
vec_destroy(temp);
|
||||
free(temp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int init_list() {
|
||||
LOGD("hide_list: initialize...\n");
|
||||
if ((hide_list = xmalloc(sizeof(*hide_list))) == NULL)
|
||||
return 1;
|
||||
vec_init(hide_list);
|
||||
|
||||
// Might return 1 if first time
|
||||
file_to_vector(HIDELIST, hide_list);
|
||||
|
||||
char *line;
|
||||
vec_for_each(hide_list, line) {
|
||||
LOGI("hide_list: [%s]\n", line);
|
||||
ps_filter_proc_name(line, kill_proc);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int destroy_list() {
|
||||
char *line;
|
||||
vec_for_each(hide_list, line) {
|
||||
ps_filter_proc_name(line, kill_proc);
|
||||
}
|
||||
vec_deep_destroy(hide_list);
|
||||
free(hide_list);
|
||||
hide_list = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void add_hide_list(int client) {
|
||||
char *proc = read_string(client);
|
||||
// ack
|
||||
write_int(client, add_list(proc));
|
||||
close(client);
|
||||
}
|
||||
|
||||
void rm_hide_list(int client) {
|
||||
char *proc = read_string(client);
|
||||
// ack
|
||||
write_int(client, rm_list(proc));
|
||||
close(client);
|
||||
}
|
@ -16,12 +16,14 @@
|
||||
#include "utils.h"
|
||||
#include "magiskhide.h"
|
||||
#include "daemon.h"
|
||||
#include "resetprop.h"
|
||||
|
||||
int sv[2], hide_pid = -1;
|
||||
struct vector *hide_list, *new_list;
|
||||
struct vector *hide_list = NULL;
|
||||
|
||||
int isEnabled = 0;
|
||||
int hideEnabled = 0;
|
||||
static pthread_t proc_monitor_thread;
|
||||
pthread_mutex_t lock;
|
||||
|
||||
void kill_proc(int pid) {
|
||||
kill(pid, SIGTERM);
|
||||
@ -41,7 +43,7 @@ static void usage(char *arg0) {
|
||||
}
|
||||
|
||||
void launch_magiskhide(int client) {
|
||||
if (isEnabled)
|
||||
if (hideEnabled)
|
||||
goto success;
|
||||
/*
|
||||
* The setns system call do not support multithread processes
|
||||
@ -50,6 +52,9 @@ void launch_magiskhide(int client) {
|
||||
|
||||
LOGI("* Starting MagiskHide\n");
|
||||
|
||||
hideEnabled = 1;
|
||||
setprop("persist.magisk.hide", "1");
|
||||
|
||||
hide_sensitive_props();
|
||||
|
||||
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sv) == -1)
|
||||
@ -62,31 +67,23 @@ void launch_magiskhide(int client) {
|
||||
close(sv[1]);
|
||||
|
||||
// Initialize the hide list
|
||||
hide_list = new_list = xmalloc(sizeof(*hide_list));
|
||||
if (hide_list == NULL)
|
||||
if (init_list())
|
||||
goto error;
|
||||
vec_init(hide_list);
|
||||
FILE *fp = xfopen(HIDELIST, "r");
|
||||
if (fp == NULL)
|
||||
goto error;
|
||||
file_to_vector(hide_list, fp);
|
||||
fclose(fp);
|
||||
char *line;
|
||||
vec_for_each(hide_list, line) {
|
||||
LOGI("hide_list: [%s]\n", line);
|
||||
ps_filter_proc_name(line, kill_proc);
|
||||
}
|
||||
|
||||
// Add SafetyNet by default
|
||||
add_list(strdup("com.google.android.gms.unstable"));
|
||||
|
||||
// Start a new thread to monitor processes
|
||||
pthread_mutex_init(&lock, NULL);
|
||||
if (xpthread_create(&proc_monitor_thread, NULL, proc_monitor, NULL))
|
||||
goto error;
|
||||
|
||||
isEnabled = 1;
|
||||
success:
|
||||
write_int(client, 0);
|
||||
close(client);
|
||||
return;
|
||||
error:
|
||||
hideEnabled = 0;
|
||||
write_int(client, 1);
|
||||
close(client);
|
||||
if (hide_pid != -1) {
|
||||
@ -101,7 +98,7 @@ error:
|
||||
}
|
||||
|
||||
void stop_magiskhide(int client) {
|
||||
if (!isEnabled)
|
||||
if (!hideEnabled)
|
||||
return;
|
||||
|
||||
LOGI("* Stopping MagiskHide\n");
|
||||
@ -109,7 +106,8 @@ void stop_magiskhide(int client) {
|
||||
pthread_kill(proc_monitor_thread, SIGUSR1);
|
||||
pthread_join(proc_monitor_thread, NULL);
|
||||
|
||||
isEnabled = 0;
|
||||
hideEnabled = 0;
|
||||
setprop("persist.magisk.hide", "0");
|
||||
write_int(client, 0);
|
||||
close(client);
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef MAGISK_HIDE_H
|
||||
#define MAGISK_HIDE_H
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#define HIDELIST "/magisk/.core/magiskhide/hidelist"
|
||||
#define DUMMYPATH "/dev/magisk/dummy"
|
||||
#define ENFORCE_FILE "/sys/fs/selinux/enforce"
|
||||
@ -20,7 +22,14 @@ void manage_selinux();
|
||||
void hide_sensitive_props();
|
||||
void relink_sbin();
|
||||
|
||||
extern int sv[2], hide_pid, isEnabled;
|
||||
extern struct vector *hide_list, *new_list;
|
||||
// List managements
|
||||
int add_list(char *proc);
|
||||
int rm_list(char *proc);
|
||||
int init_list();
|
||||
int destroy_list();
|
||||
|
||||
extern int sv[2], hide_pid, hideEnabled;
|
||||
extern struct vector *hide_list;
|
||||
extern pthread_mutex_t lock;
|
||||
|
||||
#endif
|
||||
|
@ -30,18 +30,8 @@ static void read_namespace(const int pid, char* target, const size_t size) {
|
||||
// Workaround for the lack of pthread_cancel
|
||||
static void quit_pthread(int sig) {
|
||||
LOGD("proc_monitor: running cleanup\n");
|
||||
char *line;
|
||||
vec_for_each(hide_list, line) {
|
||||
ps_filter_proc_name(line, kill_proc);
|
||||
}
|
||||
vec_deep_destroy(hide_list);
|
||||
free(hide_list);
|
||||
if (new_list != hide_list) {
|
||||
vec_deep_destroy(new_list);
|
||||
free(new_list);
|
||||
}
|
||||
hide_list = new_list = NULL;
|
||||
isEnabled = 0;
|
||||
destroy_list();
|
||||
hideEnabled = 0;
|
||||
// Kill the logging if possible
|
||||
if (log_pid) {
|
||||
kill(log_pid, SIGTERM);
|
||||
@ -54,6 +44,7 @@ static void quit_pthread(int sig) {
|
||||
write(sv[0], &kill, sizeof(kill));
|
||||
close(sv[0]);
|
||||
waitpid(hide_pid, NULL, 0);
|
||||
pthread_mutex_destroy(&lock);
|
||||
LOGD("proc_monitor: terminating...\n");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
@ -109,7 +100,6 @@ void *proc_monitor(void *args) {
|
||||
while(fdgets(buffer, sizeof(buffer), log_fd)) {
|
||||
int ret, comma = 0;
|
||||
char *pos = buffer, *line, processName[256];
|
||||
struct vector *temp = NULL;
|
||||
|
||||
while(1) {
|
||||
pos = strchr(pos, ',');
|
||||
@ -127,14 +117,10 @@ void *proc_monitor(void *args) {
|
||||
if(ret != 2)
|
||||
continue;
|
||||
|
||||
// Should be thread safe
|
||||
if (hide_list != new_list) {
|
||||
temp = hide_list;
|
||||
hide_list = new_list;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
// Critical region
|
||||
pthread_mutex_lock(&lock);
|
||||
vec_for_each(hide_list, line) {
|
||||
if (strcmp(processName, line) == 0) {
|
||||
read_namespace(pid, buffer, 32);
|
||||
@ -166,10 +152,8 @@ void *proc_monitor(void *args) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (temp) {
|
||||
vec_deep_destroy(temp);
|
||||
free(temp);
|
||||
}
|
||||
pthread_mutex_unlock(&lock);
|
||||
|
||||
if (ret) {
|
||||
// Wait hide process to kill itself
|
||||
waitpid(hide_pid, NULL, 0);
|
||||
|
@ -57,11 +57,15 @@ int check_data() {
|
||||
}
|
||||
|
||||
/* All the string should be freed manually!! */
|
||||
void file_to_vector(struct vector *v, FILE *fp) {
|
||||
int file_to_vector(const char* filename, struct vector *v) {
|
||||
char *line = NULL;
|
||||
size_t len = 0;
|
||||
ssize_t read;
|
||||
|
||||
FILE *fp = xfopen(filename, "r");
|
||||
if (fp == NULL)
|
||||
return 1;
|
||||
|
||||
while ((read = getline(&line, &len, fp)) != -1) {
|
||||
// Remove end newline
|
||||
if (line[read - 1] == '\n')
|
||||
@ -69,6 +73,20 @@ void file_to_vector(struct vector *v, FILE *fp) {
|
||||
vec_push_back(v, line);
|
||||
line = NULL;
|
||||
}
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vector_to_file(const char *filename, struct vector *v) {
|
||||
FILE *fp = xfopen(filename, "w");
|
||||
if (fp == NULL)
|
||||
return 1;
|
||||
char *line;
|
||||
vec_for_each(v, line) {
|
||||
fprintf(fp, "%s\n", line);
|
||||
}
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check if the string only contains digits */
|
||||
|
@ -63,7 +63,8 @@ unsigned get_shell_uid();
|
||||
unsigned get_system_uid();
|
||||
unsigned get_radio_uid();
|
||||
int check_data();
|
||||
void file_to_vector(struct vector *v, FILE *fp);
|
||||
int file_to_vector(const char* filename, struct vector *v);
|
||||
int vector_to_file(const char* filename, struct vector *v);
|
||||
int isNum(const char *s);
|
||||
ssize_t fdgets(char *buf, size_t size, int fd);
|
||||
void ps(void (*func)(int));
|
||||
|
Loading…
Reference in New Issue
Block a user