Add magiskhide list management

This commit is contained in:
topjohnwu 2017-04-20 22:45:56 +08:00
parent e4f3fb36f3
commit 2a985ce6c0
10 changed files with 195 additions and 54 deletions

View File

@ -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 \

View File

@ -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();

View File

@ -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 *

View File

@ -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) {

View 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);
}

View File

@ -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);
}

View File

@ -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

View File

@ -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);

View File

@ -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 */

View File

@ -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));