Compare commits

...

7 Commits
v13.2 ... v13.3

Author SHA1 Message Date
topjohnwu
8c5f11b7dd Update Magisk Manager 2017-07-19 02:34:23 +08:00
topjohnwu
7f7dda9ec2 Update uninstaller 2017-07-19 02:22:07 +08:00
topjohnwu
9c1005ff0c Update to Google CTS (2017.7.17) 2017-07-19 02:22:07 +08:00
topjohnwu
5b36b4472c Update and add new resetprop features 2017-07-19 02:22:07 +08:00
topjohnwu
a3fcc64aaa MagiskBoot log to stderr 2017-07-18 11:53:28 +08:00
topjohnwu
f3078bc903 Update MagiskSU 2017-07-16 23:39:27 +08:00
topjohnwu
6072744f7e Prevent logcat monitors crashing 2017-07-16 23:39:27 +08:00
18 changed files with 131 additions and 71 deletions

View File

@@ -489,6 +489,7 @@ void post_fs_data(int client) {
debug_log_fd = xopen(DEBUG_LOG, O_WRONLY | O_CREAT | O_CLOEXEC | O_TRUNC, 0644);
char *const command[] = { "logcat", "-v", "brief", NULL };
debug_log_pid = run_command(0, &debug_log_fd, "/system/bin/logcat", command);
close(debug_log_fd);
#endif
LOGI("** post-fs-data mode running\n");
@@ -776,6 +777,5 @@ void late_start(int client) {
// Stop recording the boot logcat after every boot task is done
kill(debug_log_pid, SIGTERM);
waitpid(debug_log_pid, NULL, 0);
close(debug_log_fd);
#endif
}

View File

@@ -31,7 +31,10 @@ static void *logger_thread(void *args) {
if (log_pid > 0)
waitpid(log_pid, NULL, 0);
// For some reason it went here, clear buffer and restart
system("logcat -c");
char *const restart[] = { "logcat", "-c", NULL };
log_pid = run_command(0, NULL, "/system/bin/logcat", restart);
if (log_pid > 0)
waitpid(log_pid, NULL, 0);
}
// Should never be here, but well...

View File

@@ -83,7 +83,7 @@ int open_new(const char *filename) {
}
void cleanup() {
printf("Cleaning up...\n");
fprintf(stderr, "Cleaning up...\n");
char name[PATH_MAX];
unlink(KERNEL_FILE);
unlink(RAMDISK_FILE);

View File

@@ -26,11 +26,11 @@ static void restore_buf(int fd, const void *buf, size_t size) {
}
static void print_info() {
printf("KERNEL [%d] @ 0x%08x\n", hdr.kernel_size, hdr.kernel_addr);
printf("RAMDISK [%d] @ 0x%08x\n", hdr.ramdisk_size, hdr.ramdisk_addr);
printf("SECOND [%d] @ 0x%08x\n", hdr.second_size, hdr.second_addr);
printf("DTB [%d] @ 0x%08x\n", hdr.dt_size, hdr.tags_addr);
printf("PAGESIZE [%d]\n", hdr.page_size);
fprintf(stderr, "KERNEL [%d] @ 0x%08x\n", hdr.kernel_size, hdr.kernel_addr);
fprintf(stderr, "RAMDISK [%d] @ 0x%08x\n", hdr.ramdisk_size, hdr.ramdisk_addr);
fprintf(stderr, "SECOND [%d] @ 0x%08x\n", hdr.second_size, hdr.second_addr);
fprintf(stderr, "DTB [%d] @ 0x%08x\n", hdr.dt_size, hdr.tags_addr);
fprintf(stderr, "PAGESIZE [%d]\n", hdr.page_size);
if (hdr.os_version != 0) {
int a,b,c,y,m = 0;
int os_version, os_patch_level;
@@ -40,38 +40,38 @@ static void print_info() {
a = (os_version >> 14) & 0x7f;
b = (os_version >> 7) & 0x7f;
c = os_version & 0x7f;
printf("OS_VERSION [%d.%d.%d]\n", a, b, c);
fprintf(stderr, "OS_VERSION [%d.%d.%d]\n", a, b, c);
y = (os_patch_level >> 4) + 2000;
m = os_patch_level & 0xf;
printf("PATCH_LEVEL [%d-%02d]\n", y, m);
fprintf(stderr, "PATCH_LEVEL [%d-%02d]\n", y, m);
}
printf("NAME [%s]\n", hdr.name);
printf("CMDLINE [%s]\n", hdr.cmdline);
fprintf(stderr, "NAME [%s]\n", hdr.name);
fprintf(stderr, "CMDLINE [%s]\n", hdr.cmdline);
switch (ramdisk_type) {
case GZIP:
printf("COMPRESSION [%s]\n", "gzip");
fprintf(stderr, "COMPRESSION [%s]\n", "gzip");
break;
case XZ:
printf("COMPRESSION [%s]\n", "xz");
fprintf(stderr, "COMPRESSION [%s]\n", "xz");
break;
case LZMA:
printf("COMPRESSION [%s]\n", "lzma");
fprintf(stderr, "COMPRESSION [%s]\n", "lzma");
break;
case BZIP2:
printf("COMPRESSION [%s]\n", "bzip2");
fprintf(stderr, "COMPRESSION [%s]\n", "bzip2");
break;
case LZ4:
printf("COMPRESSION [%s]\n", "lz4");
fprintf(stderr, "COMPRESSION [%s]\n", "lz4");
break;
case LZ4_LEGACY:
printf("COMPRESSION [%s]\n", "lz4_legacy");
fprintf(stderr, "COMPRESSION [%s]\n", "lz4_legacy");
break;
default:
fprintf(stderr, "Unknown ramdisk format!\n");
}
printf("\n");
fprintf(stderr, "\n");
}
int parse_img(unsigned char *orig, size_t size) {
@@ -126,11 +126,11 @@ int parse_img(unsigned char *orig, size_t size) {
// Check MTK
if (check_type(kernel) == MTK) {
printf("MTK header found in kernel\n");
fprintf(stderr, "MTK header found in kernel\n");
mtk_kernel = 1;
}
if (ramdisk_type == MTK) {
printf("MTK header found in ramdisk\n");
fprintf(stderr, "MTK header found in ramdisk\n");
mtk_ramdisk = 1;
ramdisk_type = check_type(ramdisk + 512);
}
@@ -151,7 +151,7 @@ void unpack(const char* image) {
mmap_ro(image, &orig, &size);
// Parse image
printf("Parsing boot image: [%s]\n\n", image);
fprintf(stderr, "Parsing boot image: [%s]\n\n", image);
int ret = parse_img(orig, size);
// Dump kernel
@@ -199,10 +199,10 @@ void repack(const char* orig_image, const char* out_image) {
mmap_ro(orig_image, &orig, &size);
// Parse original image
printf("Parsing boot image: [%s]\n\n", orig_image);
fprintf(stderr, "Parsing boot image: [%s]\n\n", orig_image);
parse_img(orig, size);
printf("Repack to boot image: [%s]\n\n", out_image);
fprintf(stderr, "Repack to boot image: [%s]\n\n", out_image);
// Create new image
int fd = open_new(out_image);

View File

@@ -22,10 +22,10 @@ static void write_file(const int fd, const void *buf, const size_t size, const c
static void report(const int mode, const char* filename) {
switch(mode) {
case 0:
printf("Decompressing to [%s]\n\n", filename);
fprintf(stderr, "Decompressing to [%s]\n\n", filename);
break;
default:
printf("Compressing to [%s]\n\n", filename);
fprintf(stderr, "Compressing to [%s]\n\n", filename);
break;
}
}

View File

@@ -62,7 +62,7 @@ static int cpio_compare(const void *a, const void *b) {
// Parse cpio file to a vector of cpio_file
static void parse_cpio(const char *filename, struct vector *v) {
printf("Loading cpio: [%s]\n\n", filename);
fprintf(stderr, "Loading cpio: [%s]\n\n", filename);
int fd = xopen(filename, O_RDONLY);
cpio_newc_header header;
cpio_file *f;
@@ -105,7 +105,7 @@ static void parse_cpio(const char *filename, struct vector *v) {
}
static void dump_cpio(const char *filename, struct vector *v) {
printf("\nDump cpio: [%s]\n\n", filename);
fprintf(stderr, "\nDump cpio: [%s]\n\n", filename);
int fd = open_new(filename);
unsigned inode = 300000;
char header[111];
@@ -158,7 +158,7 @@ static void cpio_rm(int recursive, const char *entry, struct vector *v) {
if ((recursive && strncmp(f->filename, entry, strlen(entry)) == 0)
|| (strcmp(f->filename, entry) == 0) ) {
if (!f->remove) {
printf("Remove [%s]\n", entry);
fprintf(stderr, "Remove [%s]\n", entry);
f->remove = 1;
}
if (!recursive) return;
@@ -173,7 +173,7 @@ static void cpio_mkdir(mode_t mode, const char *entry, struct vector *v) {
f->filename = xmalloc(f->namesize);
memcpy(f->filename, entry, f->namesize);
cpio_vec_insert(v, f);
printf("Create directory [%s] (%04o)\n",entry, mode);
fprintf(stderr, "Create directory [%s] (%04o)\n",entry, mode);
}
static void cpio_add(mode_t mode, const char *entry, const char *filename, struct vector *v) {
@@ -189,7 +189,7 @@ static void cpio_add(mode_t mode, const char *entry, const char *filename, struc
xxread(fd, f->data, f->filesize);
close(fd);
cpio_vec_insert(v, f);
printf("Add entry [%s] (%04o)\n", entry, mode);
fprintf(stderr, "Add entry [%s] (%04o)\n", entry, mode);
}
static void cpio_test(struct vector *v) {
@@ -270,7 +270,7 @@ static void cpio_patch(struct vector *v, int keepverity, int keepforceencrypt) {
if (injected)
continue;
// Inject magisk script as import
printf("Inject new line [import /init.magisk.rc] in [init.rc]\n");
fprintf(stderr, "Inject new line [import /init.magisk.rc] in [init.rc]\n");
line = xcalloc(sizeof(*line), 1);
line->line = strdup("import /init.magisk.rc");
line->isNew = 1;
@@ -279,7 +279,7 @@ static void cpio_patch(struct vector *v, int keepverity, int keepforceencrypt) {
injected = 1;
} else if (strstr(line->line, "selinux.reload_policy")) {
// Remove this line
printf("Remove line [%s] in [init.rc]\n", line->line);
fprintf(stderr, "Remove line [%s] in [init.rc]\n", line->line);
f->filesize -= strlen(line->line) + 1;
__ = list_pop(&line->pos);
free(line);
@@ -296,14 +296,14 @@ static void cpio_patch(struct vector *v, int keepverity, int keepforceencrypt) {
for (read = 0, write = 0; read < f->filesize; ++read, ++write) {
skip = check_verity_pattern(f->data + read);
if (skip > 0) {
printf("Remove pattern [%.*s] in [%s]\n", skip, f->data + read, f->filename);
fprintf(stderr, "Remove pattern [%.*s] in [%s]\n", skip, f->data + read, f->filename);
read += skip;
}
f->data[write] = f->data[read];
}
f->filesize = write;
} else if (strcmp(f->filename, "verity_key") == 0) {
printf("Remove [verity_key]\n");
fprintf(stderr, "Remove [verity_key]\n");
f->remove = 1;
}
}
@@ -313,7 +313,7 @@ static void cpio_patch(struct vector *v, int keepverity, int keepforceencrypt) {
for (int i = 0 ; ENCRYPT_LIST[i]; ++i) {
if (strncmp(f->data + read, ENCRYPT_LIST[i], strlen(ENCRYPT_LIST[i])) == 0) {
memcpy(f->data + write, "encryptable", 11);
printf("Replace [%s] with [%s] in [%s]\n", ENCRYPT_LIST[i], "encryptable", f->filename);
fprintf(stderr, "Replace [%s] with [%s] in [%s]\n", ENCRYPT_LIST[i], "encryptable", f->filename);
write += 11;
read += strlen(ENCRYPT_LIST[i]);
break;
@@ -332,7 +332,7 @@ static void cpio_extract(const char *entry, const char *filename, struct vector
cpio_file *f;
vec_for_each(v, f) {
if (strcmp(f->filename, entry) == 0 && S_ISREG(f->mode)) {
printf("Extracting [%s] to [%s]\n\n", entry, filename);
fprintf(stderr, "Extracting [%s] to [%s]\n\n", entry, filename);
int fd = open_new(filename);
xwrite(fd, f->data, f->filesize);
fchmod(fd, f->mode);
@@ -390,14 +390,14 @@ static void cpio_backup(const char *orig, struct vector *v) {
// Something is missing in new ramdisk, backup!
++i;
doBak = 1;
printf("Backup missing entry: ");
fprintf(stderr, "Backup missing entry: ");
} else if (res == 0) {
++i; ++j;
if (m->filesize == n->filesize && memcmp(m->data, n->data, m->filesize) == 0)
continue;
// Not the same!
doBak = 1;
printf("Backup mismatch entry: ");
fprintf(stderr, "Backup mismatch entry: ");
} else {
// Someting new in ramdisk, record in rem
++j;
@@ -405,14 +405,14 @@ static void cpio_backup(const char *orig, struct vector *v) {
rem->data = xrealloc(rem->data, rem->filesize + n->namesize);
memcpy(rem->data + rem->filesize, n->filename, n->namesize);
rem->filesize += n->namesize;
printf("Record new entry: [%s] -> [.backup/.rmlist]\n", n->filename);
fprintf(stderr, "Record new entry: [%s] -> [.backup/.rmlist]\n", n->filename);
}
if (doBak) {
m->namesize += 8;
m->filename = realloc(m->filename, m->namesize);
strcpy(buf, m->filename);
sprintf(m->filename, ".backup/%s", buf);
printf("[%s] -> [%s]\n", buf, m->filename);
fprintf(stderr, "[%s] -> [%s]\n", buf, m->filename);
vec_push_back(&bak, m);
// NULL the original entry, so it won't be freed
vec_entry(o)[i - 1] = NULL;
@@ -459,7 +459,7 @@ static int cpio_restore(struct vector *v) {
n->data = xmalloc(n->filesize);
memcpy(n->data, f->data, n->filesize);
n->remove = 0;
printf("Restoring [%s] -> [%s]\n", f->filename, n->filename);
fprintf(stderr, "Restoring [%s] -> [%s]\n", f->filename, n->filename);
cpio_vec_insert(v, n);
}
}

View File

@@ -20,7 +20,7 @@ void hexpatch(const char *image, const char *from, const char *to) {
hex2byte(to, patch);
for (size_t i = 0; i < filesize - patternsize; ++i) {
if (memcmp(file + i, pattern, patternsize) == 0) {
printf("Pattern %s found!\nPatching to %s\n", from, to);
fprintf(stderr, "Pattern %s found!\nPatching to %s\n", from, to);
memset(file + i, 0, patternsize);
memcpy(file + i, patch, patchsize);
i += patternsize - 1;

View File

@@ -58,7 +58,7 @@ static void usage(char *arg0) {
}
int main(int argc, char *argv[]) {
printf("MagiskBoot v" xstr(MAGISK_VERSION) "(" xstr(MAGISK_VER_CODE) ") (by topjohnwu) - Boot Image Modification Tool\n\n");
fprintf(stderr, "MagiskBoot v" xstr(MAGISK_VERSION) "(" xstr(MAGISK_VER_CODE) ") (by topjohnwu) - Boot Image Modification Tool\n\n");
if (argc > 1 && strcmp(argv[1], "--cleanup") == 0) {
cleanup();
@@ -68,8 +68,8 @@ int main(int argc, char *argv[]) {
mmap_ro(argv[2], (unsigned char **) &buf, &size);
SHA1(sha1, buf, size);
for (int i = 0; i < 20; ++i)
printf("%02x", sha1[i]);
printf("\n");
fprintf(stderr, "%02x", sha1[i]);
fprintf(stderr, "\n");
munmap(buf, size);
} else if (argc > 2 && strcmp(argv[1], "--unpack") == 0) {
unpack(argv[2]);

View File

@@ -58,6 +58,17 @@ void hide_sensitive_props() {
}
}
static void rm_magisk_prop(const char *name) {
if (strstr(name, "magisk")) {
deleteprop(name, 0);
}
}
void clean_magisk_props() {
LOGD("hide_utils: Cleaning magisk props\n");
getprop_all(rm_magisk_prop);
}
void relink_sbin() {
struct stat st;
if (stat("/sbin_orig", &st) == -1 && errno == ENOENT) {

View File

@@ -55,10 +55,7 @@ void launch_magiskhide(int client) {
hideEnabled = 1;
LOGI("* Starting MagiskHide\n");
if (client > 0) {
if (setprop(MAGISKHIDE_PROP, "1"))
goto error;
}
deleteprop(MAGISKHIDE_PROP, 1);
hide_sensitive_props();
@@ -104,6 +101,8 @@ void stop_magiskhide(int client) {
hideEnabled = 0;
setprop(MAGISKHIDE_PROP, "0");
// Remove without actually removing persist props
deleteprop(MAGISKHIDE_PROP, 0);
pthread_kill(proc_monitor_thread, SIGUSR1);
write_int(client, DAEMON_SUCCESS);

View File

@@ -13,6 +13,7 @@ void proc_monitor();
void manage_selinux();
void hide_sensitive_props();
void relink_sbin();
void clean_magisk_props();
// List managements
int add_list(char *proc);

View File

@@ -91,6 +91,7 @@ static void hide_daemon(int pid) {
manage_selinux();
relink_sbin();
clean_magisk_props();
if (switch_mnt_ns(pid))
return;
@@ -180,7 +181,10 @@ void proc_monitor() {
while (1) {
// Clear previous logcat buffer
system("logcat -b events -c");
char *const restart[] = { "logcat", "-b", "events", "-c", NULL };
log_pid = run_command(0, NULL, "/system/bin/logcat", restart);
if (log_pid > 0)
waitpid(log_pid, NULL, 0);
// Monitor am_proc_start
char *const command[] = { "logcat", "-b", "events", "-v", "raw", "-s", "am_proc_start", NULL };
@@ -269,6 +273,5 @@ void proc_monitor() {
kill(log_pid, SIGTERM);
waitpid(log_pid, NULL, 0);
close(log_fd);
log_pid = 0;
}
}

View File

@@ -66,23 +66,25 @@
#define PRINT_D(...) { LOGD(__VA_ARGS__); if (verbose) printf(__VA_ARGS__); }
#define PRINT_E(...) { LOGE(__VA_ARGS__); fprintf(stderr, __VA_ARGS__); }
#define PERSISTENT_PROPERTY_DIR "/data/property"
static int verbose = 0;
static bool is_legal_property_name(const char* name, size_t namelen) {
static bool is_legal_property_name(const char *name, size_t namelen) {
if (namelen < 1) return false;
if (name[0] == '.') return false;
if (name[namelen - 1] == '.') return false;
/* Only allow alphanumeric, plus '.', '-', or '_' */
/* Only allow alphanumeric, plus '.', '-', '@', ':', or '_' */
/* Don't allow ".." to appear in a property name */
for (size_t i = 0; i < namelen; i++) {
if (name[i] == '.') {
// i=0 is guaranteed to never have a dot. See above.
if (name[i - 1] == '.') return false;
if (name[i-1] == '.') return false;
continue;
}
if (name[i] == '_' || name[i] == '-') continue;
if (name[i] == '_' || name[i] == '-' || name[i] == '@' || name[i] == ':') continue;
if (name[i] >= 'a' && name[i] <= 'z') continue;
if (name[i] >= 'A' && name[i] <= 'Z') continue;
if (name[i] >= '0' && name[i] <= '9') continue;
@@ -103,6 +105,7 @@ static int usage(char* arg0) {
"Options:\n"
" -v verbose output\n"
" -n don't trigger events when changing props\n"
" if used with deleteprop determines whether remove persist prop file\n"
, arg0, arg0, arg0, arg0);
return 1;
}
@@ -138,6 +141,22 @@ char *getprop(const char *name) {
return strdup(value);
}
static void (*cb)(const char *);
static void run_actual_cb(void* cookie, const char *name, const char *value, uint32_t serial) {
cb(name);
}
static void prop_foreach_cb(const prop_info* pi, void* cookie) {
__system_property_read_callback2(pi, run_actual_cb, NULL);
}
void getprop_all(void (*cbk)(const char *name)) {
if (init_resetprop()) return;
cb = cbk;
__system_property_foreach2(prop_foreach_cb, NULL);
}
int setprop(const char *name, const char *value) {
return setprop2(name, value, 1);
}
@@ -149,7 +168,7 @@ int setprop2(const char *name, const char *value, const int trigger) {
prop_info *pi = (prop_info*) __system_property_find2(name);
if (pi != NULL) {
if (trigger) {
if (!strncmp(name, "ro.", 3)) deleteprop(name);
if (!strncmp(name, "ro.", 3)) deleteprop(name, trigger);
ret = __system_property_set2(name, value);
} else {
ret = __system_property_update2(pi, value, strlen(value));
@@ -172,13 +191,18 @@ int setprop2(const char *name, const char *value, const int trigger) {
return ret;
}
int deleteprop(const char *name) {
int deleteprop(const char *name, const int trigger) {
if (init_resetprop()) return -1;
PRINT_D("resetprop: deleteprop [%s]\n", name);
if (__system_property_del(name)) {
PRINT_E("resetprop: delete prop: [%s] error\n", name);
PRINT_D("resetprop: delete prop: [%s] error\n", name);
return -1;
}
if (trigger && strstr(name, "persist.")) {
char buffer[PATH_MAX];
snprintf(buffer, sizeof(buffer), "%s/%s", PERSISTENT_PROPERTY_DIR, name);
unlink(buffer);
}
return 0;
}
@@ -273,7 +297,7 @@ int resetprop_main(int argc, char *argv[]) {
if (file) {
return read_prop_file(filename, trigger);
} else if (del) {
return deleteprop(name);
return deleteprop(name, trigger);
} else {
return setprop2(name, value, trigger);
}

View File

@@ -12,8 +12,9 @@ int prop_exist(const char *name);
int setprop(const char *name, const char *value);
int setprop2(const char *name, const char *value, const int trigger);
char *getprop(const char *name);
int deleteprop(const char *name);
int deleteprop(const char *name, const int trigger);
int read_prop_file(const char* filename, const int trigger);
void getprop_all(void (*cbk)(const char *name));
#ifdef __cplusplus
}

2
jni/su

Submodule jni/su updated: e2821025ef...86a113a536

View File

@@ -232,8 +232,6 @@ int run_command(int err, int *fd, const char *path, char *const argv[]) {
if (xpipe2(pipefd, O_CLOEXEC) == -1)
return -1;
writeEnd = pipefd[1];
// Give the read end of the pipe
*fd = pipefd[0];
} else {
writeEnd = *fd;
}
@@ -241,7 +239,11 @@ int run_command(int err, int *fd, const char *path, char *const argv[]) {
int pid = fork();
if (pid != 0) {
close(writeEnd);
if (fd && *fd < 0) {
// Give the read end and close write end
*fd = pipefd[0];
close(pipefd[1]);
}
return pid;
}

View File

@@ -65,7 +65,22 @@ cd $MAGISKBIN
ui_print_wrap "- Unpacking boot image"
./magiskboot --unpack "$BOOTIMAGE"
[ $? -ne 0 ] && abort_wrap "! Unable to unpack boot image"
CHROMEOS=false
case $? in
1 )
abort_wrap "! Unable to unpack boot image"
;;
2 )
CHROMEOS=true
;;
3 )
ui_print_wrap "! Sony ELF32 format detected"
abort_wrap "! Please use BootBridge from @AdrianDC to flash Magisk"
;;
4 )
ui_print_wrap "! Sony ELF64 format detected"
abort_wrap "! Stock kernel cannot be patched, please use a custom kernel"
esac
# Update our previous backup to new format if exists
if [ -f /data/stock_boot.img ]; then
@@ -109,11 +124,11 @@ case $? in
esac
# Sign chromeos boot
if [ -f chromeos ]; then
if $CHROMEOS; then
echo > empty
LD_LIBRARY_PATH=$SYSTEMLIB $CHROMEDIR/futility vbutil_kernel --pack stock_boot.img.signed \
--keyblock $CHROMEDIR/kernel.keyblock --signprivate $CHROMEDIR/kernel_data_key.vbprivk \
./chromeos/futility vbutil_kernel --pack stock_boot.img.signed \
--keyblock ./chromeos/kernel.keyblock --signprivate ./chromeos/kernel_data_key.vbprivk \
--version 1 --vmlinuz stock_boot.img --config empty --arch arm --bootloader empty --flags 0x1
rm -f empty stock_boot.img
@@ -132,6 +147,7 @@ ui_print_wrap "- Removing Magisk files"
rm -rf /cache/magisk.log /cache/last_magisk.log /cache/magiskhide.log /cache/.disable_magisk \
/cache/magisk /cache/magisk_merge /cache/magisk_mount /cache/unblock /cache/magisk_uninstaller.sh \
/data/Magisk.apk /data/magisk.apk /data/magisk.img /data/magisk_merge.img /data/magisk_debug.log \
/data/busybox /data/magisk /data/custom_ramdisk_patch.sh 2>/dev/null
/data/busybox /data/magisk /data/custom_ramdisk_patch.sh /data/property/*magisk*
/data/app/com.topjohnwu.magisk* /data/user/*/com.topjohnwu.magisk 2>/dev/null
$BOOTMODE && reboot