/* magiskhide.c - initialize the environment for Magiskhide */ #include #include #include #include #include #include #include #include #include "magisk.h" #include "utils.h" #include "magiskhide.h" #include "daemon.h" #include "resetprop.h" int sv[2], hide_pid = -1; struct vector *hide_list = NULL; 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) " (by topjohnwu) - Hide Magisk!\n\n" "%s [--options [arguments...] ]\n\n" "Options:\n" " --enable: Start the magiskhide daemon\n" " --disable: Stop the magiskhide daemon\n" " --add : Add to the list\n" " --rm : Remove from the list\n" " --ls: Print out the current hide list\n" , arg0); exit(1); } void launch_magiskhide(int client) { // We manually handle crashes err_handler = do_nothing; if (hideEnabled) { write_int(client, HIDE_IS_ENABLED); close(client); return; } LOGI("* Starting MagiskHide\n"); hideEnabled = 1; if (client != -1) { if (setprop(MAGISKHIDE_PROP, "1")) goto error; } hide_sensitive_props(); if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sv) == -1) goto error; /* * The setns system call do not support multithread processes * We have to fork a new process, and communicate with sockets */ if (hide_daemon()) goto error; close(sv[1]); // Initialize the mutex lock pthread_mutex_init(&hide_lock, NULL); pthread_mutex_init(&file_lock, NULL); // Initialize the hide list if (init_list()) goto error; // Add SafetyNet by default add_list(strdup("com.google.android.gms.unstable")); write_int(client, DAEMON_SUCCESS); close(client); // Get thread reference proc_monitor_thread = pthread_self(); // Start monitoring proc_monitor(); return; error: hideEnabled = 0; write_int(client, DAEMON_ERROR); close(client); if (hide_pid != -1) { int kill = -1; // Kill hide daemon write(sv[0], &kill, sizeof(kill)); close(sv[0]); waitpid(hide_pid, NULL, 0); hide_pid = -1; } return; } void stop_magiskhide(int client) { if (!hideEnabled) { write_int(client, HIDE_NOT_ENABLED); close(client); return; } LOGI("* Stopping MagiskHide\n"); hideEnabled = 0; setprop(MAGISKHIDE_PROP, "0"); pthread_kill(proc_monitor_thread, SIGUSR1); write_int(client, DAEMON_SUCCESS); close(client); } int magiskhide_main(int argc, char *argv[]) { if (argc < 2) { usage(argv[0]); } client_request req = DO_NOTHING; 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 = fopen(HIDELIST, "r"); if (fp == NULL) return 1; char buffer[512]; while (fgets(buffer, sizeof(buffer), fp)) { printf("%s", buffer); } fclose(fp); return 0; } int fd = connect_daemon(); write_int(fd, req); if (req == ADD_HIDELIST || req == RM_HIDELIST) { write_string(fd, argv[2]); } daemon_response code = read_int(fd); close(fd); switch (code) { case DAEMON_ERROR: fprintf(stderr, "Error occured in daemon...\n"); break; case DAEMON_SUCCESS: break; case ROOT_REQUIRED: fprintf(stderr, "Root is required for this operation\n"); break; case HIDE_NOT_ENABLED: fprintf(stderr, "Magisk hide is not enabled yet\n"); break; case HIDE_IS_ENABLED: fprintf(stderr, "Magisk hide is already enabled\n"); break; case HIDE_ITEM_EXIST: fprintf(stderr, "Process [%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]); break; } return code; }