Optimize magiskhide to work with the log daemon

This commit is contained in:
topjohnwu 2018-07-04 01:52:23 +08:00
parent 52a2c6958b
commit e7a2144def
5 changed files with 100 additions and 90 deletions

View File

@ -26,21 +26,15 @@ static char *prop_value[] =
"0", "0", "0", "1",
"user", "release-keys", "0", NULL };
static int mocked = 0;
void manage_selinux() {
if (mocked) return;
char val[1];
char val;
int fd = xopen(SELINUX_ENFORCE, O_RDONLY);
xxread(fd, val, 1);
xxread(fd, &val, sizeof(val));
close(fd);
// Permissive
if (val[0] == '0') {
LOGI("hide_daemon: Permissive detected, hide the state\n");
if (val == '0') {
chmod(SELINUX_ENFORCE, 0640);
chmod(SELINUX_POLICY, 0440);
mocked = 1;
}
}
@ -65,6 +59,10 @@ static void rm_magisk_prop(const char *name, const char *value, void *v) {
}
}
static void kill_proc(int pid) {
kill(pid, SIGTERM);
}
void clean_magisk_props() {
LOGD("hide_utils: Cleaning magisk props\n");
getprop_all(rm_magisk_prop, NULL);

View File

@ -22,10 +22,6 @@ int hideEnabled = 0;
static pthread_t proc_monitor_thread;
pthread_mutex_t hide_lock, file_lock;
void kill_proc(int pid) {
kill(pid, SIGTERM);
}
static void usage(char *arg0) {
fprintf(stderr,
"MagiskHide v" xstr(MAGISK_VERSION) "(" xstr(MAGISK_VER_CODE) ") (by topjohnwu) - Hide Magisk!\n\n"

View File

@ -5,9 +5,6 @@
#define TERM_THREAD SIGUSR1
// Kill process
void kill_proc(int pid);
// Process monitor
void proc_monitor();

View File

@ -126,79 +126,82 @@ void proc_monitor() {
term_thread(TERM_THREAD);
}
// Connect to the log daemon
connect_daemon2(LOG_DAEMON, &sockfd);
write_int(sockfd, HIDE_CONNECT);
while(1) {
// Connect to the log daemon
connect_daemon2(LOG_DAEMON, &sockfd);
write_int(sockfd, HIDE_CONNECT);
FILE *logs = fdopen(sockfd, "r");
char log[4096], *line;
while (1) {
/* It might be interrupted */
if (fgets(log, sizeof(log), logs) == NULL)
continue;
char *ss = strchr(log, '[');
int pid, ppid, ret, comma = 0;
char *pos = ss, proc[256], ns[32], pns[32];
FILE *log_in = fdopen(sockfd, "r");
char buf[4096];
while (fgets(buf, sizeof(buf), log_in)) {
char *ss = strchr(buf, '[');
int pid, ppid, num = 0;
char *pos = ss, proc[256], ns[32], pns[32];
while(1) {
pos = strchr(pos, ',');
if(pos == NULL)
break;
pos[0] = ' ';
++comma;
}
while(1) {
pos = strchr(pos, ',');
if(pos == NULL)
break;
pos[0] = ' ';
++num;
}
if (comma == 6)
ret = sscanf(ss, "[%*d %d %*d %*d %256s", &pid, proc);
else
ret = sscanf(ss, "[%*d %d %*d %256s", &pid, proc);
if(sscanf(ss, num == 6 ? "[%*d %d %*d %*d %256s" : "[%*d %d %*d %256s", &pid, proc) != 2)
continue;
if(ret != 2)
continue;
// Make sure our target is alive
if (kill(pid, 0))
continue;
ppid = parse_ppid(pid);
// Allow hiding sub-services of applications
char *colon = strchr(proc, ':');
if (colon)
*colon = '\0';
// Allow hiding sub-services of applications
char *colon = strchr(proc, ':');
if (colon)
*colon = '\0';
int hide = 0;
pthread_mutex_lock(&hide_lock);
char *line;
vec_for_each(hide_list, line) {
if (strcmp(proc, line) == 0) {
hide = 1;
break;
}
}
pthread_mutex_unlock(&hide_lock);
if (!hide)
continue;
// Critical region
pthread_mutex_lock(&hide_lock);
vec_for_each(hide_list, line) {
if (strcmp(proc, line) == 0) {
read_namespace(ppid, pns, sizeof(pns));
do {
read_namespace(pid, ns, sizeof(ns));
if (strcmp(ns, pns) == 0)
usleep(50);
else
break;
} while (1);
ppid = parse_ppid(pid);
read_namespace(ppid, pns, sizeof(pns));
do {
read_namespace(pid, ns, sizeof(ns));
if (strcmp(ns, pns) == 0)
usleep(50);
else
break;
} while (1);
// Send pause signal ASAP
if (kill(pid, SIGSTOP) == -1)
continue;
// Send pause signal ASAP
if (kill(pid, SIGSTOP) == -1)
continue;
// Restore the colon so we can log the actual process name
if (colon)
*colon = ':';
// Restore the colon so we can log the actual process name
if (colon)
*colon = ':';
#ifdef MAGISK_DEBUG
LOGI("proc_monitor: %s (PID=[%d] ns=%s)(PPID=[%d] ns=%s)\n", proc, pid, ns + 4, ppid, pns + 4);
LOGI("proc_monitor: %s (PID=[%d] ns=%s)(PPID=[%d] ns=%s)\n",
proc, pid, ns + 4, ppid, pns + 4);
#else
LOGI("proc_monitor: %s\n", proc);
LOGI("proc_monitor: %s\n", proc);
#endif
/*
* The setns system call do not support multithread processes
* We have to fork a new process, setns, then do the unmounts
*/
if (fork_dont_care() == 0)
hide_daemon(pid);
break;
}
/*
* The setns system call do not support multithread processes
* We have to fork a new process, setns, then do the unmounts
*/
if (fork_dont_care() == 0)
hide_daemon(pid);
}
pthread_mutex_unlock(&hide_lock);
// The other end EOF, restart the connection
}
}

View File

@ -170,22 +170,38 @@ void ps(void (*func)(int)) {
static void (*ps_filter_cb)(int);
static const char *ps_filter_pattern;
static void proc_name_filter(int pid) {
char buf[64];
int fd;
snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
if (access(buf, R_OK) == -1 || (fd = xopen(buf, O_RDONLY)) == -1)
char buf[128];
FILE *f;
sprintf(buf, "/proc/%d/comm", pid);
if ((f = fopen(buf, "r"))) {
fgets(buf, sizeof(buf), f);
if (strcmp(buf, ps_filter_pattern) == 0)
goto run_cb;
} else {
// The PID is already killed
return;
if (fdgets(buf, sizeof(buf), fd) == 0) {
snprintf(buf, sizeof(buf), "/proc/%d/comm", pid);
close(fd);
if (access(buf, R_OK) == -1 || (fd = xopen(buf, O_RDONLY)) == -1)
return;
fdgets(buf, sizeof(buf), fd);
}
if (strcmp(buf, ps_filter_pattern) == 0) {
ps_filter_cb(pid);
}
close(fd);
fclose(f);
sprintf(buf, "/proc/%d/cmdline", pid);
f = fopen(buf, "r");
fgets(buf, sizeof(buf), f);
if (strcmp(basename(buf), ps_filter_pattern) == 0)
goto run_cb;
fclose(f);
sprintf(buf, "/proc/%d/exe", pid);
if (access(buf, F_OK) != 0)
return;
xreadlink(buf, buf, sizeof(buf));
if (strcmp(basename(buf), ps_filter_pattern) == 0)
goto run_cb;
return;
run_cb:
ps_filter_cb(pid);
fclose(f);
return;
}
/* Call func with process name filtered with pattern */