From 38fcc57bbfdb69b8e60bc0f3867052996e79366c Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Fri, 23 Nov 2018 15:47:49 -0500 Subject: [PATCH] Use component name as targets Services can name their process name arbitrarily, for instance the service in com.google.android.gms that is responsible for SafetyNet is named com.google.android.gms.unstable. There are many apps out in the wild use dedicated services with special names to detect root, and previously the user is expected to add all of them to the hide list. In this commit, we change from targeting process names to component names. On Android, component names are composed of /. When targeting component names, we can always know what application spawned the new process. This means that if the user adds a package name to the hidelist, MagiskHide can now target ALL possible processes of that specific application. To abide with this change, the default SafetyNet target is now changed from com.google.android.gms.unstable (process name) to com.google.android.gms/.droidguard.DroidGuardService (component name) --- native/jni/magiskhide/hide_utils.cpp | 3 +- native/jni/magiskhide/magiskhide.cpp | 14 ++++++--- native/jni/magiskhide/proc_monitor.cpp | 42 ++++++++++---------------- native/jni/utils/misc.cpp | 8 ++--- 4 files changed, 31 insertions(+), 36 deletions(-) diff --git a/native/jni/magiskhide/hide_utils.cpp b/native/jni/magiskhide/hide_utils.cpp index 025203f99..b9f0cb8d4 100644 --- a/native/jni/magiskhide/hide_utils.cpp +++ b/native/jni/magiskhide/hide_utils.cpp @@ -268,7 +268,8 @@ int launch_magiskhide(int client) { goto error; // Add SafetyNet by default - add_list("com.google.android.gms.unstable"); + rm_list("com.google.android.gms.unstable"); + add_list("com.google.android.gms/.droidguard.DroidGuardService"); // Get thread reference proc_monitor_thread = pthread_self(); diff --git a/native/jni/magiskhide/magiskhide.cpp b/native/jni/magiskhide/magiskhide.cpp index 704f8b1d0..0c01b508a 100644 --- a/native/jni/magiskhide/magiskhide.cpp +++ b/native/jni/magiskhide/magiskhide.cpp @@ -17,14 +17,18 @@ bool hide_enabled = false; [[noreturn]] static void usage(char *arg0) { fprintf(stderr, "MagiskHide v" xstr(MAGISK_VERSION) "(" xstr(MAGISK_VER_CODE) ") (by topjohnwu)\n\n" - "Usage: %s [--options [arguments...] ]\n\n" + "Usage: %s [--option [arguments...] ]\n\n" "Options:\n" " --status Return the status of MagiskHide\n" " --enable Start magiskhide\n" " --disable Stop magiskhide\n" - " --add PROCESS Add PROCESS to the hide list\n" - " --rm PROCESS Remove PROCESS from the hide list\n" + " --add TARGET Add TARGET to the hide list\n" + " --rm TARGET Remove TARGET from the hide list\n" " --ls Print out the current hide list\n" + "\n" + "TARGET can be either a package name or a specific component name\n" + "If TARGET is a package name, all components of the app will be targeted\n" + "A component name is composed of /\n" , arg0); exit(1); } @@ -115,10 +119,10 @@ int magiskhide_main(int argc, char *argv[]) { fprintf(stderr, "MagiskHide is enabled\n"); break; case HIDE_ITEM_EXIST: - fprintf(stderr, "Process [%s] already exists in hide list\n", argv[2]); + fprintf(stderr, "[%s] already exists in hide list\n", argv[2]); break; case HIDE_ITEM_NOT_EXIST: - fprintf(stderr, "Process [%s] does not exist in hide list\n", argv[2]); + fprintf(stderr, "[%s] does not exist in hide list\n", argv[2]); break; /* Errors */ diff --git a/native/jni/magiskhide/proc_monitor.cpp b/native/jni/magiskhide/proc_monitor.cpp index 8e4ba42e7..65fa8b221 100644 --- a/native/jni/magiskhide/proc_monitor.cpp +++ b/native/jni/magiskhide/proc_monitor.cpp @@ -20,7 +20,6 @@ #include "daemon.h" #include "utils.h" #include "magiskhide.h" -#include "flags.h" static int sockfd = -1; extern char *system_block, *vendor_block, *magiskloop; @@ -61,7 +60,7 @@ static int parse_ppid(int pid) { } static void hide_daemon(int pid) { - LOGD("hide_daemon: start unmount for pid=[%d]\n", pid); + LOGD("hide_daemon: handling pid=[%d]\n", pid); char buffer[4096]; Vector mounts; @@ -130,32 +129,32 @@ void proc_monitor() { FILE *log_in = fdopen(sockfd, "r"); char buf[4096]; while (fgets(buf, sizeof(buf), log_in)) { - char *ss = strchr(buf, '[') + 1; - int pid, ppid, num = 0; - char *pos = ss, proc[256]; + char *log; + int pid, ppid; struct stat ns, pns; - while((pos = strchr(pos, ','))) { - *pos = ' '; - ++num; - } + if ((log = strchr(buf, '[')) == nullptr) + continue; - if(sscanf(ss, num == 6 ? "%*d %d %*d %*d %256s" : "%*d %d %*d %256s", &pid, proc) != 2) + // Extract pid + if (sscanf(log, "[%*d,%d", &pid) != 1) + continue; + + // Extract last token (component name) + const char *tok, *cpnt = ""; + while ((tok = strtok_r(nullptr, ",[]\n", &log))) + cpnt = tok; + if (cpnt[0] == '\0') continue; // Make sure our target is alive if ((ppid = parse_ppid(pid)) < 0 || read_ns(ppid, &pns)) continue; - // Allow hiding sub-services of applications - char *colon = strchr(proc, ':'); - if (colon) - *colon = '\0'; - bool hide = false; pthread_mutex_lock(&list_lock); for (auto &s : hide_list) { - if (s == proc) { + if (strncmp(cpnt, s, s.size() - 1) == 0) { hide = true; break; } @@ -172,20 +171,11 @@ void proc_monitor() { if (kill(pid, SIGSTOP) == -1) continue; - // Restore the colon so we can log the actual process name - if (colon) - *colon = ':'; -#ifdef MAGISK_DEBUG - LOGI("proc_monitor: %s (PID=[%d] ns=%llu)(PPID=[%d] ns=%llu)\n", - proc, pid, ns.st_ino, ppid, pns.st_ino); -#else - 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 */ + LOGI("proc_monitor: %s PID=[%d] ns=[%llu]\n", cpnt, pid, ns.st_ino); if (fork_dont_care() == 0) hide_daemon(pid); } diff --git a/native/jni/utils/misc.cpp b/native/jni/utils/misc.cpp index e1a2faec2..de860a358 100644 --- a/native/jni/utils/misc.cpp +++ b/native/jni/utils/misc.cpp @@ -256,9 +256,9 @@ int exec_command(int err, int *fd, void (*cb)(void), const char *argv0, ...) { } char *strdup2(const char *s, size_t *size) { - size_t l = strlen(s) + 1; - char *buf = new char[l]; - memcpy(buf, s, l); - if (size) *size = l; + size_t len = strlen(s) + 1; + char *buf = new char[len]; + memcpy(buf, s, len); + if (size) *size = len; return buf; }